组件,是封装和复用性的体现。封装,将尽量少的细节暴露给外界;复用,在保证整体功能的情况下通过一些方式提供灵活性、可变性。这些设计指导原则可以让我们在程序开发的过程中,写出组织良好,可维护性比较高的代码。
组件的属性就是这样一种方式,可以让组件和外部(其他组件)之间进行有限的沟通,同时也让组件拥有了可配置性。使用过Vue2.x的朋友一定对组件的属性非常熟悉,其实Vue3.0的属性用法和Vue2.x的差不多。
仍以之前的计数器例子为基础,为它添加一些属性相关的功能:我们希望在创建计数器的时候,可以设置它初始计数值,然后后续的点击计数基于这个初始值进行累加,而不是从0开始累加。
来看下我的代码是怎么做的,是不是和你猜想中的差不多:
第一步:我们首先是为 Counter 组件使用如下代码定义了一个名为 initCount 的属性,类型为数字,默认值为 0:
props: {
initCount: {
type: Number,
default: 0
}
}
第二部:我们改造了一下 useCount 函数,让它接收一个初始值参数来初始化响应式数据 count,而不是直接用 0:
function useCount(initCount) {
const count = ref(initCount)
//...
}
第三部:通过 setup 方法的第一个参数,我们可以获取到传入组件的属性值,并调用改造过的 useCount 函数:
setup(props) {
const { count, increase, reset } = useCount(props.initCount)
// ...
}
第四部:经过上面的改造,Counter组件改造完成。最后就是在使用这个组件的时候传入我们想要的初始值:
// 使用render函数渲染
h(Counter, { initCount: 99 })
<!-- 使用模板渲染 -->
<Counter initCount="99" />
改造完成,运行程序后,我们看到的界面数字就是这个设定的初始值啦!
希望通过以上这个简单的例子,大家初步掌握了属性的基本用法。下面是完整的代码,供大家参考:
const { createApp, ref, h } = Vue
// 计数器组件
const Counter = {
// 属性定义
props: {
initCount: {
type: Number,
default: 0
}
},
// setup的第一个参数为传入的属性值
setup(props) {
const { count, increase, reset } = useCount(props.initCount)
return () => [
h('div', { class: 'counter-display' }, [
h('span', { class: 'counter-label' }, '恭喜你,你已经写了'),
h('span', { class: 'counter-text' }, count.value),
h('span', { class: 'counter-label' }, '斤代码!'),
]),
h('div', { class: 'counter-btns' }, [
h('button', { class: 'btn', onClick: increase }, '写一斤'),
h('button', { class: 'btn', onClick: reset }, '删库啦'),
])
]
}
}
// 使用初始计数值
function useCount(initCount) {
const count = ref(initCount)
const increase = () => { count.value++ }
const reset = () => { count.value = 0 }
return { count, increase, reset }
}
// 根组件
const App = {
render() {
return h('div', { class: 'container' }, [
h('h3', '计数器示例'),
h(Counter, { initCount: 99 }) // 传入初始值 99
])
}
}
// 启动
const container = document.querySelector('#app')
const app = createApp()
app.mount(App, container)