前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初探 Vue 3.0 的组装式 API(三)

初探 Vue 3.0 的组装式 API(三)

作者头像
贤羽
发布2022-06-09 15:02:15
2090
发布2022-06-09 15:02:15
举报
文章被收录于专栏:贤羽的前端小栈

在基础的响应式数据和事件函数之后,我们再来说说 computed 计算属性 和 watch 监听吧。

初探 Vue 3.0 的组装式 API(一)

初探 Vue 3.0 的组装式 API(二)

(三)组件属性、计算属性与监听

1. 组件属性

通过数据和事件处理的几个例子,大家或许发现了 Vue3 的两个基本变化思路:

  • 开发人员自己动手组装响应式数据;
  • 事件处理对象方法降级为普通函数。

而这两者都避免了再将各种不同层级的属性、方法绑定到 $vm 上,从而避免了混乱的 this 指向问题。

以至于我们在 Vue3 的例子里基本没再用到过 this

对于父级组件传入的属性值,以前都是通过 this.<属性名> 访问的,在 Vue3 的 setup() 中怎么获取组件属性呢?

很简单,setup() 函数收到的第一个参数就是传入的属性值了:

代码语言:javascript
复制
export default {
    props: {
        name: String,
    },
    setup(props) {
        const { name } = props;

        return { name };
    },
};

不过由于传入的 props 是一个响应式数据,为了确保传入的非引用型数据发生变化时,页面内状态能动态更新,我们还得用 toRefs 从里面解构取值:

代码语言:javascript
复制
import { toRefs } from 'vue';

export default {
    props: {
        name: String,
    },
    setup(props) {
        const { name } = toRefs(props);

        return { name };
    },
};

2. 计算属性

对于间接通过其它数据再计算出来的计算属性,通过 Vue3 的组装 API 实现也很简单:

代码语言:javascript
复制
// sells.js
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 的计算合成,比如:

代码语言:javascript
复制
export default {
    props: {
        // 是否禁用状态
        disabled: Boolean,
    },
    setup(props) {
        const { disabled } = toRefs(props);
        const className = computed(() => [
            'sells-list', 
            {
                'is-disabled': disabled,
            },
        ]);
    },
};

3. 监听

3.1 watch

当某个响应数据发生变化时,执行相关处理逻辑,我们就会用到 watch() 了:

代码语言:javascript
复制
const { disabledIds } = toRefs(props);
const selectedId = ref(null);

// 监听某个数据
watch(selectedId, (val, oldVal) => { 
    // do something
 });
// 监听多个数据
watch([selectedId, disabledIds], (val, oldVal) => {
    // 此时传入的 val 和 oldVal 将会是多个数据的数组
 });

// 监听某个复合条件的结果
watch(() => selectedId === disabledIds, (val, oldVal) => {
    // 当其中相关值发生改变,但结果不变时,这里不会被触发
});

我们还可以使用 watch() 返回的停止器来结束监听:

代码语言:javascript
复制
const selectedId = ref(null);

const stopWatch = watch(selectedId, (val) => { });

stopWatch();

3.2 watchEffect

watch 不同,watchEffect() 不需要指明监听目标,在它接收一个 effect 函数后,将会立刻执行并分析其中依赖的响应数据,在它们发生变化时再次执行这个 effect 函数。:

代码语言:javascript
复制
const sellsCount = ref(0);

watchEffect(() => {
    console.log(`sellsCount: ${sellsCount.value}`);
}); 
// 将会立刻看到输出日志,之后数据变化时再次打印日志

3.3 回收处理

如果需要在监听停止的同时,做一些额外的回收处理(比如解除 DOM 事件监听器、清理其它数据等),可以用到 onInvalidate 函数:

代码语言:javascript
复制
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(四)》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-11-032,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • (三)组件属性、计算属性与监听
    • 1. 组件属性
      • 2. 计算属性
        • 3. 监听
          • 3.1 watch
          • 3.2 watchEffect
          • 3.3 回收处理
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档