重新阅读 vue 文档收获

最近有空,心血来潮想着再去把 vue 文档给读一遍,记一下收获

 

1、避免 v-if 和 v-for 用在一起

链接

这里的问题以前完全没有注意过,导致经常写 iview 出现这一类的代码

<Select>
  <Option v-for="(item, index) in menuList" v-if="item.isUsed" :key="index">{{item.name}}<Option>
</Select>

原因:

   v-for 的优先级 比 v-if 要高,导致 渲染的时候,先执行了 v-for ,后执行了 v-if ,这是一个完全没有必要的 开销

以上还有一个问题:  

:key="index"

key 属性实际上是用来 diff 的时候,看能不能复用 节点的。

在diff 的时候,他会先查看 key 属性有没有一样的,一样的就拿过来复用,减少开销。

所以尽量使用类似于 id 之类独一无二,又不像index 这一类毫无意义的 key

======

2020.04.09 补充

深入了解了 vue diff 之后(勉强算深入了解吧) 发现 类似于 这种重复性很高的模块上的时候,类似于 上文的 Option,尤其是 分页的表单之类的

key 直接使用 index 说不定渲染速度会 更快一点

 

2、slot-scope 和 #default="{}"

相信不少同学对这个是比较陌生的,也有同学是比较了解的,

但是在iview 开发文档中,Table 中 提供了这个属性,相当好用,不需要再 render 了 iview 更新日志

所以我特地关注了一下这个, 具名插槽         slot-scope

文档给出的demo:
<Table :data="tableDate" :columns="columnContract" >
          <template slot-scope="{ row }" slot="contractNo">
            <MyToolTip :words="row.contractNo" :maxLength="20"></MyToolTip>
          </template>
</Table>

vue 淘汰了上面的使用方法,: 新版用法
<Table :data="tableDate" :columns="columnContract">
            <!-- 这里 使用了结构 -->
          <template #contractNo="{ row }"> 
            <MyToolTip :words="row.contractNo" :maxLength="20"></MyToolTip>
          </template>
</Table>


slot-scope="{ row }" slot="contractNo" 
完全可以使用  
#contractNo="{ row }" 
来代替

#表示  v-slot:     后面的 contractNo 就是 slot name,注意 ,如果是default的话,一定要写 #default=""

3、监听生命周期

所以说,人丑多读书(*/ω\*),我看了这个之后,发现自己以前写的代码都是辣鸡

场景:有一个页面,进入之后就设计了一个定时器,每5秒 去请求一次数据,在离开的时候,需要clear 这个定时器

beforeDestroy () {
  clearInterval(this.time);
},

看起来完全没问题,但是   程序化的事件侦听器

  • 它需要在这个组件实例中保存这个 picker,如果可以的话最好只有生命周期钩子可以访问到它。这并不算严重的问题,但是它可以被视为杂物。
  • 我们的建立代码独立于我们的清理代码,这使得我们比较难于程序化地清理我们建立的所有东西。

所以可以有更好的

mounted: function () {
  在mounted 创建 定时器
  var time = new setInterval(fn, 5000)

  监听 beforeDestory 事件,然后清除定时器
  this.$once('hook:beforeDestroy', function () {
    clearInterval(time)
  })
}

至于为什么监听的是 'hook:beforeDestroy'  ,这个 hook: 又是哪里来的,我看了一下 vue  的源码

function callHook (vm, hook) {
             // #7573 disable dep collection when invoking lifecycle hooks
             pushTarget();
             var handlers = vm.$options[hook];
             var info = hook + " hook";
             if (handlers) {
               for (var i = 0, j = handlers.length; i < j; i++) {
                 invokeWithErrorHandling(handlers[i], vm, null, vm, info);
               }
             }
             if (vm._hasHookEvent) {
               vm.$emit('hook:' + hook);
             }
             popTarget();
           }

vue 中, 直接    vm.$emit('hook:' + hook);

 

4、事件修饰符 .passive

事件修饰符

说实话,看到这个我是有点不知所措地,可能以前完全没有注意到,我竟然不知道这个属性是什么意思,

查了之后,发现是 addEventListener 的 第三个参数对象中的一个 具体的可以对应的 文档

举个栗子,你在移动端使用原生的滚动的时候,如果addEventListener 监听了实际上刚刚开始 是有200ms 的停顿的,

因为他不知道你是否会 preventDefault(),所以会先执行你addEventListener,然后再原生的滚动,即使你放进去的代码是自定义的空函数 ,依旧会有这样的一个延迟

而这个属性就是为了告诉浏览器,我没有执行preventDefault(),你放心地先滚起来把

注意,passive 和 preventDefault() 放一起会无视 preventDefault() 并向你扔一个错误

5、动态+异步 组件

这个其实没什么好像,就是单纯的记一下 链接

<component :is="currentComponent" ></component>
import LoadingComponent from "./components/LoadingComponent.vue";
import ErrorComponent from "./components/ErrorComponent.vue";
------
components: {
	'componentA': () => ({
		component: import('./components/componentA.vue'),
		// 异步组件加载时使用的组件
		loading: LoadingComponent,
		// 加载失败时使用的组件
		error: ErrorComponent,
		// 展示加载时组件的延时时间。默认值是 200 (毫秒)
		delay: 200,
		// 如果提供了超时时间且组件加载也超时了,
		// 则使用加载失败时使用的组件。默认值是:`Infinity`
		timeout: 3000
	}),
	'componentB': () => ({
		component: import('./components/componentB.vue'),
		// 异步组件加载时使用的组件
		loading: LoadingComponent,
		// 加载失败时使用的组件
		error: ErrorComponent,
		// 展示加载时组件的延时时间。默认值是 200 (毫秒)
		delay: 200,
	})
},
computed: {
	currentComponent: function () {
		return 'component' + this.AB;
	} 
},

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值