Vue学习(九)——混入

前言

混入(mixin)的使用非常简单,其实我原本打算直接写插件(plugin)的,但考虑到插件的使用范围也包括混入和自定义指令,还是先讲讲这两个的基本概念。

混入在我看来,就是给组件加上一些通用的属性和方法。比如说我们项目有很多个页面是要展示分页列表的,那页面组件都会包含当前页、每页记录、总记录数、总页数这些属性、还有页面增删查改操作的函数等等,其中有很多是完全一样,或者具备一定可复用性的。如果每个页面都搞这么一大坨,不单写起来繁琐,看起来也很乱。要是碰上不同的人开发,变量名定义还不一样,可读性可维护性就很差。所以我们想要有个东西能把这些共同的部分提取出来,这里面就要用到混入的概念。项目中如何使用大家可以参考一些开源的后台管理系统,比如jeecg的前端就用了混入。

使用混入

先利用vue-cli建一个项目test_mixin。不懂建的参考我第一篇vue文章《Vue学习(一)——组件基础》

基本使用

现在我们假设我们项目的每个组件created方法都调用console.log('create'),并且每个组件都有一个hello方法,另外还有两个属性current、pageSize。

创建目录src/mixin,并在该目录下新建文件mixinHello.js:

export const mixinHello = {
  data(){
    return{
      current: 1,
      pageSize: 10
    }
  },
  created: function () {
    console.log('create')
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
      console.log('current:' + this.current)
      console.log('pageSize:' + this.pageSize)
    }
  }
}

代码很简单,就是像我们这节开始说的那样,定义好current、pageSize属性,created方法、hello方法。接着我们在src/components目录下创建一个自定义按钮组件myBtn,并把混入加到其中:

<template>
  <div>
    <button @click="hello">测试混入</button>
  </div>
</template>

<script>
import {mixinHello} from '@/mixin/mixinHello.js'

export default {
  mixins: [mixinHello]
}
</script>

然后我们修改App.vue,引入muBtn

<template>
  <div>
    <my-btn></my-btn>
  </div>
</template>

<script>
import myBtn from '@/components/myBtn'

export default {
  name: 'App',
  components: {
    myBtn
  },
}
</script>

执行run server,访问localhost:8080,如图:

 我们点F12打开开发者工具,刷新页面,可以看到打印出create,证明调用了mixinHello的created方法:

扫描二维码关注公众号,回复: 15944495 查看本文章

然后点击按钮,打印出hello方法执行的内容。

当然如果这些方法和属性仅仅用在一个组件上,显然是没必要使用混入。混入的意义在于复用,如果很多组件都需要用到这些方法和属性,使用混入就恰到好处了。

选项合并

混入在复用时可以节省很多功夫,但是有衍生出另一个问题,如果我们在组件里面定义了名称相同的方法或者属性,执行的时候会用哪个?我们在src/components目录下创建零一个自定义按钮组件myBtnMerge.vue

<template>
  <div>
    <button style="margin: 10px" @click="hello">测试混入合并</button>
  </div>
</template>

<script>
import {mixinHello} from '@/mixin/mixinHello.js'

export default {
  mixins: [mixinHello],
  data(){
    return{
      current: 2,
      pageSize: 30
    }
  },
  created: function () {
    console.log('create merge')
  },
  methods: {
    hello: function () {
      console.log('hello merge!')
      console.log('current:' + this.current)
      console.log('pageSize:' + this.pageSize)
    }
  }
}
</script>

修改App.vue,注释掉myBtn,加上myBtnMerge

<template>
  <div>
    <!-- <my-btn></my-btn> -->
    <my-btn-merge></my-btn-merge>
  </div>
</template>

<script>
// import myBtn from '@/components/myBtn'
import myBtnMerge from '@/components/myBtnMerge'

export default {
  name: 'App',
  components: {
    // myBtn,
    myBtnMerge
  },
}
</script>

运行项目后,刷新网页,然后点击按钮,看到F12的输出:

这里我们有三个结论:

1、对于钩子函数,比如created、mounted、destroyed一类,组件自定义的方法和混入的方法同名时,会合并,并且混入的方法先于组件自定义的调用。

2、对于组件自定义的数据对象,和混入对象合并后,如果存在冲突的属性,则以组件自定义的优先。

3、对于methods、components 和 directives这一类,组件自定义的与混入的内部键值存在冲突时,以组件自定义的优先。

看起来这个有点像面向对象的继承。钩子函数像构造函数。其他则类似成员属性和成员方法。

如果不想使用默认的合并策略,混入还可以自定义合并的策略。具体实现读者可以自行搜索“optionMergeStrategies”这个关键词。

小结

混入的使用在我看来有点像面向对象里面的继承。好处是相同的属性和方法没必要重复写很多遍。尤其是做项目时,每个分页都要写一堆方法非常繁琐。当然对于钩子函数还是要谨慎使用混入,因为即使组件自定义了钩子函数,也不会覆盖混入的钩子函数。

猜你喜欢

转载自blog.csdn.net/sadoshi/article/details/127863415