神奇的vue3

【七十二变】数据响应:

        ref一般用于定义基本类型数据 也可以安排引用类型

        reactive只能定义引用类型数据

        示例如下:

<template>
  <h1>姓名:{{ bb.name }}</h1>
  <h2>{{ bb.c.d.e }}</h2>
  <button @click="change">按钮</button>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
import {h} from "vue"
import {ref, reactive} from "vue";
export default {
  name: 'App',
  components: {
    HelloWorld
  },
  setup() {
    //  ref一般用于定义基本类型数据 也可以安排引用类型
    let name = ref('嘎嘎')
    let age = 20;
    // reactive只能定义引用类型数据
    let bb = ref({
      name: "咖喱哥给",
      age: 85,
      c: {
        d: {
          e: "是是是"
        }
      }
    });

    function change() {
      console.log(bb.value.name = "发放")
      bb.value.c.d.e = "哼哼"
    }
    /*返回对象的时候可以把返回的数据可以直接在模板使用*/
    return {
      name,
      age,
      change,
      bb
    }
    /*返回一个函数直接渲染页面*/
    // return () => h('h3', "笑死我了")
  }
}
</script>

        vue2数据代理问题:

                引用数据改变其内部属性值不会发生响应,可以用this.$set(对象/数组,键,值),

                删除同理:   this.$delete(对象/数组,键,值)

                数组键为下标

        数据代理原理:

                vue2:

Object.defineProperty(数据,键,{  
get(){
读取会执行这个get函数
},
set(改变的数据){
读取会执行这个set函数,在这里更新页面
}
})

                vue3:

                               ref 还是用vue2数据劫持原理,reactive才用代理。

    let 源数据  = {
        name:"ggg"
    }

    let pp = new Proxy(源数据,{
        get(源数据,读取的键名){
            return Reflect.get(源数据,"键")      
        },

        //set 修改和新增都调佣
        set(源数据,修改的键名,修改的值){
        Reflect.set(源数据,"键","修改的值")
      
        },

        deleteProperty(源数据,删除的键名){
          return  Reflect.deleteProperty(源数据,"键") 
         }
    })

                  Reflect可以返回执行结果以防止程序裂开便于捕获错误。

                Reflect.set(源数据,"键","修改的值")    修改对象数据
                Reflect.get(源数据,"键")           读取对象数据
                Reflect.deleteProperty(源数据,"键")  删除对象数据


 

【两件法宝】setup形参:

        父级:

<template>
  <h1>爸爸</h1>
    //引入的子组件                      //自定义事件
  <hello-world msg="草拟吗" md="妈的" @fuck="fu">
    //匿名插槽传结构
    <view>爸爸传的匿名插槽插槽曹</view>
  //具名插槽传结构
    <template v-slot:qwq>
      爸爸的qwq插槽
    </template>
  </hello-world>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
import {h} from "vue"
import {ref, reactive} from "vue";

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  setup() {    //回调参数
    function fu(value){
      alert("我是你大爹:"+value)
    }
    return {
      fu
    }
  }
}
</script>

        子级:

<template>
  <h1 style="width: 100px;height: 100px;background-color: #42b983">{{msg}}</h1>
    //接收父级传的结构
  <slot></slot>
  <button @click="test">儿子按钮</button>
  <slot name="qwq"></slot>
</template>

<script>
export default {
  name: 'HelloWorld',
//传参名称
  props:['msg','md'],
 //自定义事件名称
  emits:['fuck'],
  // props接受的参数   上下文对象:没有接受的参数attrs  插槽内容  父级传的自定义函数等;
  setup(props,context){
    function test(){
     //自定义事件名称,给父级传的参数
      context.emit("fuck","骚狐狸")
    }
    return{
      test
    }
  }
}
</script>

【神机妙算】计算属性: 

<template>
  <h1>我的信息</h1>
  姓:<input type="text" v-model="ren.name1">
  <br>
  名:<input type="text" v-model="ren.name2">
  <h1> 名字: <input type="text" v-model="ren.name">          </h1>
</template>
<script>
import {h} from "vue"
                //计算属性需要引入
import {ref, reactive, computed} from "vue";
export default {
  name: 'App',
  setup() {
    let ren = reactive({
      name1: "杨",
      name2: "键",
    })
      //偷懒写法
    // ren.name = computed(() => {
    //   return ren.name1 + "~" + ren.name2
    // })
    // 完整写法
    ren.name = computed({
      get(){
        return ren.name1 + "~" + ren.name2
      },
      set(value){
        // 拿到ren.name 做些操作
        console.log(value)
      }
    })
    return {
      ren
    }
  }
}
</script>

【瞅你咋地】监视属性:

                reactive定义的当监视数据是函数返回的deep才有用,否则默认强制开启。

                reactive定义的当监视数据不是函数返回的就无法获取正确的oldvalue。

//监视ref定义的一个响应数据  不需要.value
    watch(被监视数据,(新,旧)=>{},{deep、immediate等等配置项})

//监视ref定义的多个响应数据
    watch([被监视数据1,被监视数据2,被监视数据3],([新1,新2],[旧1,旧2])=>{},{deep、immediate等等配置项})

//监视reactive定义的多个响应数据        ref定义的引用数值需要.value也可以加deep解决
    // 重大问题:1、此处无法获取正确的oldvalue
    //           2、默认强制开启深度监听无法通过配置项关闭
        watch(数据,(新,旧)=>{},{immediate等等配置项})
    
//监视reactive定义的指定单个响应数据            ref定义的引用数值需要.value也可以加deep解决
    watch( ()=>数据.键,(新,旧)=>{},{immediate等等配置项})
    
//监视reactive定义的指定一些响应数据      ref定义的引用数值需要.value也可以加deep解决
    watch( [()=>数据.键,()=>数据.键,],(新,旧)=>{},{immediate等等配置项})
    
 //监视reactive定义的指定的引用数据   此时deep有用    ref定义的引用数值需要.value也可以加deep解决
    watch( ()=>数据.键,(新,旧)=>{},{deep、immediate等等配置项})

        超级无敌智能监视:

 watchEffect(()=>{
      //在这里面用谁,就监视谁,谁动就执行,可以检测多个数据变化,默认深度监视
 })

【花开花落】vue3生命周期

实例的生命周期

         setup()生命周期在beforeCreate之前。

        上面八个生命周期可以在setup里写,需要统一在vue引入,前面加统一加on,以函数的方式调用传入要执行的回调函数。如下图所示:

import {ref, reactive, computed,watch,watchEffect,onBeforeMount} from "vue";
export default {
  name: 'App',
  setup() {
    onBeforeMount(()=>{
      console.log("的")
    })
    return {
    }
  }
}

        

【厚德载物】hook自定义函数:

        可以让vue3组合式api发挥巨大威力,一个完成的功能就是一个hook函数,不像vue2,数据、功能、监视、计算、生命周期拆开。

        相当于vue2的混入,你可以把vue的所有api(ref、reactive、on生命周期等)用于写一个功能返回并导出实现代码复用。

【引蛇出洞】toRef、toRefs:

        作用:

              toRef:创建ref对象可以让你把对象里的属性单独拿去用还不丢失响应式,用对象而不用点运算符取。

               toRefs:把对象的一级属性全部暴露取出。

<template>
  {{sonName }}
  {{ name }}
  {{ age }}
</template>
<script>
import {ref, reactive, toRef, toRefs} from "vue";
export default {
  name: 'App',
  setup() {
    let son = reactive({
      name: "啊狗",
      age: 88
    })
    let fu = reactive({
      name: "大狗",
      age: 22
    })
    let sonName = toRef(son, 'age')
    return {
      sonName,
      ...toRefs(fu)
    }
  }
}
</script>

【三十六变】shallowReactive、shallowRef(vue引入):

        shallowReactive():只考虑对象的一级属性的响应。

                应用场景:1、数据比较深;2、只要求一级属性响应。

        shallowRef():如果传入对象则不考虑对象一级属性的响应。

                应用场景:1、不要求对象一级响应要整体替换的时候。

【数据保安】readonly、shallowReadonly:

        readonly(): 接收ref、reactive生成的数据让数据所有地方不可改变。

        shallowReadonly(): 只让对象的一级属性不可改变。

【返璞归真】toRaw、markRaw:

        toRaw():只能把reactive的响应对象变成普通对象;

        markRaw():让普通对象终身无法响应,给reactive对象添加的普通数据会自动变成响应对象,如果你没有让新对象响应的需求,那你就安排这个标记函数,提高效率。

【毛坯房】customRef:

        customRef可以在响应中读取或者写入修改数据中写入自己个性化的代码。比如在输入框输入数值一秒后再改变,只能处理基本类型。

<template>
  <input type="text" v-model="didi">
  <h1>{{ didi }}</h1>
</template>
<script>
import {ref, reactive, toRef, toRefs, customRef} from "vue";
export default {
  name: 'App',
  setup() {
    function myRef(value) {
      let timer;
      return customRef((track, trigger) => {
        return {
          get() {
            track()//追踪value最新的数据变化,如果不调用则返回旧数据
            return value
          },
          set(v) {
            clearTimeout(timer)
            timer = setTimeout(() => {
              value = v
              trigger() //让vue重新解析模板
            }, 1000)
          }
        }
      })
    }
    let didi = myRef("哈哈")
    return {
      didi
    }
  }
}
</script>

【祖先的恩赐】 

        祖代传:引入provide,provide(键名,值)

        后代收:引入inject,inject(键名)

【验明正身】     

        isRef:是否为ref对象;

        isReactive:是否为reactive创建的响应代理对象;

        isReadonly:是否为readonly创建的只读代理对象;

        isProxy:是否由reactive或者readonly创建的代理对象;

【新人报道】

        Fragment:vue3默认给你包一个根标签就是 Fragment标签,可以减少不必要的标签。

        Teleport:可以让你写的结构不在写结构的位置出现,可以在任意位置出现。

<!--        想传送到哪里的标签名、或者选择器#id-->
  <teleport to="html">
    <div v-if="show" style="width: 100px;height: 100px;background-color: yellow">
      <h1>我说弹窗</h1>
      <button @click="show=false">关闭</button>
    </div>
  </teleport>

        Suspense:可以让组件异步出现,需要配合动态引入;

<template>
<div style="background-color: #42b983;padding: 30px">
  孙子的{{b}}
  <Suspense>
    //组件加载完展示真实的组件内容
    <template v-slot:default>
      <Dialog  />
    </template>
 //组件没加载完展示的虚假内容
    <template v-slot:fallback>
      等等我
    </template>
  </Suspense>
</div>
</template>
<script>
import {inject,ref,defineAsyncComponent} from "vue";
//动态引入  页面会先渲染,再渲染组件
let  Dialog = defineAsyncComponent(()=> import("@/components/Dialog"))
export default {
  name: "sun",
  components:{
    Dialog
  },
  setup(){
    let  show = ref(false)
  return {
    show
  }
  }
}
</script>

        在以上的基础上,setup函数可以返回一个new Promise 或者给setup写成async函数。.

坑坑洼洼

        获取dom对象

首先只有在挂载后才能获取到元素对象,所以获取的属性值要写在挂载声明周期;

机构写法
<div  ref="dom"> </div>

js写法
 let dom = ref(null);
    onMounted(()=>{
      console.log(dom.value)
  })

return{

    dom
    }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值