Vue3初识 学习记录(一)

Vue3的响应式

Vue2的响应式是通过Object.defindeProperty的访问器属性来调用get和set方法,并且会通知观察者Wacher重新render组件. 这种方法对于深层的数据是不太友好的,不能直接监听对象和数组的变化.

Vue3中的响应式则是通过 Proxy 替代Object.defineProperty,这样就可以直接监听对象和数组的变化,并且有多达13种拦截方法。
实现深度观测的方法: 判断当前的Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理.
核心:
(1)通过Proxy(代理):拦截对data任意属性的任意操作.
(2)通过Reflect(反射):动态对被代理对象的相应属性进行特定操作

<script type="text/javascript">
    //目标对象
    const user = {
      name: 'zmj',
      age: 20,
      wife: {
        name: 'bb',
        age: 19
      }
    }

    // 把目标对象变为代理对象
    // 参数1:user---->target目标对象
    // 参数2:handler----->处理器对象,用来监视数据及操作
    const proxyUser = new Proxy(user, {
      // 读取属性值
      get(target, prop) {
        console.log('get调用了');
        return Reflect.get(target, prop)
      },
      // 修改、添加目标对象的属性
      set(target, prop, val) {
        console.log('set调用了');
        return Reflect.set(target, prop, val)
      },
      // 删除属性值
      deleteProperty(target, prop) {
        console.log('delete调用了');
        return Reflect.deleteProperty(target, prop);
      }
    })

    // 通过代理对象获取目标对象中的某个值
    console.log(proxyUser.name);

    // 通过代理对象更新目标对象上的某个属性值
    proxyUser.name = 'lqb'
    console.log(user);

    // 通过代理对象向目标对象添加新的属性值
    proxyUser.gender = '男',
    console.log(user);

    // 通过代理对象向目标对象删除对应属性
    delete proxyUser.name;
    console.log(user);

    // 深度监视
    proxyUser.wife.name = 'zzz'
    console.log(user);
  </script>

常用的Composition API

setup():

执行时机: 在beforeCreate之前执行一次,并且this为undefined.
参数:
(1)props:值为对象, 包含组件外部传递过来,且组件内部声明接受了的属性.
(2)context: 上下文对象:
attrs:值为对象,包含组件外部传递进来但是没有在props配置中声明的属性,即相当于this. a t t r s . s l o t s : 收 到 的 插 槽 的 内 容 , 相 当 于 t h i s . attrs. slots:收到的插槽的内容,相当于this. attrs.slots:,this.slots.
emit:分发自定义事件的函数,相当与this.$emit


reactive():

作用: 定义一个对象类型的响应式数据(基本类型要用ref)。
reactive定义的响应式数据是"深层次的",不管数据有多深都能监视得到。
基于Proxy实现,通过代理对象操作源对象内部数据进行操作。
获取reactive代理数据值时,不需要 .value
但是使用ref代理时,取得值就需要. value

<script lang="ts">
import { reactive } from "@vue/reactivity";
import { defineComponent } from "@vue/runtime-core";

interface IPersion {
  name: string;
  age: number;
  job: {
    type: string,
    salary: string,
    a: any
  };
  hobby: any;
}

export default defineComponent({
  setup() {
    const persion: IPersion = reactive({
      name: "李四",
      age: 19,
      job: {
        type: "前端工程师",
        salary: "20K",
        a: {
          b: {
            c: 666,
          },
        },
      },
      hobby: ["抽烟", "喝酒", "烫头"],
    });

    function changeInfo() {
      persion.name = "李四";
      persion.age = 48;
      persion.job.type = "JAVA工程师";
      persion.job.salary = "60K";
      persion.job.a.b.c = 999;
      persion.hobby[0] = "学习";
    }

    return {
      persion,
      changeInfo,
    };
  },
});
</script>

computed():

vue3中的计算属性是可以直接在setup中使用的,只需要从vue中引入computed即可

<script lang="ts">
import { reactive, computed} from "vue";
import { defineComponent } from "@vue/runtime-core";

export default defineComponent({
  setup() {
    let person = reactive({
      firstName: '张',
      lastName: '三',
    })
    person.fullName = computed(() => {
      return person.firstName + person.lastName
    })

    return {
      person
    };
  },
});
</script>

计算属性里的值是只读属性,不可以修改.如果要修改需要考虑读和写的完整写法

setup() {
    let person = reactive({
      firstName: '张',
      lastName: '三',
    })
    person.fullName = computed({
      get() {
        return person.firstName + '-' +person.lastName
      },
      set(value) {
        const nameArr = value.split('-')
        person.firstName = nameArr[0]
        person.lastName = nameArr[1]
      }
    })

    return {
      person
    };
  },

watch():

watch可以在setup中多次调用。并且监视的是用 ref 或者 reactive 代理的数据类型。
watch监视的是一个属性而不是一个 所以用ref定义的基本数据被监视时不需要 .value
watch接受三个参数:
第一个:监视的对象
第二个:数据变化后需要做的操作,也就是一个回调函数,将新的值与旧的值作为参数传入这个回调函数中。
第三个:传入一个对象,里面是各种配置项

import { ref, watch} from "vue";

export default ({
  setup() {
    
    let sum = ref(0)

    watch(sum, (newValue, oldValue) => {
      console.log('sum变了', newValue, oldValue);
    }, {immediate:true, deep: true})

    return {
      sum
    };
  },
});

如果是监视reactive所定义的一个响应式数据的全部属性时,则得不到oldValue,并且会强制开启深度监视,无法关闭。

import { reactive,ref, watch} from "vue";

export default ({
  setup() {
    const person = reactive({
      name: 'zmj',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })

    watch(person, (newValue, oldValue) => {
      console.log('person改变了', newValue, oldValue);
    })

    return {
      person
    };
  },
});

但是如果是监视reactive所定义的一个响应式数据的某个属性时,就可以得到oldValue,但是第一个参数需要是一个函数并且返回监视的那个属性

<script>
import { reactive,ref, watch} from "vue";

export default ({
  setup() {
    const person = reactive({
      name: 'zmj',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })

    watch(() => person.age, (newValue, oldValue) => {
      console.log('age改变了', newValue, oldValue);
    })

    return {
      person
    };
  },
});
</script>

watchEffect():

用法:不需要指明监视哪个属性,回调函数中用到哪个属性,就监视哪个属性。不用写返回值。

watchEffect(() => {
      const x1 = person.age
      console.log('watchEffect执行了');
    })

toRef()/toRefs():

作用:创建一个ref对象,其value值指向另一个对象中的某个属性。
应用:要将响应式对象中的某个属性单独提供给外部使用时。
语法:

let person = reactive({
	name: 'zzz',
	age:'18'
})

const name = toRef(person, 'name')

toRefs():批量创建多个ref对象。
语法:

let person = reactive({
	name: 'zzz',
	age:'18'
})

const x= toRefs(person)

shallowReavtive():

作用:只处理对象最外层属性的响应式。

shallowRef():

作用:只处理基本数据类型的响应式,不进行对象的响应式处理。


toRaw():

作用:将一个由reactive生成的响应式对象转为普通对象。
应用:用于读出响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面的更新。

markRaw():

作用:标记一个对象,使其永远不会再成为响应式对象。
应用:一些第三方类库的值不应该被设置为响应式。当渲染某些不可变数据源的列表时,跳过响应式转换可提高性能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值