介绍vue3中的compositionApi

compositionApi

setup

setup 是Vue3.x新增的一个选项, 他是组件内使用 Composition API的入口。

setup执行时机,在beforeCreate之前执行

setup(props,context) 参数

props: 组件传入的属性

context:{attrs,slot,emit}

//注意:setup中接受的props是响应式的, 当传入新的props 时,会及时被更新。由于是响应式的, 所以不可以使用ES6解构,解构会消除它的响应式。

//错误代码示范:段代码会让props不再支持响应式
export default defineComponent ({
    setup(props, context) {
        const { name } = props //错误用法
        console.log(name)
    },
})

可以使用toRefs进行转变,变成普通ref对象
什么是原始对象:
let obj={
	name:'zhang',
	age:'12'
} //这种就是原始对象
注意:定义的原始对象是没有响应式的

readonly(将响应式对象转为原始对象)

let obj=reactive({
	name:'zhang',
	age:'12'
}) //当前为响应式对象

obj=readonly(obj); //将响应式数据转为普通原始对象

reactive(只能用于代理对象)

reactive函数可以代理一个对象, 但是不能代理基本类型,例如字符串、数字、boolean等

返回对象的响应式副本,返回的 proxy 是等于原始对象的。建议只使用响应式 proxy,避免依赖原始对象。

reactive 将解包所有深层的 refs,同时维持 ref 的响应性。

import { reactive, ref } from 'vue'

const count = ref(1)
const obj = reactive({ count })

// ref 会被解包
//解包相当于是将.value赋值给了obj.count
console.log(obj.count === count.value) // true


count.value++  // 它会更新 `obj.count`
console.log(count.value) // 2
console.log(obj.count) // 2

// 它也会更新 `count` ref
obj.count++
console.log(obj.count) // 3
console.log(count.value) // 3

ref

接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。

const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

//如果将对象分配为 ref 值,则它将被 reactive 函数处理为深层的响应式对象。

toRef

可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。

const state = reactive({
  foo: 1,
  bar: 2
})

const fooRef = toRef(state, 'foo')

fooRef.value++
console.log(state.foo) // 2

state.foo++
console.log(fooRef.value) // 3

toRefs

将响应式对象转换为ref普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref

const state = reactive({
  foo: 1,
  bar: 2
})

const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:

{
  foo: Ref<number>,
  bar: Ref<number>
}
*/

// ref 和原始 property 已经“链接”起来了
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3


//当从组合式函数返回响应式对象时,toRefs 非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行解构/展开:


或者

const state=reactive({
            num1:0,
            num2:0,
            result:0
        });
const  showstate=toRefs(state)
let {num1,num2,result}=showstate

这里的展开不会丢失响应性

在setup中使用方法

<button @click="setTitle">执行方法改变父组件的title</button>

import {ref} from "vue"
export default {
    name:"App",
    setup(){
        let title =ref("app组件中的标题")let setTitle=()=>{
            title.value="哈哈哈"
        }
        return{
            title
        }
    }
}
函数编程写法
{{num1}} {{num2}}

import {reactive,toRefs} from "vue"
export default{
    name:"页面名",
    props:{
        msg:String
    }
	setup(){
        const  {num1,num2}=stateData()
        return{
            num1,
            num2,
            add
        }
  }
  
  function stateData(){
  	const state=reactive({
            num1:0,
            num2:0,
            result:0
        });
        function add(){
            state.result=state.num1+state.num2;
        }
        return toRefs(state)
      //这里的toRefs相当于可以将state的值进行展开解构出来
  	}
}

computed

import {reactive ,computed} from "vue"
export default{
    name:"页面名",
    props:{
        msg:String
    }
	setup(){
        const state=reactive({
            num1:0,
            num2:0,
            result:computed(()=>parseInt(state.num1)+parseInt(state.num2))
        });
        //或者这么写
    	const full=computed(()=>{
           return  parseInt(state.num1)+parseInt(state.num2)
        })
        return{
            state,
        }
  }
}
//parseInt:将字符串转为数字

watch

watch(source, callback, [options])

参数说明:

  • source:可以支持string,Object,Function,Array; 用于指定要侦听的响应式变量
  • callback: 执行的回调函数
  • options:支持deep、immediate 和 flush 选项。
//侦听reactive定义的数据

import { defineComponent, ref, reactive, toRefs, watch } from "vue";
export default defineComponent({
  setup() {
    const state = reactive({ nickname: "xiaofan", age: 20 });
 
    setTimeout(() =>{
        state.age++
    },1000)
 
    // 修改age值时会触发 watch的回调
     watch(
       state,  
      (curAge, preAge) => {
        console.log("新值:", curAge, "老值:", preAge);
      }
    );
    //如果需要监听reactive里面的值需要这样写
    watch(
      () => state.age,  
      (curAge, preAge) => {
        console.log("新值:", curAge, "老值:", preAge);
      }
    );
 
    return {
        ...toRefs(state)
    }
  },

//侦听ref定义的数据

const year = ref(0)
setTimeout(() =>{
    year.value ++ 
},1000)
 
watch(year, (newVal, oldVal) =>{
    console.log("新值:", newVal, "老值:", oldVal);
})
侦听多个ref定义的数据
watch([() => state.age, year], ([curAge, newYear], [preAge, oldYear]) => {
    console.log("新值:", curAge, "老值:", preAge);
    console.log("新值:", newYear, "老值:", oldYear);
})

注意如果要监听复杂数据对象要在后面加deep:true

const state = reactive({
    room: {
    id: 100,
    attrs: {
        size: "140平方米",
        type:"三室两厅"
    },
    },
});
watch(() => state.room, (newType, oldType) => {
    console.log("新值:", newType, "老值:", oldType);
}), {deep:true})

wacthEffect

无论你的值是否改变,都会先执行一次

import {reactive,toRefs,watchEffect}
export default{
    setup(){
        let data=reactive({
            num:1
        })
        watchEffect(()=>{
            console.log("data.num",data.num) //当前监听的值为data.num
        })
        setInterval(()=>{
            data.num
        },1000)
        return{
            ...toRefs(data)
        }
    }
}

vue3生命周期函数

image-20211221091024261

注意:vue3的生命周期函数要写在setup中
import { defineComponent, onBeforeMount, onMounted, onBeforeUpdate,onUpdated, onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered
} from "vue";
 
export default defineComponent({
  // beforeCreate和created是vue2的
  beforeCreate() {
    console.log("------beforeCreate-----");
  },
  created() {
    console.log("------created-----");
  },
  setup() {
    console.log("------setup-----");
 
    // vue3.x生命周期写在setup中
    onBeforeMount(() => {
      console.log("------onBeforeMount-----");
    });
    onMounted(() => {
      console.log("------onMounted-----");
    });
    // 调试哪些数据发生了变化
    onRenderTriggered((event) =>{
        console.log("------onRenderTriggered-----",event);
    })
  },
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值