前言:
本人前端菜鸟,看过去的"史山"代码,发现的响应式问题,虽然明确知道如何避免这个bug,但是还是对产生这样bug的具体原因非常感兴趣,我现在也是一知半解,这次发帖解答的同时也是寻求帮助,希望有大佬能从响应式的角度讲解一下
正文:
造成bug的demo非常简单,需要vue2 + ant-design-vue即可
js
<template>
<div id="app">
username:<a-input v-model="formData.username" /><br/>
one:<a-input v-model="formData.one" /><br/>
two:<a-input v-model="formData.two" /><br/>
addOne:<a-input v-model="formData.addOne" /><br/>
addTwo:<a-input v-model="formData.addTwo" /><br/>
</div>
<template>
<script>
const InitData = {
username: "zsh",
one: "one",
two: "two",
deep: {
addOne: "addOne",
addTwo: "addTwo"
}
}
export default {
name: 'App',
components: {
},
data () {
return {
formData: {
username: '',
one: "",
two: "",
addOne: "",
addTwo: "",
}
}
},
mounted() {
this.Init()
},
methods: {
Init() {
this.formData = InitData
this.formData.addOne = InitData.deep.addOne
this.formData.addTwo = InitData.deep.addTwo
},
},
}
</script>
bug现象
当修改addOne的input内容,失焦后显示的数据就会恢复原样,之后如果修改one或two这些初次赋值对象最外层有的属性时,就会把之前修改的内容显示出来
我的主观分析
这里先允许我做个说明,以下只是我的主观分析,并不一定正确,也希望有大佬能够指正和讲解。
首先,Init函数的赋值,只是让username、one、two、deep建立了响应式,addOne和addTwo是没有被重写set与get的方法的。
我们知道v-model是value属性和input事件的语法糖,addOne输入框的数值发生改变,触发input事件,也修改了formData中的addOne属性,但是因为此属性没有响应式(在input事件赋值触发其set函数中,没有改变副作用函数来改变模版用到的值),不能让传递到input内部的属性改变,所以失焦后会恢复原样,但为什么是失焦触发就不太明白了
在修改已经建立响应式的属性时,触发响应式时,之前已经修改的属性addOne也会连带着触发模版数据修改。(这里也是我也太确定,希望有大佬能够指点)
最后
这次学习整理了日常碰到的小bug,其实在初次赋值就不应该整体赋值,而是结偶出对应属性在依次赋值就可以避免。但是这对背后的响应式原因也是让我学习不少,最后也希望大佬对我的解答做出指正和更细致的分析,谢谢大家了