相信很多写vue组件的人都会遇到这样的情况,有两个组件,功能很相似,但又有个体差异化的实现,这时候我们就来到“岔路口”了,我是应该把它拆分成两个不同的组件呢?还是搞成一个组件,然后通过props传值来创造差异性从而进行内在的区分呢?
其实这两种方法就实现功能来说,都是可行的,但往vue特性的理解上来看,两种解决方案都不够完美和高级:第一种,如果拆分成两个组件,你就不得不冒着功能变动而要在两个文件中更新代码的风险,这与 《 The Pragmatic Programmer 》书中的DRY原则相违背,是不优雅的;第二种,太多的props传值会让你的代码变得混乱不堪,增加后续的维护成本,即便是你本人一直在维护的情况下。
so,vue里面的mixin的优越性就在这里要体现出来了!简单来说,mixin特性类似于Object.assign() 方法的效果,就是数据合并,但mixin是为vue而生的,所以mixin在vue中使用就显得功能更强大。总结了mixin中的两个特性:
1.如果mixin和自己的组件中都有mounted方法,则mounted方法会执行两次,而且mixin中的会先执行,案例如下:(mixin可以当做一个组件,也有Vue组件生命周期的所有方法)
//mixin
const hi = {
mounted() {
console.log('hello mixin!')
}
}
//vue component
new Vue({
el: '#app',
mixins: [hi],
mounted() {
console.log('hello Vue !')
}
});
//Output in console
> hello mixin!
> hello Vue !
2.mixin中的属性和方法会与组件的进行合并,同名方法时,组件中的方法会覆盖mixin中的方法,案例如下:
//mixin
const hi = {
methods: {
sayHello: function() {
console.log('hello from mixin!')
}
},
mounted() {
this.sayHello()
}
}
//vue component
new Vue({
el: '#app',
mixins: [hi],
methods: {
sayHello: function() {
console.log('hello from Vue instance!')
}
},
mounted() {
this.sayHello()
}
})
// Output in console
> hello from Vue instance!
> hello from Vue instance!
实际使用的时候,我们会给mixin建一个单独的文件夹,里面放要用到的mixin文件,然后在需要用到的组件里面引入对应的mixin文件就ok了,如下:
baseMixin.js代码如下:
import { parseDate} from '@/utils/index'
export const baseMixin = {
data() {
return {
listQuery:{
dateRange:[],
page: 1,
limit: 10
}
}
},
methods: {
weekDate() {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
this.listQuery.dateRange = [parseDate(start, 'yyyy-MM-dd'), parseDate(end, 'yyyy-MM-dd')]
},
handleFilter() {
this.listQuery.page = 1
this.getList()
}
}
}
组件代码使用如下:
import { baseMixin } from '@/mixins/baseMixin'
export default {
mixins:[baseMixin],
mounted() {
//可以直接只用mixin中的方法或者data属性
this.weekDate()
this.listQuery.page = 2
},
}
但是有一点要强调的,也是官方文档一再强调的,尽量别使用全局的mixin组件,因为会在所有的vue组件中生效,谨慎!不然自己挖坑把自己埋了都不知道。
就这些吧!