前言:vue3重写了数据绑定,v2基于
Object.defineProperty()
实现;v3 基于
Proxy
实现。v3的优势有:可以监听数组变化;可以监听动态新增的属性;可以监听删除的属性;可以监听数组的索引和length属性。
所以我们在使用vue3数据绑定的时候也需要加入新的api:
ref
绑定基本数据类型为proxy响应对象、
isRef
判断是否为ref对象
<template>
<!-- ref基础用法 -->
<input type="text" v-model="msg.name" />
<div @click="cahngeMsg">{{ msg.name }}</div>
</template>
<script setup lang="ts">
import { ref, isRef } from 'vue';
// ref 将msg变量变成一个’双向绑定‘变量
const msg: {} = ref({ name: 'name' });
const cahngeMsg = () => {
// 在给ref对象赋值的时候需要加.value
msg.value.name = '点击后的信息';
// isRef判断变量 是不是’双向绑定‘变量
console.log(isRef(msg, 'msg')); //true
</script>
reactive
绑定引用数据类型为proxy响应对象
注:上面用ref去绑定对象、数组等复杂的数据类型,源码里面其实也是去调用reactive绑定。
<template>
<!-- 属性框 -->
<input type="text" v-model="msgFrom.name" />
<div>姓名:{{ msgFrom.name }}</div>
<input type="text" v-model="msgFrom.age" />
<div>年龄:{{ msgFrom.age }}</div>
<input type="text" v-model="msgFrom.gender" />
<div>性别:{{ msgFrom.gender }}</div>
<div @click="cahngeMsg">提交From</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
// reactive对比ref用法
// 只能绑定引用类型
// 取值、赋值、改变 不需要加.value
// 定位为数组的时候不能直接赋值,会破坏Proxy响应对象
const msgFrom = reactive({
name: '姓名',
age: '年龄',
gender: '性别',
const cahngeMsg = (value: string) => {
msgFrom.name = '1111';
// 注意:一定要在ref对象后面加value获取值
console.log(msgFrom);
</script>
ref
其他用法:获取dom对象
<template>
<!-- ref获取dom基础用法 -->
<div ref="msgRef" @click="cahngeMsg">获取dom</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const msgRef = ref<HTMLDivElement>();
const cahngeMsg = (value: string) => {
// 注意:一定要在ref对象后面加value获取值
console.log(msgRef.value.innerHTML, 'msgRef');
</script>
shallowRef
、triggerRef
基础用法
<template>
<!-- ref基础用法 -->
<input type="text" v-model="msg.name" />
<div @click="cahngeMsg">{{ msg.name }}</div>
</template>
<script setup lang="ts">
import { shallowRef, triggerRef } from 'vue';
// shallowRef对比ref是比较浅层次的响应(使用方法如下)
const msg: {} = shallowRef({ name: 'name' });
const cahngeMsg = () => {
// 错误的使用方法 value对象的name值会改变但是视图上不会
msg.value.name = '点击后的信息';
// 正确的使用方法 注意:不能在shallowRef更新变量的时候,用ref更新变量
msg.value = { name: '点击后的信息' };
// triggerRef强制跟新ref绑定数据(包括shallowRef) 注意:使用ref会自动调用triggerRef
triggerRef(msg);
</script>
customRef
用法(工厂函数实现get和set适合去做防抖之类的)
<template>
<!-- customRef基础用法 -->
<input type="text" v-model="msg" />
<div @click="cahngeMsg">{{ msg }}</div>
</template>
<script setup lang="ts">
import { customRef } from 'vue';
// 定义自定义的函数响应函数
const myCustom = (value: any) => {
return customRef((track, trigger) => {
return {
get() {
console.log(value, 'get');
track();
return value;
set(newVal) {
console.log(value, newVal, 'set');
value = newVal + '---';
trigger();
// myCustom实例使用
var msg: string = myCustom('install');
// 手动更新数据
const cahngeMsg = (value: string) => {
msg.value = '111';
</script>
readonly
拷贝一份proxy对象将其设置为只读
shallowReactive
只能对浅层的数据 如果是深层的数据只会改变值 不会改变视图
toRef
将普通对象变成ref对象,如果原始对象是响应式的是会更新视图并且改变数据的,如果原始对象是非响应式的就不会更新视图数据是会变的。
toRefs
原理和 toRef
一样,多个对象可直接结构赋值 reactive
内的对象;
toRaw
将响应式对象变成普通对象