vue.js - 如果 prop 在模板中直接分配给对象,则 Vue prop watcher 会意外触发
问题描述
这是代码:
<template>
<div>
<foo :setting="{ value: 'hello' }" />
<button @click="() => (clicked++)">{{ clicked }}</button>
</div>
</template>
<script>
import Vue from 'vue'
// dummy component with dummy prop
Vue.component('foo', {
props: {
setting: {
type: Object,
default: () => ({}),
},
},
watch: {
setting() {
console.log('watch:setting')
},
},
render(createElement) {
return createElement(
'div',
['Nothing']
)
},
})
export default {
data() {
return {
clicked: 0,
}
},
}
</script>
我还做了一个codepen:https ://codepen.io/clinicion-lin/pen/LYNJwJP
问题是:每次单击按钮时,setting
foo 组件中的 prop 观察器都会触发,我猜原因是:settings
在重新渲染期间重新评估了其中的内容,但我不确定。
这种行为本身不会造成任何问题,但如果没有给予足够的关注,它可能会导致不需要的更新甚至错误(实际上我只是做了一个,这就是我来问的原因:D)。使用 可以轻松解决该问题:setting="settingValue"
,但我想知道是否有替代解决方案或最佳实践。我看到有些代码也是直接在模板中赋值对象,感觉自然方便。
感谢任何可以提供解释或提示的人。
解决方案
首先,文档:“每次父组件更新时,子组件中的所有道具都将刷新为最新值”
通过v-bind:propA="XX"
在模板中使用,你是在告诉 Vue “XX 是 JavaScript 表达式,我想用它作为 propA 的值”
所以如果你使用{ value: 'hello' }
表达式,字面意思是“创建新对象”表达式,真的是令人惊讶的新对象吗?每次重新渲染父级时创建(并在您的情况下执行观察者)?
为了更好地理解 Vue,记住模板中的所有内容总是编译成纯 JavaScript 并使用该工具作为vue-compiler-online来查看 Vue 编译器的输出确实很有帮助。
例如这样的模板:
<foo :settings="{ value: 'hello' }" />
编译成这样:
function render() {
with(this) {
return _c('foo', {
attrs: {
"settings": {
value: 'hello'
}
}
})
}
}
像这样的模板:
<foo :settings="dataMemberOrComputed" />
编译成这样:
function render() {
with(this) {
return _c('foo', {
attrs: {
"settings": dataMemberOrComputed
}
})
}
}
突然很清楚,在第一个示例中每次都会创建新对象,并且在第二个示例中使用对对象的相同引用(相同或不同......取决于逻辑)。
我看到有些代码也是直接在模板中赋值对象,感觉自然方便。
我仍然是 Vue 新手,但我不时浏览像 Vuetify 这样的“大”库的源代码来学习新东西,我不认为将“新对象”表达式传递给 prop 是常见的模式(这会有什么用?)。
很常见的是<foo v-bind="{ propA: propAvalue, propB: propBValue }">
-传递对象的属性,这是一个非常不同的事情......
推荐阅读
- c++ - 如何将节点保存到数组中
- google-sheets - 接收“SUMIFS 的数组参数大小不同。” 谷歌表格中的错误
- javascript - 访问有序的类属性
- python - 在自定义环境中运行的 Tensorflow C51 示例代码会出现形状错误
- ios - CI - Xcode 12 服务器在集成后不发送电子邮件
- python - python中的portscanner问题
- html - 可以使用元标记(http-equiv)设置 COOP/COEP 标头吗?
- swift - 泛型方法的类型不匹配问题
- asp.net - 使用 React 和 ASP 下载文件
- haskell - 在 Haskell 中手动实现整数除法