vue的官网当中有详细的介绍,但描述的实在太官方了,你要读懂它估计要反复阅读好几遍
https://cn.vuejs.org/guide/essentials/reactivity-fundamentals.html#caveat-when-unwrapping-in-templates
ref() 函数和 reactive() 都是为了使一个属性变成响应式的,那么什么是响应式的,什么又是不响应式的呢?
响应式 和 非响应式
我个人理解,所谓响应式,就是一个地方变化了之后,其他依赖这个地方的地方也跟着相应的变化,这就是响应式的,反之就是不响应式的。
比如,页面上有好多个地方都引用了一个变量,要是我在某个时刻改变了这个变量的值,这时如果这个页面上引用这个变量的地方的都跟着变化了,那这就叫响应式的。
再比如
const a = ref(1)
const b = ref(1)
const c = computed(args => {
return a.value + b.value
});
console.log(c.value);
a.value = 2;
console.log(c.value);
上面这个也叫响应式的,当然JavaScript语言本身也不是响应式的,这种写法是vue自己的特性,可以看到这里使用了一个 computed() 函数,这样定义的变量叫做计算属性,目的就是把一个变量变成响应式的。
let a = 1;
const b = ref(1)
const c = computed(args => {
return a + b.value
});
console.log(c.value);
a = 2;
console.log(c.value);
这种性质在Java这种语言中是不可理解的。
int a=1;
int b=2;
int c=a+b
System.out.println(c)
a=2;
System.out.println(c)
ref() 函数和 reactive()
我自己总结一下
在组合式 API 中,推荐使用 ref() 函数来声明响应式状态,ref() 接收参数,并将其包裹在一个带有 .value 属性的 ref 对象中返回。这里用的是引用对象实现的,既然是引用,那意思就是说你现在拿到的是一个包含了原对象的新的对象,我明确告诉你你拿到的不是原来的对象哟,你想要使用的时候必须时刻记得是用.value的方式来操作原来的对象。
reactive()与将内部值包装在特殊对象中的 ref 不同,reactive() 将使对象本身具有响应性,从而变成一个响应式对象,这个响应式对象是 JavaScript 代理对象,用的是代理的方式实现的,既然是代理,那意思就是表面上看是一模一样,但是骨子里还是有区别的,你要时刻注意,你拿到的其实已经不再是原来的对象了。
ref()
import {reactive, ref} from "vue";
let villagers = ref([]);
villagers.value.push({});
villagers.value.pop();
villagers.value.filter(value=>{});
reactive()
import {reactive, ref} from "vue";
let villagers = reactive([]);
villagers.push({});
villagers.pop();
villagers.filter(value=>{});
小例子
想要实现下面的效果
最终的代码如下,但是一开始的各种错误写法导致一直无法实现这样的效果,找原因找了好久,主要就是 ref() 和 reactive() 使用的问题. 这次彻底了解了一下这俩货的用途。
<template>
<el-form :model="form" class="el-form">
<el-form-item label="姓名">
<el-input v-model="form.name" clearable @input="search"/>
</el-form-item>
</el-form>
<el-table :data="villagers" style="width: 100%">
<el-table-column label="姓名" prop="name"/>
<el-table-column label="手机号" prop="phone"/>
<el-table-column label="证件类型" prop="cardType"/>
<el-table-column label="证件号码" prop="cardNo"/>
<el-table-column label="卡号/账号" prop="account"/>
</el-table>
</template>
<script setup>
import {reactive, ref} from "vue";
const villagerList = [{
name: '孙士河',
phone: '152****2966',
cardType: '0100',
cardNo: '131***********0217',
account: '623************8261',
}, {
name: '杨彦芳',
phone: '158****2205',
cardType: '0100',
cardNo: '131***********0212',
account: '623************4722',
}]
const villagers = ref(villagerList);
const form = reactive({
name: ''
});
const search = () => {
console.log('search:', form.name);
villagers.value = villagerList.filter(villager => {
return villager.name.includes(form.name);
});
}
</script>
<style>
.el-form {
display: flex;
}
</style>
ref 实现
如果使用 ref()实现 则定义如下
const villagers = ref(villagerList);
const search = () => {
console.log('search:', form.name);
villagers.value = villagerList.filter(villager => {
return villager.name.includes(form.name);
});
}
错误写法
let villagers = ref(villagerList);
const search = () => {
console.log('search:', form.name);
villagers = villagerList.filter(villager => {
return villager.name.includes(form.name);
});
}
reactive 实现
let villagers = reactive(villagerList);
const search = () => {
console.log('search:', form.name);
const villagers2 = villagerList.filter(villager => {
return villager.name.includes(form.name);
});
villagers.length = 0;
villagers.push(...villagers2);
}
错误写法1
let villagers = reactive(villagerList);
const search = () => {
console.log('search:', form.name);
const villagers2 = villagerList.filter(villager => {
return villager.name.includes(form.name);
});
villagers=[];
villagers.push(...villagers2);
}
错误写法2
let villagers = ref(villagerList);
const search = () => {
console.log('search:', form.name);
villagers = villagerList.filter(villager => {
return villager.name.includes(form.name);
});
}