vue3.0新特性之重: vue-composition-api
1. 安装vue-cli npm i -g @vue/cli
2. 创建项目 vue create project
3. 在项目中安装并引入composition-api,体验vue3.0新特性
***npm install @vue/composition-api --save***
4. 使用:
import Vue from 'vue'
import VueCompositionApi from '@vue-composition-api'
***Vue.use(VueCompositionApi )***
6. 运行项目: cnpm run serve;
setup是组件提供的新属性, 为使用composition-api提供了统一的入口;
在beforeCreate 之后, created之前执行;
setup 参数释义:
props: 获得外界传入的props;
context: 上下文对象,包含了一些有用的属性, 这些属性在2.0中通过this访问到, 在vue3.0中通过context访问到,并且在setup()中无法访问到this:
import {setup , reactive } from '@vue/composition-api'
setup(props, ctx){
console.log(props) // 不定义就获取不到
ctx.attrs
ctx.slots
ctx.parent
ctx.root
ctx.emit
ctx.refs
},
props:{
name: String,
}
等价于2.0中的vue.observable()函数, 用来创建响应式的数据/集合, 通过…扩展运算符时无法改变数据, 需要用toRefs()转化为单个响应式数据。
{{count}}
setup(props, ctx){
const state = reactive({ count: 0 })
**return state; // 必须return**
},
用来创建响应式的单个数据,
let num = ref(0);
num.value++;
console.log(num.value) // 1
用来创建响应式的单个数据,
let num = ref(0);
console.log(isRef(num)) // true
将reactive创建出来的响应式对象, 转换为普通对象,转换后, 都是ref()类型的响应式数据。
在这里插入代码片
computed()用来创建计算属性, 返回值是一个ref实例;
let count = ref(1);
const plusOne = computed(()=>{return count.value+=1})
console.log(plusOne.value) //2
plusOne.value++ // err 只能读不能写
let count = ref(0);
const plusOne = computed({
get: () => { return count.value},
set: (val) => {return count.value = val}
})
plusOne.value = 9; // 改变plusOne的值触发set
return {
count,
plusOne
}
watch 在组件创建的时候会执行一次, 加入参数lazy可以控制在数据改变的时候再执行,组件首次创建时不执行;
// 基础用法
let val = ref(0)
watch(() => {console.log(val.value})
setTimeout(()=>{
val.value++
},2000)
// 监听reactive数据
let const RT = reactive({ count: 0 })
watch(()=>RT.count, (newValue,oldValue) => {
console.log(newValue,oldValue)
},{lazy: true})
setTimeout(()=>{
RT.count++
},2000)
// 监听ref数据
let const Rf = ref(0)
watch(()=>RF, (newValue,oldValue) => {
console.log(newValue,oldValue)
},{lazy: true})
setTimeout(()=>{
RF.value++
},2000)
// 监听多个数据源 第二个参数中使用解构赋值将name,age解构出来 -- reactive
let const RT = reactive({
name:'a',
age: 20
})
watch([() => RT.name, () => RT.age}], ([newNameValue,newAgeValue],[oldNameValue,oldAgeValue]) => {
console.log(newNameValue,newAgeValue)
console.log(oldNameValue,oldAgeValue)
},{lazy: true})
setTimeout(()=>{
RT.name = 'b',
RT.age = 26
},2000)
// 监听多个数据源 -- ref
let name = ref('zhang')
let age = ref(20)
watch([name, age], ([newName, newAge],[oldName,oldAge]) => {
console.log(newName,newAge)
console.log(oldName,oldAge)
},{lazy: true})
setTimeout(()=>{
name.value = 'b',
age.value = 26
},2000)
// 清除监视
// 在setup中创建的watch会在组件销毁的时候自动停止, 要想在组件未被销毁的时候让watch停止监视, 调用watch的返回值即可
let count= ref(0)
let stop= watch(count, (newCount,oldCount) => {
console.log(newCount,oldCount)
})
// 清除监视
stop();
// 清除watch中无效的异步任务 使用第三个函数onClean
// 场景: watch被stop 或 watch被重复使用
let keyWord = ref('');
let asyacValue = val => {
return setTimeout(()=>{
console.log(val)
},1000)
}
watch(keyWord,(newV, oldV, onClean) =>{
console.log(newV, oldV)
consr timer = asyacValue(newV)
onClean(()=>{
clearTimeout(timer)
})
})
beforeCreated -> setup
created -> setup
beforeMount -> OnBeforeMount()
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> OnUpdated
BeforeDestroy -> OnBeforeUnmount
destroy -> OnUnmount
provide和inject用于组件嵌套之间的数据传递, 在父组件中使用provide注入数据, 在子组件中使用inject接收父组件传递的数据
// 父组件
setup(){
// provide('要传递的数据名称','要传递的数据值')
provide('color','red')
let c = ref('red');
provide('color',c)
}
// 子组件
// 孙组件
<h2 :style="{color:col}"></h2>
setup(){
inject('要接收的数据名称')
let col = inject('color')
return {
col
}
}
<h3 ref="refD" >ref引用DOM</h3>
let refD = ref(null);
OnMounted(){
refD.value.style.color = 'red'
}
return {
refD
}
// 父组件通过ref获取子组件的值
// 父组件
<son ref="sonRef" />
setup(){
let sonRef = ref('null');
// 获取子组件的值
console.log(sonRef.value.str)
return {sonRef}
}
// 子组件
setup(){
let str = ref('abc')
return {
str
}
}