- 组件实例的自定义属性的安全命名是什么?
- 存储特定于组件但非反应性数据的推荐方法是什么?
一些推理:
在使用 Vue.js 时,有时会遇到我需要在组件实例中存储一些静态数据的情况。据我了解 Vue,组件实例可以被视为具有一些特殊属性(this.$data、.$el、.$parent 等)的普通对象。这告诉我,我可以对对象做任何我想做的事情,只是要注意不要与内部使用的属性名称发生冲突。
一个常见的例子是 Web 组件元素,它包含一些其他逻辑甚至影子 DOM(例如 WebGl 的 Canvas),并且引用绑定到 Vue 组件,这意味着有一些初始化逻辑和处置逻辑绑定到组件的生命周期。此处的引用可以是代理对象,不一定是 DOM 元素本身。我通常将其作为带有"_"前缀的直接属性存储在组件中:
<template>
<my-custom-canvas @ready="canvasReady">
</template>
<script>
export default {
methods: {
canvasReady (canvas) { this._my_custom_canvas = canvas; }
}
}
</script>
所以AD 1.像这样污染组件实例是否"正常"和"安全"?或者我应该把它放到this.$data
中,让它成为反应性数据?最终,我找不到任何关于如何在 Vue 中使用非反应式数据的好指南。在某些情况下,感觉它应该包含在组件本身中,而不是全局空间之外的某个地方。另外,这是完全错误的还是没有约定的边缘情况?谁能给我一些论据,为什么我应该避免自定义非反应性属性?
我不一定会称它为重复项,但您可能会发现这个问题的答案是相关的:
如何在 Vue 2 中设置组件非反应式数据?
这个话题也被 Vue 核心团队讨论过:
https://github.com/vuejs/vue/issues/1988
简短的回答是,将非反应性数据直接添加到this
并没有错。
Vue 使用_
和$
前缀作为它自己的内部属性(见这里 https://v2.vuejs.org/v2/api/#data),所以你可能会发现避免这些前缀实际上更安全。从名称冲突的角度来看,这与命名道具、数据属性等没有什么不同,因为它们也通过this
的属性暴露。mixins等的私人属性有自己的约定,在 https://v2.vuejs.org/v2/style-guide/#Private-property-names-essential 中概述。如果没有别的,我建议阅读详细说明部分,因为它进一步讨论了 Vue 自己的命名约定。
有点相关的说明是,如果你使用Object.freeze
冻结一个对象,那么 Vue 不会尝试让它成为反应式的。这与对象是HTML元素的情况并不真正相关,但是如果您只是想使大型静态数据远离反应系统,那么这可能是一种更简单的方法。
当我需要存储非反应式数据(例如 consts 或枚举)时,我只需将其放入数据函数之外的数据对象中,并放入创建的生命周期方法中。
当您在数据函数之外的数据上定义变量时,它们不会是被动的。
例如,这会将其初始化为 null 值,并在需要时使其在模板中可用,但如果它发生更改,它不会启动刷新。
<template>
<my-custom-canvas @ready="canvasReady">
</template>
<script>
export default {
methods: {
canvasReady (canvas) { this.data.myCanvas = canvas; }
},
created() {
this.data.myCanvas = null;
}
}
</script>
但是,如果您不打算在模板中使用它,则可以将其放在组件外部。
<template>
<my-custom-canvas @ready="canvasReady">
</template>
<script>
const myCanvas = null;
export default {
methods: {
canvasReady (canvas) { myCanvas = canvas; }
},
}
</script>