0
点赞
收藏
分享

微信扫一扫

数据分析实战训练营8期-拉钩教育完整网盘

download:​​数据分析实战训练营8期-拉钩教育完整网盘​​

十分钟,让你学会Vue的这些巧妙冷技巧

前言

写了两年的​​Vue​​,期间学习到好几个提高开发效率和性能的技巧,现在把这些技巧用文章的形式总结下来。



1. 巧用​​$attrs​​和​​$listeners​​

​​$attrs​​用于记录从父组件传入子组件的所有不被​​props​​捕获以及不是​​class​​与​​style​​的参数,而​​$listeners​​用于记录从父组件传入的所有不含​​.native​​修饰器的事件。那下面的代码作例子:



Vue.component('child', {

  props: ['title'],

  template: '<h3>{{ title }}</h3>'

})



new Vue({

  data:{a:1,title:'title'},

  methods:{

    handleClick(){

      // ...

    },

    handleChange(){

      // ...

    }

  },

  template:'

    <child class="child-width" :a="a" b="1" :title="title" @click.native="handleClick" @change="handleChange">',



})

复制代码



则在​​<child/>​​在中



​​attrs​​的值为​​{a:1,b:"1"}​​

​​listeners​​的值为​​{change: handleChange}​​

通常我们可以用​​$attrs​​和​​$listeners​​作组件通信,在二次封装组件中使用时比较高效,如:



Vue.component("custom-dialog", {

  // 通过v-bind="$attrs"和v-on="$listeners"把父组件传入的参数和事件都注入到el-dialog实例上

  template: '<el-dialog v-bind="$attrs" v-on="$listeners"></el-dialog>',

});



new Vue({

  data: { visible: false },

  // 这样子就可以像在el-dialog一样用visible控制custom-dialog的显示和消失

  template: '<custom-dialog :visible.sync="visible">',

});

复制代码


再举个例子:



Vue.component("custom-select", {

  template: `<el-select v-bind="$attrs" v-on="$listeners">

    <el-option value="选项1" label="黄金糕"/>

    <el-option value="选项2" label="双皮奶"/>

  </el-select>`,

});



new Vue({

  data: { value: "" },

  // v-model在这里其实是v-bind:value和v-on:change的组合,

  // 在custom-select里,通过v-bind="$attrs" v-on="$listeners"的注入,

  // 把父组件上的value值双向绑定到custom-select组件里的el-select上,相当于<el-select v-model="value">

  // 与此同时,在custom-select注入的size变量也会通过v-bind="$attrs"注入到el-select上,从而控制el-select的大小

  template: '<custom-select v-model="value" size="small">',

});

复制代码


2. 巧用​​$props​​

​​$porps​​用于记录从父组件传入子组件的所有被​​props​​捕获以及不是​​class​​与​​style​​的参数。如



Vue.component('child', {

  props: ['title'],

  template: '<h3>{{ title }}</h3>'

})



new Vue({

  data:{a:1,title:'title'},

  methods:{

    handleClick(){

      // ...

    },

    handleChange(){

      // ...

    }

  },

  template:'

    <child class="child-width" :a="a" b="1" :title="title">',



})

复制代码


则在​​<child/>​​在中,​​$props​​的值为​​{title:'title'}​​。​​$props​​可以用于自组件和孙组件定义的​​props​​都相同的情况,如:



Vue.component('grand-child', {

  props: ['a','b'],

  template: '<h3>{{ a + b}}</h3>'

})



// child和grand-child都需要用到来自父组件的a与b的值时,

// 在child中可以通过v-bind="$props"迅速把a与b注入到grand-child里

Vue.component('child', {

  props: ['a','b'],

  template: `

  <div>

    {{a}}加{{b}}的和是:

    <grand-child v-bind="$props"/>

  </div>

  `

})



new Vue({

  template:'

    <child class="child-width" :a="1" :b="2">',

})

复制代码


3. 妙用函数式组件

函数式组件相比于一般的​​vue​​组件而言,最大的区别是非响应式的。它不会监听任何数据,也没有实例(因此没有状态,意味着不存在诸如​​created​​,​​mounted​​的生命周期)。好处是因只是函数,故渲染开销也低很多。



把开头的例子改成函数式组件,代码如下:



<script>

  export default {

    name: "anchor-header",

    functional: true, // 以functional:true声明该组件为函数式组件

    props: {

      level: Number,

      name: String,

      content: String,

    },

    // 对于函数式组件,render函数会额外传入一个context参数用来表示上下文,即替代this。函数式组件没有实例,故不存在this

    render: function (createElement, context) {

      const anchor = {

        props: {

          content: String,

          name: String,

        },

        template: '<a :id="name" :href="`#${name}`"> {{content}}</a>',

      };

      const anchorEl = createElement(anchor, {

        props: {

          content: context.props.content, //通过context.props调用props传入的变量

          name: context.props.name,

        },

      });

      const el = createElement(`h${context.props.level}`, [anchorEl]);

      return el;

    },

  };

</script>

复制代码



上面的​​search​​函数赋值为​​debounce​​返回的结果, 也就是具有防抖功能的请求函数。这种方式可以避免我们在组件里要自己写一遍防抖逻辑。



这里有个例子​ ​sandbox​​,大家可以点进去看看经过高阶函数处理的​​method​​与原始​​method​​的效果区别,如除此之外,​​method​​还可以定义为生成器,如果我们有个函数需要执行时很强调顺序,而且需要在​​data​​里定义变量来记录上一次的状态,则可以考虑用生成器。



例如有个很常见的场景:微信的视频通话在接通的时候会显示计时器来记录通话时间,这个通话时间需要每秒更新一次,即获取通话时间的函数需要每秒执行一次,如果写成普通函数则需要在​​data​​里存放记录时间的变量。但如果用生成器则能很巧妙地解决

举报

相关推荐

0 条评论