什么是mixins
在官方文档中
混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。
// 定义一个混入对象
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
选项合并
当组件和混入对象有相同的选项时,它们将会被混合;
如果混合的数据对象与组件数据冲突的时候,组件数据优先;
如果是钩子混合,混合的钩子优选;
什么是HOC
HOC 就是高阶组件(Higher-order component)
HOC经常出现于react,但是在vue中也可以被用到;但是vue中由于设计思想与react不同,所以使用mixins对于效率的提升大于使用hoc。
react中的hoc
先看一个react的demo
function WithConsole (WrappedComponent) {
return class extends React.Component {
componentDidMount () {
console.log('with console: componentDidMount')
}
render () {
return <WrappedComponent {...this.props}/>
}
}
}
在这个代码中WithConsole就是一个高阶组件;它的特点是什么呢:
1:高阶组件是一个function函数,可以看出它不会修改原来的组件,使用return去返回一个组件然后再渲染被包装的组件WrappedComponent。
2:高阶组件只接受数据props,不关心数据来源。等其他特点
vue中的hoc
先来看一个vue的基本组件
<template>
<div>
<span @click="handleClick">props: {{test}}</span>
</div>
</template>
<script>
export default {
name: 'BaseComponent',
props: {
test: Number
},
methods: {
handleClick () {
this.$emit('customize-click')
}
}
}
</script>
//使用组件
<base-component @customize-click="handleCustClick" :test="100" />
然后如果我们需要在这个组件挂载的时候都console一段话,可以使用mixins
export default consoleMixin {
mounted () {
console.log('I have already mounted')
}
}
然后混入其中
export default{
...
mixins: [consoleMixin]
...
}
如果使用高阶组件怎么完成同样的功能呢;在高阶组件中接受一个组件作为参数,返回一个新组件;在这里就要了解到什么是组件,在此之前要了解在vue中什么是组件,根据vue的源码,vue的组件在创建之后被引入的时候是一个JSON对象,但是当这个对象注册(components)之后,Vue会以该对象创建一个构造函数,在此之前import导入的时候,是一个对象 。 所以vue中高阶组件就是接受一个对象,返回成一个新的对象。
export default function WithConsole (WrappedComponent) {
return {
template: '<wrapped v-on="$listeners" v-bind="$attrs"/>',
components: {
wrapped: WrappedComponent
},
mounted () {
console.log('I have already mounted')
}
}
}
WithConsole就是一个高阶组件,接受WrappedComponent组件作为参数;返回一个新的组件;我们将WrappedComponent注册为wrapped组件,在template渲染。但是这个组件有很多的不完全功能,比如接受不到props和事件,无法插入slot,还需要再改进。太麻烦了,就不多写了,vue上使用hoc远没有mixins来的方便,这里只是了解下这个思想。
Vue和React
看起来vue里面高阶组件比较麻烦,这是由于两者的设计思想和目标不同,在react中写组件像写js函数,而vue更像先把函数封装之后,直接作用于html上面,这样有利也有弊,高度封装丢失了一定的灵活性,但是写起来更加轻松。