背景:
- 项目为常见的管理后台系统,封装了一个列表组件
- 列表组件内定义了
searchData
方法用于调取获取列表数据的接口 - 代码逻辑如下:
--- 父组件 ---
data () {
type: 0, // 0、1、2 三个值
searchParams: { // 对象类型
p1: ''
},
b: '' // 字符串类型
},
watch () {
type (val) {
let oldP1 = this.searchParams.p1
this.searchParams = {
p1: oldP1
}
if (/* 某种判断 */) {
this.b = ''
}
},
b (val) {
this.searchParams.p1 = val
console.log(JSON.stringify(this.searchParams)) // => { p1: '' }
this.$refs.child.searchData()
}
},
methods () {
changeType (val) {
/*val 可能的值有3个,0、1、2*/
this.type = val
},
changeB (val) {
this.b = val
}
},
--- 列表子组件 ---
props: {
url: String,
searchParams: {
type: Object,
default () {
return {}
}
}
},
methods: {
searchData () {
const params = this.searchParams
console.log(JSON.stringify(params)) // => { p1: '上一次的p1值' }
this.$ajax.post(this.url, params).then(...)
}
}
问题:
父组件调用 changeType 方法 且 满足某种判断 下,希望得到的是
- 触发子组件的 searchData 方法,并且
searchParams
的p1
值为 ‘’ - 但实际情况下,调取接口时
searchParams
的p1
值为 上一次保留的p1
值 - 且父、子组件打印的
searchParams
不相同
父组件直接调用 changeB 方法 时,searchParams
为 ‘’,且两次打印的值相同
分析:
- 两次都改变了searchParams 的属性值,
- 但是通过 changeType 改变时,searchParams 改变了引用地址
- 而通过 changeB 改变时,仅改变了属性值
- 打印时,父组件内一切正常
- 推测:子组件监听父组件的状态变化是异步的,这意味着当 searchParams 改变引用地址时,上述代码先执行了
this.$refs.child.searchData()
,子组件后监听到父组件searchParams
的改变