传统的vue2.0的mixin存在一下缺点:
- 属性名重复冲突,这使得mixin中的数据将会被替换掉,有时会造成无法预料的问题
- 可重用性有限,无法向mixins传入任何参数来改变逻辑,降低了在抽象逻辑方面的灵活性
- 数据来源无法确定,mixins中的数据没有显式的列出来,导致代码中很多数据或方法无法确定其来源,甚至有时会造成代码误删
在vue3.0中我们使用自定义hooks来解决这些问题
传统mixins展示:
export default {
data () {
return {
msg: 1
}
},
mounted () {
this.testFn()
},
methods: {
testFn () {
console.log('testFn')
}
}
}
使用mixins:
<template>
<div>{{ aa }}</div>
</template>
<script>
import myMixins from './myMixins'
export default{
mixins: [myMixins],
mounted () {
console.log('index mounted')
}
}
</script>
我们使用自定义hooks的方式:
import { ref, onMounted } from 'vue'
export default function () {
const aa = ref(1)
function testFn () {
console.log('testFn')
}
onMounted(() => {
testFn()
})
return {
aa
}
}
<template>
<div>{{ aa }}</div>
</template>
<script lang="ts">
import { defineComponent, onMounted } from 'vue'
import myHooks from './myHooks'
export default defineComponent({
setup () {
const { aa, testFn } = myHooks()
onMounted(() => {
testFn('index mounted')
})
return {
aa,
testFn
}
}
})
</script>
可以看到我使用自定义hooks的方式引入的数据和方法都能直接看到来源,且方法可以传入参数
为什么导出的是一个function而不是对象?
- 因为导出为对象的话就意味着在import导入时就执行了封装的逻辑,而我们封装的逻辑是用composition api包装了的的特殊代码,这些代码只能在setup里才能正常使用,所以需要导出一个函数,这样就可以在组件setup里调用该函数来指定执行时机。
- 导出为function还有一个用途是方便传参,这样可以在不同的组件引用时做一些差异化逻辑处理。