为什么 vue 组件属性需要以冒号为前缀?
因此,在 Vue 组件中,当您在模板中编写标签时,您可以像在普通 XML 中一样指定静态参数,或者可以通过在参数名称前面添加冒号来指定响应式参数。
现在,我偶然发现了 这个 Vuetify 示例,并且我玩了v-menu
组件。例如,该组件具有 close-on-click
属性,在本例中,该属性被标记为响应式。这是合乎逻辑的,因为在本例中,当您更改开关的位置时,该属性也会更新。
但是,您也可以指定一个常量。而且,由于常量值不会改变,因此在 Vue 中,它们不必是响应式的。但是,在这里,如果我指定 close-on-click
(不带冒号),它将无法正常工作。除非它是反应性的,否则它不会读取此属性。
我的问题是,为什么即使我们指定一个常量作为它的值,这个属性也需要被标记为反应性的?
所以,更准确地说:为什么
false
是一个常量,因此,不应将该属性标记为响应式。
So, in Vue components, when you are writing tags in a template, you can specify a static parameter, like in a normal XML, or, you can specify a reactive parameter by adding colon in front of the parameter name.
Now, I stumbled upon this Vuetify example, and I played with the v-menu
component. This component has, for example, a close-on-click
property, which, in this example, is marked as reactive. That is logical, because in this example, this property is updated when you change the switch's position.
However, you can also specify a constant. And, since constant values do not change, in Vue, they do not have to be reactive. But, here, if I specify close-on-click
(without colon), it will not work properly. It will not read this property unless it is reactive.
My question is, why this property needs to be marked as reactive even if we specify a constant as its value?
So, to be more exact: Why <v-menu close-on-click=false
does not work, but <v-menu :close-on-click="false"
does?
false
is a constant, so, this property should not be marked as reactive.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
tldr:
反应性使用绑定来更新模板,但并非所有绑定都必须是反应性的。这个答案试图澄清这两个相关但独立的概念之间的区别。
简短回答:
它不需要是“反应性” >。它需要“绑定”(评估为 JavaScript 表达式)。使用...
...将字符串
“false”
绑定到属性close-on-click
。由于该属性需要布尔值,因此"false"
计算结果为true
,因为除空字符串 (""
) 之外的任何字符串都计算结果为true
当转换为boolean
时。并且...绑定 JavaScript 表达式
false
的结果,显然其计算结果为false
。这与反应性无关。它与评估作为字符串(不带
:
)或 JavaScript 表达式(带:
)传递给属性的值有关。长/正确答案:
您正在混淆两个相似但独立的概念。
其中之一是"反应性",另一个是通过使用"动态绑定" JavaScript 表达式。
属性前面的冒号 (
:
) 用于动态绑定,而不是用于反应性。:
是v-bind:
的简写。将绑定视为
{{ }}
(mustache) 模板绑定的替代方案,但专为元素属性和道具而设计(因为 Mustache 在属性中不起作用)。正如 Mustache 语法一样,v-bind:
可用于将反应式和非反应式表达式绑定到模板。当表达式的结果更改时,非反应式表达式不会更新模板。
反应性,在 Vue 中,是一个术语,用于表示 Vue 检测数据结构变化并在检测到变化时使用这些数据结构更新表达式的“神奇”能力。
响应式对象的一些示例:
Vue.observable()
中的data()
函数返回的对象@vue/composition-api
插件,ref()
和reactive()
函数的结果。pinia
和vuex
、$router
/$route
等中存储状态...)但是,在幕后,所有反应式对象都是上述情况之一的实现。实际上,反应性是一个包装器。在 Vue2 中,如果你检查一个反应式对象,你会注意到它有一个
[__ob__: Observer]
属性。那是反应观察者。在 Vue3 中,它不再是一个观察者,而是一个 Proxy< /a>.
主要区别在于,在 Vue3 中,原始对象(代理的目标)实际上未受影响。此外,使用代理进行变更检测更加直接。
如果有兴趣,网上有很多材料,通常标记为“高级 vue 反应性”或“vue 深度反应性”。
为了更清楚地理解,这里有一个绑定两个表达式的示例:一个是静态的,一个是反应性的。显然,只有响应式模板在结果发生变化时才会更新:
注意:即使我在上面的示例中使用了
{{}}
(mustache 语法),当您使用v-bind:
时也会发生同样的情况> 或其较短版本:
在元素属性中。我希望这能够澄清“反应性”和“绑定”之间的区别。
tldr:
Reactivity uses bindings to update the template, but not all bindings are necessarily reactive. This answer attempts to clarify the difference between these two related, but separate, concepts.
short answer:
It doesn't need to be "reactive". It needs to be "bound" (evaluated as JavaScript expression). Using...
...binds the string
"false"
to the propertyclose-on-click
. Since the property expects a boolean,"false"
evaluates totrue
, because any string other than empty string (""
) evaluates totrue
when cast toboolean
. And...binds the result of the JavaScript expression
false
, which evaluates tofalse
, obviously.This has nothing to do with reactivity. It has to do with evaluating the value passed to the attribute as string (without
:
) or as a JavaScript expression (with:
).long/proper answer:
You are mixing up two similar, but separate concepts.
One of them is "reactivity" and the other is "dynamically binding" through the use of a JavaScript expression.
The colon (
:
) in front of an attribute is used for dynamically binding, not for reactivity.:
is a shorthand forv-bind:
.Think of binding as an alternative for
{{ }}
(mustache) template binding, but designed for element attributes and props (because mustache doesn't work in attributes). Just as the mustache syntax,v-bind:
can be used to bind both reactive and non-reactive expressions to the template.Non-reactive expressions will not update the template when the expression's result changes.
Reactivity, in Vue, is a term used to denominate Vue's "magical" ability to detect changes in data structures and update expressions using those data structures when a change has been detected.
A few examples of reactive objects:
data()
function in Options APIVue.observable()
, in Vue 2.x@vue/composition-api
plugin in Vue 2), the result ofref()
andreactive()
functions.pinia
andvuex
,$router
/$route
, etc...) but, under the hood, all reactive objects are an implementation of one of the cases above.Effectively, reactivity is a wrapper. In Vue2, if you inspect a reactive object you will notice a
[__ob__: Observer]
property on it. That's the reactivity observer.In Vue3, it's no longer an Observer, but a Proxy.
The main difference is that in Vue3 the original object (the proxy's target) is virtually untouched. Also, change detection is more straightforward with Proxies.
If interested, there are a lot of materials online, typically labeled "advanced vue reactivity" or "vue reactivity in depth".
For a clearer understanding, here's an example which binds two expressions: one static and one reactive. Obviously, only the reactive one updates the template when its result changes:
Note: Even though I used
{{}}
(mustache syntax) in the above example, the same thing happens when you usev-bind:
or its shorter version:
in element attributes.I hope this clarifies the difference between "reactivity" and "binding".