0x01 对引用对象赋值引用不会触发响应!※
直接上代码
<template>
<div class="userSelector">
<input v-model="sUserName"><button @keydown.enter="searchUser" @click="searchUser">检索用户</button>
</div>
<div>
<userCat v-show="isNull" /> <!-- userCat组件在下面 -->
</div>
</template>
<script>
import userCat from './userCat.vue'
import Data from '@/datas/data.js'
export default {
. . .
data() {
return {
sUserName: "",
user: Data.user
}
},
methods: {
async searchUser() {
const data = { text: this.sUserName.toString() };
try {
const response = await this.axios.post("http://localhost:9090/api/findbyname", data);
console.debug(response.data);
if (response.data.length != 0) {
this.user = response.data; // 这里之间赋值引用,Data.user的数据确实变了,但userCat里的{{ user }}就是不变
console.debug(this.user);
} else {
alert("妹有啊!");
}
} catch (error) {
alert(error);
}
}
},
}
</script>
![image](https://pic.aketer.me//i/e1144918-0a79-4264-916b-c076f4d98450.jpg)
这里怎么点下面插件内容都不变,我看后端给的回应都正常的,打了个debug输出Data,Data里面的user也对的,怎么改都不行,最后翻了半天文档才搞明白
下面要这么写
—| this.user = response.data
|
+| Object.keys(response.data).forEach(key => {
+| this.user[key] = response.data[key];
+| });
响应式系统的数据钩子在对象上(setter
、getter
),对象内容改变会触发响应,但对象的引用上没有,给引用赋值新的引用虽然数值变了,但钩子在旧的对象上,和新的没关系,所以不能触发响应。只有改旧的对象或者他的子对象,才能触发响应事件。可以使用.array
、.map
、.splice
或者使用Vue全局响应的工具。
btw, Vue的$set
在Vue3里已经废弃了,不能用了
0x02 插值表达式{{}}中绑定响应式对象的子元素,不会触发响应※
太怪了,搞一晚上
在Vue中,当你使用双大括号插值(Mustache 语法){{ user }}
时,它会自动调用 user.toString()
方法,这会导致 user.id
和 user.username
的值被提取并显示。当 user
对象发生变化时,Vue 会检测到 user
对象的引用发生了变化,因此会重新渲染 {{ user }}
的内容。
但是,user.id
和 user.username
是直接引用 user
对象的属性,并不会触发 Vue 的响应式系统。因此,即使 user
对象本身发生了变化,user.id
和 user.username
的值也不会自动更新。
如果你希望 user.id
和 user.username
在 user
对象发生变化时也能够自动更新,你可以使用 Vue 的计算属性或者监听 user
对象的变化来手动更新这些值。例如:
<template>
<!-- 调试点--> {{user}} <!-- 这里在user刷新之后马上会刷新 -->
<div class="userCat">
<div class="userDetails">
<h2> {{user.username}} </h2> <!-- 这里当user刷新后根本不会变-->
<h2>用户名: {{ username }}</h2> <!-- 在这里引入个新变量,在computed里更新,因为响应式更新会触发computed -->
<slot />
</div>
</div>
</template>
<script>
// 因为传参太麻烦,我把数据放到data.js里了,data.js放下面
import Data from '@/datas/data.js';
export default {
data() {
return {
user: Data.user // 绑定user
};
},
computed: {
username() {return this.user.username;},
}
}
</script>
// data.js
const Data = new reactive({
isUser,
isBook,
books: [],
users:[],
book,
user:{}
});
export default Data;
<img src="https://pic.aketer.me//i/0ee05a2b-c1b3-403f-99ff-72461a072f9c.jpg" alt="image">
ok了