笔记,免得每次都去翻文档
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()
函数返回。