Componsition API的出现个人理解是替换之前的Mixin,以实现代码复用。
1. 一个组件中声明一个变量,之前是在data里面,现在可以写在setup里面
export default {
name: "Composition",
setup() {
// 每一个模块的数据可以写在一块,但是数据多的话看setup可能不清爽,可以把每一个模块的数据抽离成一个函数返回data
// counter相关
const data = reactive({
counter: 1,
doubleCounter: computed(() => data.counter * 2),
});
let timer;
onMounted(() => {
timer = setInterval(() => {
data.counter++;
}, 1000);
});
onUnmounted(() => {
clearInterval(timer);
});
const data = userCounter(); // 这样的话可以统一建立一个js文件用的时候直接引入进去,setup也看着比较简洁,一目了然,代码也能很好的得到复用。
// 在模板中使用data数据的话必须带上data.counter, data.doubleCounter,那这个时候就可以使用toRefs,已实现对对象的解构,这样上下文中就可以直接用counter,doubleCounter。
const { counter, doubleCounter } = userCounter();
// 其他数据,单值响应式
const msg = ref("some message");
// 使用元素的引用
const desc = ref(null);
// 侦听器
watch(counter, (val, oldVal) => {
const p = desc.value;
p.textContent = `counter change form ${oldVal} to ${val}`;
});
return {
counter,
doubleCounter,
msg,
desc,
};
},
beforeCreate() {
console.log("beforeCreate");
},
created() {
console.log("created");
},
};
function userCounter() {
const data = reactive({
counter: 1,
doubleCounter: computed(() => data.counter * 2),
});
let timer;
onMounted(() => {
timer = setInterval(() => {
data.counter++;
}, 1000);
});
onUnmounted(() => {
clearInterval(timer);
});
return toRefs(data);
}
2. 渲染函数api的修改
以前使用渲染函数,它的特性和属性是分开的,包括事件/原生事件也是分开的,在写的时候可能会写错地方
vue3的修改对于渲染函数来说变得更加简单好用了,修改主要有以下几点:
- 不再传入h函数,需要我们手动导入;import {h} from 'vue'; 之前的是在render函数中作为参数返回 render(h) {}
- 拍平的props结构,不嵌套,所有的事件以on为前缀,只要加上on就表示是个事件,vue底层会做处理。
render() {
const emit = this.$emit;
const onClick = this.onClick;
return h('div', [
h('div', {
onClick() {
emit('update:modelValue', 'new Value')
}},
`i am comp, ${this.modelValue}`
),
h('button', {
onClick() {
onClick();
}},
`click it !!!`
),
])
}
- scopedSlots删掉了,统一到slots
3. 函数式组件:vue3中的函数式组件只能用简单函数方式创建,functional选项废弃
在vue3中函数式组件变化较大,有以下几点:
- 性能提升可忽略不计,所以在vue3中推荐使用状态组件;
- 函数式组件仅能通过纯函数形式声明,接收props和context两个参数;
- SFC中<templete>不能添加functional特性声明函数式组件;
- {functional: true} 组件选项移除;
// 声明一个函数式组件,Functional.vue
import {h} from 'vue';
const Heading = (props, context) {
return h(`h${props.level}`, context.attrs, context.slots);
}
Heading.props = ['level']
export default Heading;
// 组件使用:
<functional level="3">这是一个h3标签内容</functional>
// 渲染结果:
<h3>这是一个h3标签内容</h3>
4. 自定义指令:vue3中自定义指令API和组件保持一致:
bind ——> beforeMount
inserted ——> mounted
beforeUpdate ——> New! 元素自身更新前调用,和组件生命周期很像
update ——> removed!被移除,使用updated代替
componentUpdated ——> updated
beforeUnmount ——> New!元素将要移除时使用
unbind ——> unmounted
以上纯属个人理解,有问题欢迎指导~~