Vue3–customRef节流运用、provide和inject组件、响应式数据的判断

这是我参与更文挑战的第27天,活动详情查看: 更文挑战

一、customRef的节流运用

customRef用于自定义一个ref,可以显示的控制依赖追踪和触发响应,接受一个工厂函数,两个参数分别用于追踪的track与用于触发响应的triger,并返回一个带有get和set属性的对象,在实际开发中可以实现防抖函数。

1.1 首先在hook文件夹下, 新建一个debounce.ts文件

import { customRef } from 'vue'

export function useDebounced<T>(value: T, delay = 300, callback: Function) {
    let timer: any = null
    return customRef((track, trigger) => {
        return {
            get() {
                track() // 告诉vue追踪数据
                return value
            },
            set(newValue: T) {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    value = newValue
                    callback(newValue)
                    trigger() // 告诉vue更新视图
                }, delay);
            }
        }
    })
}
复制代码

1.2 然后在customeRef.vue中用input输入框做演示

<template>
  <div>
      <input type="text" v-model="keyword">
  </div>
</template>

<script lang="ts">
import {useDebounced} from '../hooks/debounce'
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'customRef',
  setup() {
      // 初始值 500延迟 500延迟后的回调方法
      let keyword = useDebounced<string>('',500,(v:string)=>{
          // 这里可以写拿到v后请求接口逻辑
          console.log(v,'节流后的数据');  
      })

      return {
          keyword
      }
  }
});
</script>

<style scoped>

</style>
复制代码

2021-06-27-17-05-31.gif

二、 provide和inject组件通讯

provide和inject可以轻松实现跨层级组件通讯,provide在父组件中返回要传给下级的数据,inject在需要使用这个数据的子辈组件或者孙辈等下级组件中注入数据。

2.1 新建一个provide页面, 提供message消息

<template>
  <div>
    <injectComponent></injectComponent>
  </div>
</template>

<script lang="ts">
import { defineComponent, provide } from "vue";
import injectComponent from "../components/inject.vue";

export default defineComponent({
  name: "",
  setup() {
    provide("message", "你好");
  },
  components: {
    injectComponent,
  },
});
</script>

<style scoped>
</style>
复制代码

2.2 新建一个inject组件, 接收消息

<template>
  <div>
      {{msg}}, 我是inject组件
  </div>
</template>

<script lang="ts">
import { defineComponent,inject } from 'vue';

export default defineComponent({
  name: '',
  setup(){
    let msg = inject('message')
    console.log(msg);
    return {
        msg
    }
  }
});
</script>

<style scoped>

</style>
复制代码

效果:
image.png

2.3 我们看孙级组件中使用

<template>
  <div>
      {{msg}}, 我是孙级组件
  </div>
</template>

<script lang="ts">
import { defineComponent,inject } from 'vue';

export default defineComponent({
  name: '',
  setup(){
    let msg = inject('message')
    console.log(msg);
    return {
        msg
    }
  }
});
</script>

<style scoped>

</style>

然后在子组件中使用
  <div>
      {{msg}}, 我是inject组件
      <p></p>
      <grandson></grandson>
  </div>
复制代码

image.png

三、响应式数据的判断

如果要检测一个数据是否为响应式数据,可以通过 isRef, isReactive,isReadonly,isProxy来判断

<template>
  <div>
      <p>isResponse</p>
  </div>
</template>

<script lang="ts">
import { defineComponent, isRef, ref, isReactive,reactive,isReadonly,readonly,isProxy} from 'vue';

export default defineComponent({
  name: '',
  setup() {
      console.log(isRef(ref('')),'判断是否ref响应式');
      console.log(isReactive(reactive({})),'判断是否reactive响应式');
      console.log(isReadonly(readonly({})),'判断是否readonly只读');
      console.log(isProxy(readonly({})),'判断proxy代理');      
      console.log(isProxy(ref('')),'判断proxy代理');  // ref不是代理   
  }
});
</script>

<style scoped>

</style>
复制代码

image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享