笔记,免得每次都去翻文档
vue3 的组合式 API(Composition API) 表示 vue 也开始 fp 了,好(鼓掌 👏)。
基础用法
写在setup 中:
const App = {
data() {
return {
message: "Hello!",
};
},
setup() {
//写入 setup
},
};
Vue.createApp(App).mount("#app");
setup里可以有变量和函数,但需要在外使用的都要靠return返回。- 创建
setup时组件实例还未创建,所以无法使用this。(这很 fp) - 但是可以访问:
props,attrs,slots,emit。
参数
setup接受两个参数:
props:组件的props。(响应式)context:组件的属性{attrs,slots,emit}。
app.component("MyMessage", {
props: {
msg: String,
},
setup(props) {
const msg = props.msg;
return { msg };
},
template: `<h1>{{msg}}</h1>`,
});
响应式变量
对于响应式变量(需要双向绑定的变量),使用ref函数包裹:
import { ref } from "vue"; //要单独导入!
//非模板下使用 Vue.ref
const message = ref("Hello");
ref针对的是一般变量,如果包裹对象使用reactive。
如果想在setup里对ref变量进行修改,则需要使用<变量>.value的形式访问值(在模板中/reactive中不需要)。
使用两种方式改变变量:
<div id="app">
<p>{{message}}</p>
<p>method: <input type="text" @input="onMethod" /></p>
<p>setup : <input type="text" @input="onSetup" /></p>
</div>
const App = {
setup() {
const message = Vue.ref("Hello!");
const group = Vue.reactive({ num: 0 });
function onSetup(event) {
message.value = event.target.value;
group.num++;
}
return { message, onSetup };
},
methods: {
onMethod: function (event) {
this.message = event.target.value;
this.group.num++;
},
},
};
Vue.createApp(App).mount("#app");
生命周期钩子
生命周期钩子也可以写在setup中,基本处理方法是在前面加上 on:
| 选项式 API | Hook inside setup |
|---|---|
| beforeCreate | Not needed* |
| created | Not needed* |
| beforeMount | onBeforeMount |
| mounted | onMounted |
| beforeUpdate | onBeforeUpdate |
| updated | onUpdated |
| beforeUnmount | onBeforeUnmount |
| unmounted | onUnmounted |
| errorCaptured | onErrorCaptured |
| renderTracked | onRenderTracked |
| renderTriggered | onRenderTriggered |
比如再修改一下上面的代码:
const App = {
setup() {
const message = Vue.ref("Hello!");
//模板中不需要 `Vue`
Vue.onMounted(() => {
message.value = "Mounted!";
});
return { message };
},
};
Vue.createApp(App).mount("#app");
Watch 和 Computed
Watch 和 Computed 也可以写在setup中。
const App = {
setup() {
const message = Vue.ref("Hello!");
const info = Vue.ref("");
const computed_message = Vue.computed(() => `🥳${message.value}🥳`);
Vue.watch(message, (newValue, oldValue) => {
info.value = "上次 Message 的值是:" + oldValue;
});
//中略
return { message, info, computed_message, onSetup };
},
};
Vue.createApp(App).mount("#app");
使用watch时发现要求第一个参数要是对象。如果想要监听 props 的话,则传入一个返回 prop 值的函数(()=>props.value)。
script setup
一个新的 SFC 下的语法糖。使用方法:
<script setup>
...
</script>
代码会在每次组件实例被创建的时候执行。
<script setup>中的顶层绑定(变量、函数等)和导入的 import 都会暴露给模板,不用写长长的 return 了。- 导入的组件也可以直接在模板中使用。
- 使用
defineProps和defineEmits声明props和emits。 - 使用
defineExpose明确暴露给外界(其它组件)的变量。 - 使用
useSlots和useAttrs辅助函数调用slots和attrs。 - 可以和普通的
<script>一起使用。
返回渲染函数
模板不要,完全 fp 化()
app.component("MyMessage2", {
props: {
msg: String,
},
setup(props) {
const msg = props.msg;
return () => Vue.h("h1", [msg]);
},
});
同理也能返回 jsx,但对于仅返回渲染用内容官方推荐使用render()函数返回。