有用的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
 
 

猜你喜欢

转载自www.cnblogs.com/ljyyjj/p/11611875.html