一些vue你不太知道的知识 | 8月更文挑战

531 阅读4分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

一、v-if和v-for哪个优先级更高?

<div v-for="item in dataList" v-if="isShow"></div>

可以自己写这样一段代码,然后进行断点调试,会走到源码中compiler/codegen/index.js这个文件,最后会发现:

v-for比v-if会更先执行,并且就算把v-if写在v-for之后都会先执行v-for,所以大家可以在外面套一层v-if就不会先执行v-for了,不然就会浪费很多性能。

二、vue的组件化理解

1、在源码中(src\core\global-api\assets.js),vue-loader会编译template为render函数,最终导出的依然是组件配置对象

2、组件是可以独立可复用的代码,可以提高开发效率

3、组件可以分类为:页面组件,通用组件,业务组件

4、vue的组件是基于配置的,平时写的组件就是组件配置而非组件,框架后续会生成构造函数,通过VueCompontent来实现

5、组件常用方法:props,自定义事件,插槽等

6、开发组件时要注意高内聚低耦合,并且遵循单向数据流的原则

三、为什么vue的组件模板只能有一个根元素

1、实例化vue时只能设置一个入口,如果设置多个vue就不知道哪个才是这个类

var vm = new Vuw({
    el: "#app"
});

2、单文件组件中template下的元素其实就是树状结构下的根数据,并且template具有隐藏性,并不展示在页面中;template也可以写在任何地方(head,body,script里都可以);template标签里任何HTML内容都是无效的必须使用innerHTML获取

3、vue源码中使用到的diff算法中要求只有一个根元素,在patch.js中patchVnode();

四、vue的性能优化方法

1、路由懒加载

const router = new VueRouter({ 
    routes: [          { path: '/index', component:() => import('./index.vue') }   
    ]
})

2、keep-alive缓存页面

<template> 
     <div id="app">           <keep-alive> <router-view/></keep-alive>      </div> </template>

3、v-show复用Dom

<template> 
     <div class="cell">           <div v-show="value" class="on"> 
               <showMore :n="999"/> 
          </div>           <section v-show="!value" class="off">                <showMore :n="999"/>           </section>       </div> </template>

循环内容较大的时候使用v-show比使用v-if更好

4、v-for中避免同时使用v-if

因为上面第一个问题中就提到了v-for比v-if更先执行,所以会消耗不必要的性能,如果下面dataList数据量是很大的json数组就会很耗费性能了

<template>
    <div v-if="dataList.length > 0" v-for="item in dataList">{{item}}</div>
    <div>暂无数据</div>
</template>
<script>
    export default {
        data() {
            return {
                dataList: [1,2,3,4,5,6,7,8]
            }
        }
    }
</script>

如果是多数据长列表展示,可以使用虚拟滚动,只渲染展示区域的少部分内容

<recycle-scroller class="items" :items="items" :item-size="50" > <template v-slot="{item}">
    <FetchItemView :item="item" @vote="voteItem(item)"/> 
</template> </recycle-scroller>//可以参考:vue-virtual-scroller和vue-virtual-scroller-list

5、事件销毁

created() {
     this.timer = setInterval(this.refresh, 2000)},beforeDestroy() { 
     clearInterval(this.timer) }

vue组件销毁时会自动解绑它的全部指令和事件监听器,但是仅限于当前组件的事件

6、图片懒加载

如果页面图片很多,需要对加载速度有要求,我们可以把需要展示的区域进行展示,不展示的区域先不做加载,等到滚动的时候再加载,类似于手机端的上滑分页加载的功能

<img v-lazy="../static/images/abc.png"/>
//可以参考vue-lazyload

五、vue组件之间的通信方式

例如图中:

A.vue-B.vue是父子组件,

B.vue和C.vue是兄弟组件,

A.vue和D.vue/E.vue是隔代关系,也是跨层组件

常用的通信方式有:

1、props 可以用于父子组件,向下传递给子组件

2、emit/emit/on事件总线,用来触发事件和监听事件,可以用于父子组件,兄弟组件,跨层组件

3、vuex所有页面都可以访问,因为vuex实现了单向数据流,全局使用states存放数据,只要数据修改必须通过Mutation提交修改信息,并且Mutation有订阅者模式可以给外部插件调用states数据的更新,根据state的变化渲染到视图中

4、parent/parent/children和ref,ref在Dom元素中使用指向dom元素,在组件中使用就会指向组件实例,主要用于访问父子组件

5、attrs/attrs/listeners常用于跨层组件通讯,attrs里存放的是父组件中绑定的非props属性,attrs里存放的是父组件中绑定的非props属性,listeners存放的是父组件中绑定的非原生事件

6、provide/inject是高阶插件/组件库提供的,可以使用在跨层组件,但是不是响应式的

7、event子组件通过events给父组件发送消息,向上传递给父组件

今天就写这么多,留点明天写,不然每天想内容好累,日更真不容易,每天好忙还要坚持写,加油,感觉掘金给的动力!