35

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

 3 years ago
source link: http://blog.krimeshu.com/2020/10/18/vue-3-composition-api-introduction-3/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

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

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

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

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

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

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

        return { name };
    },
};

2. 计算属性

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

// sells.js
import { ref, computed } from 'vue';

export default {
    props: {
        // 库存数量
        totalCount: Number,
        // 售出数量
        sellCount: Number,
    },
    setup(props) {
        const { 
            totalCount = ref(0), 
            sellCount = ref(0), 
        } = props;
        // 剩余数量
        const remainCount = computed(() => totalCount.value - sellCount.value);

        return { totalCount, sellCount, remainCount };
    },
};

除了实际的业务逻辑之外, computed() 通常还可以用于多个 className 的计算合成,比如:

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

3. 监听

3.1 watch

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

const { disabledIds } = props;
const selectedId = ref(null);

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

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

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

const selectedId = ref(null);

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

stopWatch();

3.2 watchEffect

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

const sellsCount = ref(0);

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

3.3 回收处理

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

const sellsCount = ref(0);

watch(sellsCount, (val, oldVal, onInvalidate) => {
    console.log(`sellsCount: ${val}`);
    onInvalidate(() => {
        // 回收处理
    });
});

watchEffect((onInvalidate) => {
    console.log(`sellsCount: ${sellsCount.value}`);
    onInvalidate(() => {
        // 回收处理
    });
});

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK