Vue笔记10-其它Composition API

shallowReactiveshallowRef

shallow:浅的,和deep相反
shallowReactive:只处理对象最外层属性的响应式
shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理
如果有一个对象数据,结构比较深,但是变化只对外层属性变化:使用shallowReactive
如果有一个对象数据,后序不会修改对象中的属性,而是生成新的对象来替换:使用shallowRef

<template>
  <h4>当前的x.y值是:{{ x.y }}</h4>
  <button @click="x={y:888}">点我替换x</button>
  <button @click="x.y++">点我x.y++</button>
  <hr>
  <h4>{{ person }}</h4>
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <h2>薪资:{{ person.job.j1.salary }}K</h2>
  <button @click="person.name+='~'">修改姓名</button>
  <button @click="person.age++">增长年龄</button>
  <button @click="person.job.j1.salary++">涨薪</button>
</template>

<script>
import {shallowReactive, shallowRef} from 'vue'

export default {
  name: 'App',
  setup() {
    //数据
    let person = shallowReactive({// 只考虑第一层数据的响应式,在修改salary的时候,是修改不成功的
      name: '张三',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })
    let x = shallowRef({
      y: 0
    });
    console.log('******', x)

    //返回一个对象(常用)
    return {
      x,
      person
    }
  }
}
</script>

readonlyshallowReadonly

readonly:让一个响应式数据变成只读(深只读)
shallowReadonly:让一个响应式数据变成只读(浅只读)

<template>
  <h4>当前求和为:{{ sum }}</h4>
  <button @click="sum++">点我++</button>
  <hr>
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <h2>薪资:{{ person.job.j1.salary }}K</h2>
  <button @click="person.name+='~'">修改姓名</button>
  <button @click="person.age++">增长年龄</button>
  <button @click="person.job.j1.salary++">涨薪</button>
</template>

<script>
import {reactive, readonly, ref, shallowReadonly} from 'vue'

export default {
  name: 'App',
  setup() {
    //数据
    let sum = ref(0)
    let person = reactive({
      name: '张三',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })

    person = readonly(person);// person里的任何东西都改不了
    person = shallowReadonly(person);// 浅层次的readonly,深层次的可以修改
    sum = readonly(sum);// sum改不了
    sum = shallowReadonly(sum);// sum改不了

    //返回一个对象(常用)
    return {
      sum,
      person
    }
  }
}
</script>

toRawmarkRaw

toRaw:将一个reactive生成的响应式对象转为普通对象,用于读取响应式对象对应的普通对象,对这个普通对象的操作,页面都不会更新。
markRaw:标记一个对象,使其永远不会成为响应式对象,当有些值没必要设置成响应式的时候,可以跳过响应式转换提高性能,例如复杂的第三方类库等。

<template>
  <h4>当前求和为:{{ sum }}</h4>
  <button @click="sum++">点我++</button>
  <hr>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪资:{{ job.j1.salary }}K</h2>
  <h3 v-show="person.car">座驾信息:{{ person.car }}</h3>
  <button @click="name+='~'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
  <button @click="showRawPerson">输出最原始的person</button>
  <button @click="addCar">给人添加一台车</button>
  <button @click="person.car.name+='!'">换车名</button>
  <button @click="changePrice">换价格</button>
</template>

<script>
import {markRaw, reactive, ref, toRaw, toRefs} from 'vue'

export default {
  name: 'App',
  setup() {
    //数据
    let sum = ref(0)
    let person = reactive({
      name: '张三',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    });

    function showRawPerson() {
      const p = toRaw(person);
      p.age++;
      console.log(p);
    }

    function addCar() {
      let car = {name: '奔驰', price: 40};
      person.car = markRaw(car);
    }

    function changePrice() {
      person.car.price++;
      console.log(person.car.price);
    }

    //返回一个对象(常用)
    return {
      sum,
      person,
      ...toRefs(person),
      showRawPerson,
      addCar,
      changePrice
    }
  }
}
</script>

customRef

自定义ref,可以对ref包装的数据改动,显示的进行跟踪和触发更新。
写一个效果,写一个input和一个h3,在input里输入内容后,h3的内容等待1秒后展示。

<template>
  <input type="text" v-model="keyword">
  <h3>{{ keyword }}</h3>
</template>

<script>
import {customRef} from 'vue'

export default {
  name: 'App',
  setup() {
    // 自定义一个myRef
    function myRef(value, delay) {
      let timer;
      // 通过customRef去实现自定义
      return customRef((track, trigger) => {
        return {
          get() {
            console.log(`通过get方法读取${value}`);
            track();// 告诉Vue这个value值是需要被“追踪”的
            return value;
          },
          set(newValue) {
            clearTimeout(timer);
            timer = setTimeout(() => {
              value = newValue;
              console.log(`通过set方法设置${newValue}`);
              trigger();// 告诉Vue去更新界面
            }, delay);
          }
        }
      });
    }

    let keyword = myRef('hello', 1000);// 使用程序员自定义的ref
    return {
      keyword
    }
  }
}
</script>

provideinject

实现祖先和后代的组件间通信,祖先组件通过provide将数据提供出去,后代组件通过inject注入数据。
App.vue(祖先组件)

<template>
  <div id="App">
    <h1>我是祖先组件</h1>
    <h2>{{ value }}</h2>
    <button @click="value+=1">点我加1</button>
    <Child></Child>
  </div>
</template>
<script>
import Child from "./components/Child.vue";
import {provide, ref} from "vue";

export default {
  name: 'App',
  components: {Child},
  setup() {
    let value = ref(1);
    provide('value', value);
    return {
      value
    }
  }
}
</script>
<style scoped>
#App {
  background-color: red;
  padding: 10px;
}
</style>

Child.vue(子组件)

<template>
  <div id="Child">
    <h1>我是子组件</h1>
    <GrandChild></GrandChild>
  </div>
</template>
<script>
import GrandChild from "./GrandChild.vue";

export default {
  name: "Child",
  components: {GrandChild}
}
</script>
<style scoped>
#Child {
  background-color: green;
  padding: 10px;
}
</style>

GrandChild.vue(孙组件)

<template>
  <div id="GrandChild">
    <h1>我是孙组件</h1>
    <h1>{{ value }}</h1>
  </div>
</template>
<script>
import {inject} from "vue";

export default {
  name: "GrandChild",
  setup() {
    let value = inject("value");
    return {
      value
    }
  }
}
</script>
<style scoped>
#GrandChild {
  background-color: yellow;
  padding: 10px;
}
</style>

响应式数据的判断

isRef:检查一个值是否是一个ref对象
isReactive:检查一个对象是否是由reactive创建的响应式代理
isReadonly:检查一个对象是否是由readonly创建的只读代理
isProxy:检查一个对象是否是由reactivereadonly方法创建的代理

<template>
  <div>

  </div>
</template>
<script>
import {isProxy, isReactive, isReadonly, isRef, reactive, readonly, ref} from "vue";

export default {
  name: 'App',
  setup() {
    let car = reactive({name:"奔驰",price:100});
    let sum = ref(0);
    let car2 = readonly(car);

    console.log(isRef(sum));
    console.log(isReactive(car));
    console.log(isReadonly(car2));
    console.log(isProxy(car));
    console.log(isProxy(sum));
  }
}
</script>

相关推荐

  1. Vue笔记10-其它Composition API

    2024-07-12 01:00:03       27 阅读
  2. vue3 学习笔记10 -- 父子传参

    2024-07-12 01:00:03       27 阅读
  3. Vue3其它工具类:other.ts

    2024-07-12 01:00:03       30 阅读
  4. Vue3实战笔记16)—pinia基本用法--Getter

    2024-07-12 01:00:03       33 阅读
  5. vue3 学习笔记12 -- 插槽的使用

    2024-07-12 01:00:03       25 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 01:00:03       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 01:00:03       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 01:00:03       62 阅读
  4. Python语言-面向对象

    2024-07-12 01:00:03       72 阅读

热门阅读

  1. Chromium编译指南2024 Linux篇-解决运行报错信息(六)

    2024-07-12 01:00:03       24 阅读
  2. prototype 和 __proto__的区别

    2024-07-12 01:00:03       27 阅读
  3. Spring-Data-Elasticsearch

    2024-07-12 01:00:03       30 阅读
  4. npm ERR! code ENOTEMPTY npm ERR! syscall rename npm ERR!

    2024-07-12 01:00:03       26 阅读
  5. sizeof()

    2024-07-12 01:00:03       26 阅读
  6. Python 四种字符串格式化方式

    2024-07-12 01:00:03       24 阅读
  7. 存取款系统接口设计

    2024-07-12 01:00:03       22 阅读
  8. SpringBoot 自定义异常返回数据格式

    2024-07-12 01:00:03       23 阅读
  9. ubuntu 安装cups和爱普生打印机

    2024-07-12 01:00:03       22 阅读
  10. 服务器怎么进PE系统?

    2024-07-12 01:00:03       27 阅读
  11. 还在代码中写HttpUtil?是时候说再见啦

    2024-07-12 01:00:03       28 阅读