Vue3 Composition API(案例)

前言:如果你是从vue2转到vue3的一份子,那么你重点学一下核心内容Composition API 。vue3的更新使代码写起来更加清晰,而且更接近于原生开发,对TS支持友好,现在我们来学习一下API。

如果你也想学一下TS那么请看这里 带你学习语法Typescript

setup api

setup(props,context){
  // 不可以通过this获取所以要通过参数获取
  console.log(props.message)
  console.log(context.attrs.id + ' ' + context.attrs.class)
  console.log(context.emit)
  console.log(context.slots)

返回值return{ }可以代替 data(){}可以在模板中直接引用

setup()函数里可以写函数 可以代替methon{} 写方法

reactive

// 响应式方法一

// const state = reactive({
//   title: 'hello kun',
//   content: 100
// })

ref

// 响应式方法二 挂载后可以直接在template中引用,不需要.value,vue自动解包为你省了一步
// 但是下面方法里依然还是要.value的
//template中浅层的解包,如果嵌套了不能解包。但是reactive中嵌套可以解包,但是我们不建议这么做
const title = ref('hello kun')
const content = ref(100)

readonly

一个proxy的set方法被劫持,可以传用但是不能修改,返回只读的代理

1,普通对象

无法响应式,比如我们可以传入到子组件,子组件无法修改但是无法做到响应式

2,传入reactive对象

子组件不能改,但是是响应式的,可以在这里改state1 或者ref的state3
const state1 = reactive({
  name:'kun',
  height:1.88
})
const state2 = readonly(state1)

3, 传入ref对象

const state3 = ref("why")
const state4 = readonly(state3)

了解:reactive判断的api

isproxy

检查对象是否是由 reactive 或 readonly创建的 proxy

isReactive

检查对象是否是由 reactive创建的响应式代理:

如果该代理是 readonly 建的,但包裹了由 reactive 创建的另一个代理,它也会返回 true;

isReadonly

检查对象是否是由 readonly 创建的只读代理。

toRaw

返回 reactive 或 readonly 代理的原始对象(建议保留对原始对象的持久引用。请谨慎使用)。

shallowReactive

创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (深层还是原生对象)。

shallowReadonly

创建一个 proxy,使其自身的 property 为只读,但不执行嵌套对象的深度只读转换(深层还是可读、可写的)。

torefs

对reactive返回的对象进行解构获取的值,那么无论是修改结构后的变量,还是修改reactive返回的state对象,数据都不是响应式的,

vue提供了各函数torefs,可以将reactive返回的对象中的属性都转成ref

 const state = reactive({
      name:'zlk',
      age:18
    })
    let {name,age} = toRefs(state);
    const btnclick = () => {
      // state.name = 'kun'
      name.value = 'kun'
    }

state.name和name.value建立链接,任何一个修改都会变化

toref

如果我们只希望转换一个属性为ref,而不是整个reactive对象,可以使用toref方法

const state = reactive({
  name:'zlk',
  age:18
})
const name = toRef(state,'name')
const {age} = state;

const btnclick = () => {
  // state.name = 'kun'
  name.value = 'kun'
}

ref其他api

const info = shallowRef({name:'kun'})

const btnclick = () => {
  info.value.name = 'feiji'
  triggerRef(info)
}

shallowRef浅层ref,未响应式

triggerRef手动触发后,响应式了

customRef

<template>
<div>
  <input v-model="message">
  <h3>{{message}}</h3>
</div>
</template>


const message = ref('hello');
return{
  message
}

这是普通双向绑定,

我们来自定义一个ref,做防抖

import {customRef} from "vue";

export function useref(value,delay = 1000){
    let timer;
    return customRef((track, trigger) => {
        return{
            get(){
                track(); // 收集依赖
                return value 
            },
            set(newvalue){
                clearTimeout(timer)  // 防抖
                timer = setTimeout(() => {
                    value = newvalue  //赋值
                    trigger(); //更新模板依赖
                },delay)
            }
        }
    })
}

computed

方式一:接收一个getter函数,并为 getter 函数返回的值,返回一个不变的 ref 对象

setup(){
  let first = ref("kun");
  let last = ref("ba");
  let haha = 'nihao'
  const fullName = computed(() => {
    return first.value + ' ' + last.value
  })
  return{
    first,
    last,
    fullName,
    haha
  }
}

方式二:接收一个具有 get 和 set 的对象,返回一个可变的**(可读写)ref 对象**;

setup(){
  let first = ref("kun");
  let last = ref("ba");


  let fullName = computed({
    get:() => {
      return first.value + ' ' + last.value
    },
    set:(newvalue) => {
      const names = newvalue.split(" ");
      first.value = names[0];
      last.value = names[1];
    }
  })

  const btnclick = () => {
    fullName.value = "coder kun"
  }

watchEffect

watchEffect传入的函数会被立即执行一次,并且在执行的过程中会收集依赖;

只有收集的依赖发生变化时,watchEffect传入的函数才会再次执行;

const name = ref("hello")
const age = ref("18")

watchEffect(() => {
  console.log("watcheffect",name.value,age.value)
})
const btnclick = () => {
  name.value = "hi"
  age.value = 23
}
return{
  name,
  age,
  btnclick
}

watchEffect的停止侦听

setup(){
  const name = ref("hello")
  const age = ref("18")

 const stop = watchEffect(() => {
    console.log("watcheffect",name.value,age.value)
  })
  const btnclick = () => {
    // name.value = "hi"
    // age.value = 23
    age.value++;
    if (age.value > 25){
      stop();
    }
  }

这个时候我们可以获取watchEffect的返回值函数,调用该函数即可。

watchEffect清除副作用

setup中使用ref

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MkkYrxak-1669985503691)(C:\Users\jia\AppData\Roaming\Typora\typora-user-images\image-20221004012044488.png)]

watchEffect的执行时机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u1XWWW8P-1669984040392)(C:\Users\jia\AppData\Roaming\Typora\typora-user-images\image-20221004012322694.png)]

setup(){
  const name = ref("zlk");
  const age = ref(18);
  const titleref = ref(null)
  const stopwatch = watchEffect(() => {
    console.log(titleref.value)
  },{
    flush:"post"
  })

调整watchEffect的执行时机

{
flush:“post”
}

Watch的使用

单个数据源监听

一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref);

直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);

ref

// const name = ref('zlk')
// const age = ref(18)

// watch(name , (newname,oldname) => {
//   console.log(newname,oldname)
// })

reactive

// const state = reactive({
//   name:'zlk',
//   age:18
// })
// watch(() => state.name, (newname,oldname) => {
//   console.log(newname,oldname)
// })

侦听器还可以使用数组同时侦听多个源

// watch([name,age], (newname,oldname) => {
//   console.log(newname,oldname)
// })

侦听一个数组或者对象 ,使用一个getter函数,并且对可响应对象进行解构

// const names = reactive(["abc","bnm","nba"])
// watch(() => [...names],(newvalue,oldvalue) => {
//   console.log(newvalue,oldvalue)
// })

侦听一个深层的侦听,那么依然需要设置 deep 为true:

p也可以传入 immediate 立即执行;

声明周期钩子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZVomp9Jc-1669984040402)(C:\Users\jia\AppData\Roaming\Typora\typora-user-images\image-20221006145743691.png)]

setup(){
  const content = ref(0);
  console.log("开始创建组件")
  onMounted(() => {
    console.log("onMounted-组件挂载到页面之后")
  })
  onBeforeMount(() => {
    console.log("onBeforeMount-组件挂载到页面之前")
  })
  onUpdated(() => {
    console.log("onUpdated-组件更新之后")
  })
  onActivated(() => {
    console.log("onActivated")
  })
  onUnmounted(() => {
    console.log("onUnmounted")
  })
  onBeforeUpdate(() => {
    console.log("onBeforeUpdate-组件更新之前")
  })
  const btnclick = () => {
    content.value++;
  }
  return{
    content,
    btnclick
  }
}

created 和 beforecreate直接在setup里面写就可以了,vue3取消了,例如之前我们请求数据在created中请求,现在可以直接在setup里面写axios代码不用函数包裹调用

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值