本文最后更新于 249 天前,如有失效请评论区留言。
Mixins
这是一个简单的Mixins的例子,看起来没什么问题,但是当数组里的mixins多了后,每个命名都不同,这是你就不知道那个属性、方法是那个Mixins注入的,导致命名空间的冲突
高阶组件
react采用了高阶组件(HOC)来解决这个问题,定义一个withMouse,返回一个组件
但是,仍然还是有命名空间冲突的问题,比如多个HOC组件嵌套,这种情况仍然无法马上清晰的知道那个值是那个组件
const App = withFoo(withAnother(withMouse({
props: ['x', 'y', "foo", "bar"],
template: `{{x}} {{y}}`,
})))
作用域插槽
所以vue采用了作用域插槽来解决
当有多个的时候,也能很清晰的显示区别,当遇到命名重复也可以更改
const App = {
components: { Mouse },
template: `
<Mouse v-slot="{ x,y }">
<Foo v-slot="{ foo }">
<Cut v-slot="{ x: z }">
{{x}} {{y}} {{ foo }} {{ z }}
</Cut>
</Foo>
</Mouse>
`,
}
这种方法的唯一缺点是为了逻辑提取和重用,创建了多个组件实例
Composition API
使用Composition就完美解决了上面的问题
并且vue作者不推荐下面这种写法的原因也能理解了,就是怕命名空间冲突无法第一时间及时了解问题
完整源代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app"></div>
<script>
const { createApp, h, ref, onMounted, onUnmounted } = Vue
function useMouse () {
const x = ref(0)
const y = ref(0)
const update = e => {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
windows.removeEventListener('mousemove', update)
})
return { x, y }
}
const App = {
setup () {
const { x, y } = useMouse()
const foo = ref('foo')
return {
x,
y,
foo,
}
},
template: `{{x}} {{y}} {{foo}}`,
}
createApp(App).mount('#app')
</script>
</body>
</html>