有用的Vue开发技巧
Posted ljyyjj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有用的Vue开发技巧相关的知识,希望对你有一定的参考价值。
原文链接:https://juejin.im/post/5d861aabe51d4557ca7fde06
1.状态共享
随着组件的细化,就会遇到多组件状态共享的情况,Vuex当然可以解决这类问题,不过就像Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是vue.js 2.6新增加的Observable API ,通过使用这个api我们可以应对一些简单的跨组件数据状态共享的情况。
如下这个例子,我们将在组件外创建一个store,然后在App.vue组件里面使用store.js提供的store和mutation方法,同理其它组件也可以这样使用,从而实现多个组件共享数据状态。
首先创建一个store.js,包含一个store和一个mutations,分别用来指向数据和处理方法。
1 import Vue from"vue"; 2 3 export const store = Vue.observable({ count: 0 }); 4 5 export const mutations = { 6 setCount(count) { 7 store.count = count; 8 } 9 };
然后在App.vue里面引入这个store.js,在组件里面使用引入的数据和方法
2.长列表性能优化
我们应该都知道vue会通过object.defineProperty对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要vue来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止vue劫持我们的数据呢?可以通过object.freeze方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了
1 export default { 2 data: () => ({ 3 users: {} 4 }), 5 async created() { 6 const users = await axios.get("/api/users"); 7 this.users = Object.freeze(users); 8 } 9 };
另外需要说明的是,这里只是冻结了users的值,引用不会被冻结,当我们需要reactive数据的时候,我们可以重新给users赋值。
1 export default { 2 data: () => ({ 3 users: {} 4 }), 5 async created() { 6 const users = await axios.get("/api/users"); 7 this.users = Object.freeze(users); 8 }, 9 methods:{ 10 // 改变值不会触发视图响应this.data.users[0] = newValue 11 // 改变引用依然会触发视图响应this.data.users = newArray 12 } 13 };
3.去除多余的样式
随着项目越来越大,书写的不注意,不自然的就会产生一些多余的css,小项目还好,一旦项目大了以后,多余的css会越来越多,导致包越来越大,从而影响项目运行性能,所以有必要在正式环境去除掉这些多余的css,这里推荐一个库purgecss,支持CLI、javascriptApi、Webpack等多种方式使用,通过这个库,我们可以很容易的去除掉多余的css。
1 <h1>Hello Vanilla!</h1><div> 2 We use Parcel to bundle this sandbox, you can find more info about Parcel 3 <ahref="https://parceljs.org"target="_blank"rel="noopener noreferrer">here</a>. 4 </div> 5 6 body { 7 font-family: sans-serif; 8 } 9 a { 10 color: red; 11 } 12 ul { 13 li { 14 list-style: none; 15 } 16 } 17 18 19 import Purgecss from"purgecss"; 20 const purgecss = new Purgecss({ 21 content: ["**/*.html"], 22 css: ["**/*.css"] 23 }); 24 const purgecssResult = purgecss.purge();
最终产生的purgecssResult结果如下,就可以看到多余的a和ul标签的样式都没了
4.函数式组件
函数式组件,即无状态,无法实例化,内部没有任何生命周期处理方法,非常轻量,因而渲染性能高,特别适合用来只依赖外部数据传递而变化的组件。
写法如下:
在template标签里面标明functional 只接受props值 不需要script标签
1 <!-- App.vue --> 2 <template> 3 <div id="app"> 4 <List:items="[‘Wonderwoman‘, ‘Ironman‘]" :item-click="item => (clicked = item)" 5 /> 6 <p>Clicked hero: {{ clicked }}</p> 7 </div> 8 </template> 9 <script> 10 import List from"./List"; 11 12 exportdefault { 13 name: "App", 14 data: () => ({ clicked: "" }), 15 components: { List } 16 }; 17 </script> 18 19 <!-- List.vue 函数式组件 --> 20 <template functional> 21 <div> 22 <p v-for="item in props.items" @click="props.itemClick(item);"> 23 {{ item }} 24 </p></div> 25 </template>
5.监听组件的生命周期
比如有父组件Parent和子组件Child,如果父组件监听到子组件挂载mounted就做一些逻辑处理,常规的写法可能如下:
1 // Parent.vue 2 <Child @mounted="doSomething"/> 3 4 // Child.vue 5 mounted() { 6 this.$emit("mounted"); 7 }
这里提供一种特别简单的方式,子组件不需要任何处理,只需要在父组件引用的时候通过@hook来监听即可,代码重写如下:
1 <Child @hook:mounted="doSomething"/> 2 <Child @hook:updated="doSomething"/>
当然这里不仅仅是可以监听mounted,其它的生命周期事件,例如:created,updated等都可以,是不是特别方便~
再比如平时的绑定卸载事件:
1 window.addEventListener(‘resize‘,this.handleResize) 2 this.$on(‘hook:destroyed‘,() => { 3 window.removeventListener(‘resize‘,this.handleResize) 4 })
更多有关hooks用法(useMounted,useComputed)可查看vue-hook源码
6.Watch的初始立即执行
当 watch 一个变量的时候,初始化时并不会执行,如下面的例子,你需要在created的时候手动调用一次。
1 created() { 2 this.fetchUserList(); 3 }, 4 watch: { 5 searchText: ‘fetchUserList‘, 6 }
上面这样的做法可以使用,但很麻烦,我们可以添加immediate属性,这样初始化的时候就会自动触发(不用再写created去调用了),然后上面的代码就能简化为:
1 watch: { 2 searchText: { 3 handler: ‘fetchUserList‘, 4 immediate: true 5 } 6 }
7.Watch的深度监听
1 data () { 2 return { 3 searchText: { 4 date: ‘123‘ 5 } 6 } 7 } 8 watch: { 9 searchText: { 10 handler: ‘fetchUserList‘, 11 deep: true 12 } 13 }, 14 methods: { 15 fetchUserList () {} 16 }
这样deep 可以监听到searchText.date的变化
8.~~位运算 快速转化为数字
1 let a = ‘12136546‘; 2 let b = 0; 3 4 b = ~~a; 5 console.log(b) //12136546 6 a = ‘asdsad‘ 7 b = ~~a; 8 console.log(b) //0
以上是关于有用的Vue开发技巧的主要内容,如果未能解决你的问题,请参考以下文章