vue如何让第三方包兼容IE

我们在使用vue的过程中会发现安装了第三方包,却无法在IE浏览器下正常运行的情况,这是因为vue-cli为了打包速度,默认情况下是不会使用babel-loader去处理node_modules下的第三方包的,这里有三种解决方案:

1. 将第三方包移出node_modules文件夹

将包从node_modules中拷贝出来,放入components文件夹下,再将import包的路径改为components下的路径,这样就可以在自己的项目中使用babel-loader去编译第三方的包了,但是这样做很不优雅。

2. 在vue.config.js中配置webpack使babel-loader去编译node_modules中的包

module.exports = {
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /\/node_modules\/tree-table-vue\//,
          use: {
            loader: "babel-loader"
          }
        }
      ]
    }
  }
};

这里有个疑问一直没搞明白,exclude 是排除的意思,webpack官方文档也是这样解释的,但是这个文件默认就是排除掉的,按照官方文档,应该使用include包含这个路径,但是使用include却无效,而使用exclude是有效的。

3. 终级解决方案,vue-cli的配置项transpileDependencies

module.exports = {
  transpileDependencies: ["tree-table-vue"]
};

css单行文字分散对齐

在页面中,我们有时候为了显示上的美观,会做文字的分散对齐,如何用css实现单行文字分散对齐呢?

/* webkit内核浏览器 */
.test {
  text-align-last: justify;
}
/* IE浏览器兼容方案 */
.test {
  text-align: justify;
  text-justify: distribute;
}

iview 模态框设置 loading 后表单验证失败无法清除 loading 状态

在使用 iview 模态框过程中我们使用确定按钮异步提交信息,提交成功后才关闭模态框,但我们发现若无法通过表单验证,禁止提交时,确定按钮的 loading 状态无法清除,无法修改表单后再次提交信息。官方文档中也没有关于这一点的说明,查阅官方 issue 后发现了解决方案。即先将loading状态设置为false,再使用this.$nextTick在下次将loading状态设置为true。

<template>
  <Modal :loading="modalLoading" @on-ok="submitForm">
    <form ref="form"></form>
  </Modal>
</template>
<script>
  export default {
    name: "test",
    data() {
      return {
        modalLoading: true
      };
    },
    methods: {
      // 改变loading状态函数
      changeLoading() {
        // 将loading状态设置为关闭
        this.modalLoading = false;
        // 下次模态框加载时重置loading状态为true
        this.$nextTick(() => {
          this.modalLoading = true;
        });
      },
      // 点击确定执行的函数
      submitForm() {
        // iview表单验证
        this.$refs.form.validate(valid => {
          if (valid) {
            console.log("表单验证成功,异步执行确定请求");
          } else {
            // 表单验证失败时重置loading状态
            this.changeLoading();
          }
        });
      }
    }
  };
</script>

css列表渲染使用flex布局固定每行布局数量

在实际应用中,我们常常会使用for循环渲染输出html内容块,然后使用flex布局及flex布局中的flex-wrap属性来使循环渲染的内容块自动换行。这样做的弊端是当浏览器的宽度改变时每行的内容块数量也会改变,无法获得统一的视觉体验。如何使浏览器宽度改变时flex布局每行布局数量不变呢?

这里有一个小技巧,即对html内容块使用百分比宽度布局。

仅使用百分比宽度布局则会发现无法给内容块之间设置间距,每个内容块都是紧密相连的。大家可能会想到使用justify-content属性与align-items属性来增加间距,justify-content中的space-around、space-evenly等属性值可以使内容块水平分散对齐,但是最后一行如果未填满,也会被居中,视觉体验并不好。那么如何解决间距问题呢?

这里我们把刚刚的内容块作为一个容器,给内容块设置一个padding值。这样就有了间距。真正的内容放置在内容块内层的div中即可。

<div class="container">
    <div class="block">
        <div class="content"></div>
    </div>
    <div class="block">
        <div class="content"></div>
    </div>
    <div class="block">
        <div class="content"></div>
    </div>
    <div class="block">
        <div class="content"></div>
    </div>
    <div class="block">
        <div class="content"></div>
    </div>
</div>
.container {
    display: flex;
    flex-wrap: wrap;
    background: red;
    width: 100%;
    height: 100%;
}
.block {
    width: 25%; /* 每行4个 */
    width: 20%; /* 每行5个 */
    background: green;
    padding: 5px;
}
.content {
    width: 100%;
    height: 100%;
    background: blue;
}

监听对象内的属性

通过vue的官方文档我们知道watch函数可以监听data中的各种变量,但若要监听的变量是一个对象中的某个属性,就很难做到了。

data() {
    return {
        normalVar: 0,
        myObject: {
            myKey: myValue
        }
    }
},
watch() {
    // 这是对普通对象的监听,要监听myObject中的myKey就无法直接用watch做到了
    normalVar() {
        console.log('normalVar changed');
    }
}

那么我们如何监听到myObject中的myKey变化呢?这里就要用到computed属性做为中间层了,通过computed做为中间层就可以完美监听到myObject中myKey的变化了。

data() {
    return {
        myObject: {
            myKey: myValue
        }
    }
},
computed() {
    computeMyKey() {
        return this.myObject.myKey
    }
},
watch() {
    computeMyKey() {
        console.log('myKey changed');
    }
}

+ newDate() 是什么意思?

我们都知道 javascript 是一种弱类型的语言,类型是可以被转换的。在实际应用中我们常常会看到这样一种获取毫秒数的方法:+ new Date()。这是什么原理呢?

为什么+ new Date() = new Date().getTime()。原理是 js 类型转换,+ new Date()相当于对new Date()进行类型转换,将 Date 类型转换为 Number 类型,若转换失败会得到 NaN。+ new Date()调用了 Date.prototype 上的 valueOf 方法,该方法等同于 Date.prototype.getTime()。

iview未显示在视图中的表单不进行验证

在使用表单的过程中,我们经常会碰到后面的表单内容依据前面表单项的选择不同而发生变化的情况,这种时候我们需要表单验证工具根据条件不再对未渲染的表单项进行验证。

要实现未显示在视图中的表单不被验证,应注意表单的条件渲染不能使用vue的v-show,而应该使用v-if,因为v-show只是切换display属性不再显示表单,但是表单还是被渲染并存在于DOM树中的,这时表单验证工具还是会生效的,而使用v-if,表单项在为false的条件下,不会被渲染,表单验证也就不会生效了。

iview 手风琴树算法

设置外部变量 lastNode 保存上次节点(若 lastNode 为 null 则什么都不做)以判断父子关系

依据父子关系:

若点击自身或子树,不操作。
若点击父树,则折叠所有子树。
若点击父树的兄弟树,则折叠与兄弟树同级的所有其他父树

如果 lastNode 和 currentNode 在同一树分支中,父树的 nodeKey 一定比子树小,遍历 nodeKey 小的树,来确定 lastNode 和 currentNode 是父子树关系,还是兄弟树关系

若确定 currentNode 是 lastNode 的兄弟树。则查找 currentNode 与 lastNode 的公共父树。(由于 accordion 模式,若是兄弟树关系则 currentNode 一定是 lastNode 父树的兄弟树,因此 currentNode 的父树也是 lastNode 的父树,是双方的公共父树)

用到的函数:查找兄弟树父树、折叠除当前节点外,当前节点父树下所有的结点、判断树关系、递归查找是否为子节点

Read more »

javascript的事件回调参数

const ele = document.getElementById("id");
function haha(abc) {
    console.log(abc);
    console.log(event);
}

// 声明一个参数,则该参数为事件,同时也可以使用默认事件变量event
ele.addEventListener("click", e => {
    console.log(e); // event
    console.log(event) // event
}, true);

// 不声明参数,则默认传入event
ele.addEventListener("click", () => {
    console.log(event); // event
}, true);

// 声明一个命名函数,也是同样道理
ele.addEventListener("click", function haha() {
    console.log(event); // event
}, true);


ele.addEventListener("click", function haha(abc) {
    console.log(abc); // event
    console.log(event); // event
}, true);

ele.addEventListener("click", haha); // event event

// 相当于页面加载时直接执行haha函数,并不是在点击时调用,此时event一定为undefined,参数abc根据是否传入而定,若不传则为undefined,否则为传入的值本身。
ele.addEventListener("click", haha()); // undefined undefined

通过上面的代码我们可以看出,在javascript中使用addEventLister监听事件,并不能给回调函数携带参数,只能自定义event的变量名,或者使用默认的event变量。默认的event变量是自动传入回调函数的。

function haha(abc) {
    console.log(abc);
    console.log(event);
}
<!-- 不传参数时可以取到默认的event, -->
<div onclick="haha()"></div>
<!-- undefined event -->

<!-- 传了参数可以取到参数与默认的event -->
<div onclick="haha('haha')"></div>
<!-- haha event -->

在html中监听事件,可以传递参数,event依然默认传入函数中,若声明函数参数时,声明了和event同名的参数,则要将实参event传入函数,否则打印event报undefined。

// 声明形参event
function haha(abc, event) {
    console.log(abc);
    console.log(event);
}
<!-- 不传参数时无法取到默认的event, -->
<div onclick="haha()"></div>
<!-- undefined undefined -->

<!-- 传了参数可以取到参数与event -->
<div onclick="haha('haha', event)"></div>
<!-- haha event -->

vue中的事件与使用html属性监听事件相同,若声明了event形参,则应该传入$event实参,否则报undefined。

0%