Vue3的Compoisition API 初览

1.Compoisition API

  Composition API字面意思是组合API,它是为了实现基于函数的逻辑复用机制而产生的,将组成组件的内容划分为各种逻辑,并将这些逻辑通过Composition Api*(组合APi)来明朗化。

2.setup函数和常用的Compoisition API

 如果 setup 返回一个对象,则该对象的属性将合并到组件模板的渲染上下文中:

<template>
  <div>{{ count }} {{ object.foo }}</div>
</template>
 
<script>
//reactive 和 ref 都是用来定义响应式数据的 reactive更推荐去定义复杂的数据类型 ref 更推荐定义基本类型

//ref 和 reactive 本质我们可以简单地理解为ref是对reactive的二次包装, ref定义的数据访问的时候要多一个.value

  import { ref, reactive } from 'vue'
 
  export default {
 props: {
    name: String
  },

//该函数将接收到的 prop 作为其第一个参数
//context:
//上下文对象            对应之前vue2的
// context.attrs    this.$attrs 	 组件标签上的属性(非响应式对象)
//context.slots	 this.$slots	 插槽(非响应式对象)
//context.emit 	 this.$emit		 标签上自定义的触发事件(方法)
//context.emit('自定义事件名',参数)
//attr ->> Noe-props属性 <child app="app"/> 不用props接收 就会被attrs接收到
//slots ->> <child>parent</child> ->> slots.default()获取到 ()=> h('div',{},slots.default())
//setup函数在created生命周期之前就会触发 所以里面不能用this对象了

handleChange(){

      alert('change')
}

  template: `<child @change="handleChange"></child>`
    setup(props,context,toRefs,readonly,toRef) {
     // ref 一般是简单变量使用
      const count = ref(0)
      // reactive一般是复杂机构的 如 对象 数组等使用
      const object = reactive({ foo: 'bar' })
      //用toRefs解构出来的变量是响应式的
      // toRefs解构出来的样子从propxy({name:'dell'}) 变成{name:proxy({value:'dell'})}
      const {name}=toRefs(object )
      //只读的 不能修改
      const copyName = readonly(object );
      //从object里面取 如果没有 就是空数据
        const age = toRef(object , "age");

      // 暴露到template中
      return {
        count,
        object
      }
    }
  }
 app.component("child", {
      template: `<div @click="handleClick">child</div>`,
      setup(props, context) {
        const { attrs, slots, emit } = context;
        function hanldeClick() {
          emit("change");
        }
        return { hanldeClick };
      },
    });
</script>

3.computed方法

 

const app = Vue.createApp({
      setup() {
        const { ref, computed } = Vue;
        const count = ref(0);
        const handleClick = () => {
          count.value += 1;
        };
        const countAddFive = computed(() => {
           return count.value + 5;
         });
      // 类似ES6的proxy 可以设置set 和 get操作时的拦截器
        const countAddFive = computed({
          get: () => {
            return count.value + 5;
          },

          set: (param) => {
            count.value = param - 5;
          },
        });
        setTimeOUt(()=>{

              countAddFive  = 100
       },1000)
        return { count, handleClick, countAddFive };
      },
      template: `
            <div>
                <span @click="handleClick">{{count}}</span> -- {{countAddFive}}
            </div>
        `,
    });

4.watch和watchEffect

 

setup() {

    const { ref, computed, watch, reactive, toRefs, watchEffect } = Vue;
        const name = ref("hzx");
//参数可以拿到原始的和现在的值
//具备一定的惰性lazy 首次页面展示的时候不会执行
//立即执行 无惰性 加入immediate选项立即执行
  watch(name, (currentValue, preValue) => {

               console.log(currentValue,preValue)
 
   }, { immediate: true });

}
//使用比较多的是异步请求 
 const stop = watchEffect(() => {
          // nameObj.name 只要检测到对数据有依赖 就会有侦听
          console.log(nameObj.name)
          setTimeout(() => {
            //   停止侦听 watch和这里的方法一样
            stop();
          }, 5000);
 });

5.setup中的生命周期函数

 const app = Vue.createApp({
      setup() {
        const {
          onBeforeMount,
          onMounted,
          onBeforeUpdate,
          onUpdated,
          onBeforeUnMount,
          onUnmounted,
          onRenderTracked,
          onRenderTriggered,
        } = Vue;
        onBeforeMount(() => {
          console.log("onBeforeMount");
        });
        onMounted(() => {
          console.log("onMounted");
        });
        onBeforeUpdate(() => {
          console.log("onBeforeUpdate");
        });
        onUpdated(() => {});

        onRenderTracked(() => {
          //页面渲染之后 重新收集响应式依赖
        });
        onRenderTriggered(() => {
          // 页面再次渲染 会执行
        });
      },
      template: `
            <div>
               
                 Hello World
            </div>
        `,
    });

 6.setup中的provide和ref(获得真实的DOM)

    const app = Vue.createApp({
      setup() {
        const { ref, provide, readonly } = Vue;
        const name = ref("dell");
        // 传递给子组件的数据是只读的
        provide("name", readonly("dell"));

        // 提供改变name的方法
        provice("changeName", (value) => {
          name.value = value;
        });
      },
      template: `
            <div>

                 <child/>
            </div>
        `,
     return {name,handleClick}
    });
    app.component("child", {
      setup() {
        const { inject } = Vue;
        // 默认值hello
        const name = inject("name", "hello");
        const changeName = inject("changeName");
        const handleClick = () => {
          changeName("lee");
        };
        return { name, handleClick };
      },
      template: `<div @click="handleClick">child</div>`,
    });

 

   //获取真实的DOM
    const app = Vue.createApp({
      setup() {
       //获取这个DOM节点
        const { ref } = Vue;
        const hello = ref(null);
          onMounted(() => {
          //获取这个DOM节点
          console.log(hello.value);
        });
        return { hello };
      },
      template: `
            <div>
                 //获取这个DOM节点
                 <div ref="hello">helloworld</div>
            </div>
        `,
    });

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值