在基础的响应式数据和事件函数之后,我们再来说说 computed 计算属性 和 watch 监听吧。
前文:
(三)组件属性、计算属性与监听
1. 组件属性
通过数据和事件处理的几个例子,大家或许发现了 Vue3 的两个基本变化思路:
- 开发人员自己动手组装响应式数据;
- 事件处理对象方法降级为普通函数。
而这两者都避免了再将各种不同层级的属性、方法绑定到 $vm 上,从而避免了混乱的 this
指向问题。
以至于我们在 Vue3 的例子里基本没再用到过 this
。
对于父级组件传入的属性值,以前都是通过 this.<属性名>
访问的,在 Vue3 的 setup()
中怎么获取组件属性呢?
很简单,setup()
函数收到的第一个参数就是传入的属性值了:
1 2 3 4 5 6 7 8 9 10
| export default { props: { name: String, }, setup(props) { const { name } = props;
return { name }; }, };
|
不过由于传入的 props
是一个响应式数据,为了确保传入的非引用型数据发生变化时,页面内状态能动态更新,我们还得用 toRefs
从里面解构取值:
1 2 3 4 5 6 7 8 9 10 11 12
| import { toRefs } from 'vue';
export default { props: { name: String, }, setup(props) { const { name } = toRefs(props);
return { name }; }, };
|
2. 计算属性
对于间接通过其它数据再计算出来的计算属性,通过 Vue3 的组装 API 实现也很简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { ref, toRefs, computed } from 'vue';
export default { props: { totalCount: Number, sellCount: Number, }, setup(props) { const { totalCount = ref(0), sellCount = ref(0), } = toRefs(props); const remainCount = computed(() => totalCount.value - sellCount.value);
return { totalCount, sellCount, remainCount }; }, };
|
除了实际的业务逻辑之外,computed() 通常还可以用于多个 className 的计算合成,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| export default { props: { disabled: Boolean, }, setup(props) { const { disabled } = toRefs(props); const className = computed(() => [ 'sells-list', { 'is-disabled': disabled, }, ]); }, };
|
3. 监听
3.1 watch
当某个响应数据发生变化时,执行相关处理逻辑,我们就会用到 watch() 了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const { disabledIds } = toRefs(props); const selectedId = ref(null);
watch(selectedId, (val, oldVal) => { });
watch([selectedId, disabledIds], (val, oldVal) => { });
watch(() => selectedId === disabledIds, (val, oldVal) => { });
|
我们还可以使用 watch() 返回的停止器来结束监听:
1 2 3 4 5
| const selectedId = ref(null);
const stopWatch = watch(selectedId, (val) => { });
stopWatch();
|
3.2 watchEffect
与 watch 不同,watchEffect() 不需要指明监听目标,在它接收一个 effect 函数后,将会立刻执行并分析其中依赖的响应数据,在它们发生变化时再次执行这个 effect 函数。:
1 2 3 4 5 6
| const sellsCount = ref(0);
watchEffect(() => { console.log(`sellsCount: ${sellsCount.value}`); });
|
3.3 回收处理
如果需要在监听停止的同时,做一些额外的回收处理(比如解除 DOM 事件监听器、清理其它数据等),可以用到 onInvalidate 函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const sellsCount = ref(0);
watch(sellsCount, (val, oldVal, onInvalidate) => { console.log(`sellsCount: ${val}`); onInvalidate(() => { }); });
watchEffect((onInvalidate) => { console.log(`sellsCount: ${sellsCount.value}`); onInvalidate(() => { }); });
|
下一篇:《初探 Vue 3.0 的组装式 API(四)》