# Vue3.0 componsition Api
提示:
使用以下 api 需要导入 vue 模块进行结构 import { reactive, watchEffect, computed ,toRefs , ref, onBeforeMount, onMounted} from "vue";
setup =(将 2.x 版本中 beforeCreate 和 created)
# setup 执行方法
setup 是 vue3.x 中新的操作组件属性的方法,它是组件内部暴露出所有的属性和方法的统一 API。
// 执行时机
setup(props,content){
console.log('setup')
}
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
# 接收 props 数据 && 上下文对象 content
setup 函数的第二个形参是一个上下文对象,这个上下文对象中包含了一些有用的属性,这些属性在 vue 2.x 中需要通过 this 才能访问到,在 vue 3.x 中,它们的访问方式如下:
<script lang="ts">
// 父组件
<Child msg="app" />
import Child from "./components/HelloWorld.vue"; // 引入子组件的时候注意要加后缀
export default {
components: {
Child,
},
// 子组件
props: {
msg: String,
},
setup(props,content){
console.log(props);//接收父组件值
console.log(content); // 上下文对象
/*
attrs: Object
emit: ƒ ()
listeners: Object
parent: VueComponent
refs: Object
root: Vue
...
*/
console.log(this) // undefined
}
}
</script>
<template>
<div>
<h1>
{{ msg }}
</h1>
</div>
</template>
::: error
**注意:**在 setup() 函数中无法访问到 this
:::
# reactive
reactive 函数接收一个普通函数,返回一个响应式的数据对象。 reactive 函数等价于 vue 2.x 中的 Vue.observable() 函数,vue 3.x 中提供了 reactive() 函数,用来创建响应式的数据对象,基本代码示例如下:
setup(props,conetnt){
const data = reactive({
value:1
})
function add(){
data.value++
}
return {
data,
add
}
}
# ref
ref() 函数用来根据给定的值创建一个响应式的数据对象,ref() 函数调用的返回值是一个对象,这个对象上只包含一个 .value 属性:
setup(){
const xx =ref(初始值) 无初始值设置为null
如果传入的是对象,将调用reactive方法进行深层响应转换。
(1)调用
xx.value
(2)自动解套(即不需要xx.value获取值)
1、在setup的return{xx}中,在template中直接{{xx}}
2、在reactive定义的对象属性中
const x=ref(xx)
const xxx=reactive({x})
xxx.x调用
3、通过reactive对象调用属性赋值ref的形式,也会自动解套
const xx=reactive({x})
xx.x=ref(xxx)
xx.x直接调用
(3)获取dom的ref
当使用组合式 API 时,reactive refs 和 template refs 的概念已经是统一的
setup(){
let x=ref(null);
获取dom
x.value
return{
x
}
}
在template中
<标签 ref='x'></标签>
(4)使用模板语法遍历获取dom
template中:
<li v-for='(item,index) in 3' :key=index :ref="el=>{divs[index]=el}">
{{item}}
</li>
setup中:
const divs = ref([])
组件挂载后,即能通过divs.value获取遍历元素的所有dom
return{
divs
}
}
# 在 reactive 对象中访问 ref 创建的响应式数据
当把 ref() 创建出来的响应式数据对象,挂载到 reactive() 上时,会自动把响应式数据对象展开为原始的值,不需通过 .value 就可以直接被访问,例如:
setup() {
const refCount = ref(0)
const state = reactive({refCount})
console.log(state.refCount) // 输出 0
state.refCount++ // 此处不需要通过 .value 就能直接访问原始值
console.log(refCount) // 输出 1
return {
refCount
}
}
【注意:新的 ref 会覆盖旧的 ref,示例代码如下:】
setup() {
// 创建 ref 并挂载到 reactive 中
const c1 = ref(0);
const state = reactive({ c1 });
// 再次创建 ref,命名为 c2
const c2 = ref(9);
// 将 旧 ref c1 替换为 新 ref c2
state.c1 = c2;
state.c1++;
console.log(state.c1); // 输出 10
console.log(c2.value); // 输出 10
console.log(c1.value); // 输出 0
}
# computed 计算属性
# 只读的计算属性
import {ref,computed} from 'vue'
export default {
setup(){
let refdata = ref(0);
const comdata = computed(()=>refdata.value+2)
function refadd() {
refdata.value++;
}
function comadd() {
com.value++;
}
return {
refdata,
comdata,
refadd,
comadd
}
};
}
# 可读可写的计算属性
import {ref,computed} from 'vue'
export default {
setup(){
let refdata = ref(0);
const computedData = computed({
// 取值函数
get: () => refdata.value + 1,
// 赋值函数
set: () => {
refdata.value = refdata.value + 55;
},
});
function refadd() {
refdata.value++;
}
function comadd() {
com.value++;
}
return {
refdata,
comdata,
refadd,
comadd
}
};
}
const com = computed(() => data.count);
# toRefs
setup(){
const data = reactive({
count:1
})
return {
...toRefs(data) // 将响应式的对象变为普通对象 在家 ... 结构,在模板中就可以直接使用属性,不用data.count
}
}
# watchEffect
监听reactive函数中的count;
const com = computed(() => data.count);
watchEffect(() => {
这里可以拿到监听后的数据;
console.log(com.value);
});
# 生命周期
onMounted(() => {
console.log("挂载完成");
});
onBeforeMount(() => {
console.log("挂载前");
});
onBeforeUpdate(() => {
console.log("更新前");
});
onUpdated(() => {
console.log("更新完成");
});
onBeforeUnmount(() => {
console.log("销毁前");
});
onUnmounted(() => {
console.log("销毁完成");
});
onRenderTriggered(e => {
console.log();
debugger;
//检查哪个依赖导致组件重新呈现
});
# 响应式数据的判断
- isRef: 检查一个值是否为一个 ref 对象
- isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
- isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
- isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理
# isRef
isRef() 用来判断某个值是否为 ref() 创建出来的对象; 应用场景:当需要查看某个数据是否为 ref() 创建出来的值的时候,例如:
import { ref, isRef } from "vue";
export default {
setup() {
let emit = ref("123");
const unwrapped = isRef(foo) ? foo.value : foo;
console.log(unwrapped) // 如果不用三元运算符的话,返回值是boolean值
},
};
# isReactive
import { reactive, isReactive } from "vue";
export default {
setup() {
let data = reactive({
dome: "123",
});
const data2 = reactive("13");
const bool = isReactive(data);
const bool2 = isReactive(data2);
console.log(bool); // 返回 true
console.log(bool2); // 返回 false,
},
};
# 参考
微信公众号文章:vue3 的学习记录 (opens new window)