Vue3的组合式API,简单来说,就是将原来的“方法”式API,变成了“函数”式API。
你只需要把原来的methods,直接塞到setup里面即可,是不是很简单?
但是要注意,组合式API跟传统的template-based API是有冲突的,所以Vue3默认情况下是禁止同时使用两种API的,如果你硬要同时使用,会抛出一个错误。
现在我们开始正式介绍Vue3的组合式API。
首先是setup函数,这个函数是整个组合式API的核心,所有的逻辑都应该在这个函数里面实现。
<template>
<div>
<p>{{ message }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { reactive, toRefs } from 'vue';
export default {
setup() {
const state = reactive({
count: 0,
message: 'Hello Vue3!',
});
const increment = () => {
state.count++;
};
const message = toRefs(state.message);
const count = toRefs(state.count);
return {
message, // 可以直接在模板中使用message变量
count, // 可以直接在模板中使用count变量
increment, // 可以直接在模板中使用increment函数
};
},
};
</script>
上面的代码中,我们使用了reactive函数来创建一个响应式对象,这个对象包含了count和message两个属性。然后我们通过toRefs函数将这两个属性转换成普通的变量,这样就可以在模板中直接使用了。最后,我们将这三个变量以及一个函数一起返回,这样就可以在模板中直接使用了。是不是很简单?
再来看看计算属性应该如何实现。在组合式API中,计算属性需要作为一个函数返回,而不是像template-based API那样直接在methods中定义。这个函数的返回值就是计算属性的值。
<template>
<div>
<p>{{ message }}</p>
<button @click="increment">Increment</button>
<p>{{ reversedMessage }}</p>
</div>
</template>
<script>
import { reactive, toRefs } from 'vue';
export default {
setup() {
const state = reactive({
count: 0,
message: 'Hello Vue3!',
});
const increment = () => {
state.count++;
};
const reversedMessage = () => {
return state.message.split('').reverse().join('');
};
const message = toRefs(state.message);
const count = toRefs(state.count);
const reversedMessageRefs = toRefs(reversedMessage()); // 注意这里需要使用toRefs将函数转换成普通变量才能使用!否则会报错!
return {
message, // 可以直接在模板中使用message变量
count, // 可以直接在模板中使用count变量
reversedMessageRefs,
increment,
};
},
};
</script>
上面的代码中,我们定义了一个reversedMessage
函数作为计算属性。这个函数会返回message
属性的反向字符串。注意到我们在使用toRefs
函数将reversedMessage
函数转换成普通变量的时候,需要传入函数的返回值,而不是函数本身。否则会报错。
接下来是watch监听器的实现。在组合式API中,我们需要使用watch
函数来监听某个属性的变化。当属性值发生变化时,watch
函数中定义的回调函数会被触发。
<template>
<div>
<p>{{ message }}</p>
<button @click="increment">Increment</button>
<p>{{ reversedMessage }}</p>
</div>
</template>
<script>
import { reactive, toRefs } from 'vue';
export default {
setup() {
const state = reactive({
count: 0,
message: 'Hello Vue3!',
});
const increment = () => {
state.count++;
};
const reversedMessage = () => {
return state.message.split('').reverse().join('');
};
const { message, count, reversedMessageRefs, increment } = watch(() => {
console.log('message changed!');
return { message, count };
}, newVal => {
console.log('message:', newVal.message);
console.log('count:', newVal.count);
});
return {
message, // 可以直接在模板中使用message变量
count, // 可以直接在模板中使用count变量
reversedMessageRefs, // 可以直接在模板中使用reversedMessage变量(注意这里需要使用reversedMessageRefs而不是reversedMessage)!注意这里需要使用toRefs将函数转换成普通变量才能使用!否则会报错!
increment, // 可以直接在模板中使用increment函数
};
},
};
</script>
上面的代码中,我们使用了watch函数来监听message属性的变化。当message属性发生变化时,回调函数会被触发。回调函数的第一个参数是一个函数,这个函数会返回我们需要监听的值。在这个例子中,我们返回了message属性。