[英]Best practice to to set non-reactive const variables in Vue?
The situation情况
In my Vue app, I have a Vue component which mounts an svg, which I have defined with a few props.在我的 Vue 应用程序中,我有一个 Vue 组件,它安装了一个 svg,我用一些道具定义了它。 These are a combination of reactive and non-reactive data.
这些是反应性和非反应性数据的组合。 The reactive data that we need is
percData
, which therefore sits in the data(){}
object. We also have colours
, width
, height
, and scale
, which are not reactive and never will be.我们需要的反应性数据是
percData
,因此它位于data(){}
object 中。我们还有colours
、 width
、 height
和scale
,它们不是反应性的,也永远不会是。 I don't call these in the <template>
block, and I don't plan for them to change.我不在
<template>
块中调用它们,也不打算更改它们。 These are currently declared with const
, and are not within the export defautl{}
block scope.这些当前使用
const
声明,并且不在export defautl{}
块 scope 内。
The question(s)问题
<script>
tag in Vue in a multi-component app?<script>
标签工作? Is each script/component a separate scope from the global one? My possible understanding我可能的理解
As per this thread and this thread , I think the best place for my const would be in a separate file, from which I would then import them in my mySvgComponent
component.根据这个线程和这个线程,我认为我的 const 最好放在一个单独的文件中,然后我将从该文件中将它们导入我的
mySvgComponent
组件中。 Is this the correct approach?这是正确的方法吗?
My code我的代码
<template>
<div></div>
</template>
<script>
import { mySvgComponent} from '../mySvgComponent'
import { select } from 'd3'
const [colour1, colour2, colour3, colour4] = ['#000000', '#111111', '#222222', '#3333'];
const width = 135
const height = 135
const scale = .75
export default {
name:'mySvgComponent',
data(){
return{
percData: null
}
},
props: {
summary: Object
},
methods: {
percSetup(summary) {
return this.percData = [
{ colour: colour1, perc: +summary.colour1Percentage.toFixed(2)},
{ colour: colour2, perc: +summary.colour2Percentage.toFixed(2)},
{ colour: colour3, perc: +summary.colour3Percentage.toFixed(2)},
{ colour: colour4, perc: +summary.colour4Percentage.toFixed(2)}
]
}
},
async mounted() {
this.percSetup(this.$props.summary)
const svg =
select('div')
.append('svg')
.call(mySvgComponent(this.percData)
.width(width)
.height(height)
.scale(scale))
}
}
</script>
<style></style>
Related threads and why I don't think they answer my question:相关主题以及为什么我不认为他们回答了我的问题:
<template>
tag, and I don't need it to be responsive.<template>
标签中调用我的 const 变量,我不需要它来响应。method()
to return my const variables?method()
来返回我的 const 变量? In Vue.js, you can set non-reactive (ie, constant) variables by declaring them in the data object as a function that returns an object, rather than declaring them directly as properties of the data object. This ensures that the variables are only set once during the initialisation of the component and cannot be modified later.在 Vue.js 中,您可以通过在数据 object 中将它们声明为返回 object 的 function 来设置非反应性(即常量)变量,而不是直接将它们声明为数据 object 的属性。这确保变量仅被设置在组件初始化期间一次,以后不能修改。 Here's an example:
这是一个例子:
data: function () {
return {
nonReactiveConst: 'This is a non-reactive const variable'
}
}
Another way to create a non-reactive variable in Vue is to use the Vue.observable() function to create an observable object, and then assign the non-reactive variable as a property of that object.在 Vue 中创建非反应变量的另一种方法是使用 Vue.observable() function 创建一个可观察对象 object,然后将非反应变量分配为该 object 的属性。
const state = Vue.observable({
nonReactiveConst: 'This is a non-reactive const variable'
});
You can then access the non-reactive variable inside the component's template using state.nonReactiveConst.然后,您可以使用 state.nonReactiveConst 访问组件模板内的非反应变量。
It's important to note that using this method, you can still mutate properties of the object, but you can't reassign the whole object.重要的是要注意,使用此方法,您仍然可以改变 object 的属性,但不能重新分配整个 object。
Vue SFC is syntax sugar, it's necessary to understand what code it's compiled to in order to use it effectively. Vue SFC 是语法糖,理解它编译成什么样的代码才能有效地使用它。
The result of SFC script
syntax is ES module with roughly the same content as the body of <script>
block, with name
and render
options being added by the compiler. SFC
script
语法的结果是 ES 模块,其内容与<script>
块的主体大致相同, name
和render
选项由编译器添加。 Then general modular JavaScript practices are applicable.那么一般模块化JavaScript的做法都是适用的。 The constants can remain in current module if they don't take much lines and aren't reused in other modules, and can be moved to a separate module otherwise.
如果常量不占用太多行并且不在其他模块中重用,则常量可以保留在当前模块中,否则可以移动到单独的模块中。 In case the constants are supposed to be used in a template, they can be returned from
data
or setup
function.如果常量应该在模板中使用,它们可以从
data
或setup
function 中返回。
The result of SFC script setup
syntax is ES module with the whole block being moved to generated setup
function, with the exception of imports. SFC
script setup
语法的结果是 ES 模块,整个块被移动到生成的setup
function,导入除外。 In this case it's inefficient to declare constants in this block because they will be created on each component instantiation, this may be a reason to move them to a separate module, although this can be considered preliminary optimization.在这种情况下,在此块中声明常量是低效的,因为它们将在每个组件实例化时创建,这可能是将它们移动到单独模块的原因,尽管这可以被视为初步优化。
Considering the above, the scope of Vue SFC modules works exactly like it's expected from ESM because this is what they are compiled to.考虑到上述情况,Vue SFC 模块 scope 的工作方式与 ESM 的预期完全一样,因为这是它们被编译的结果。
Vue composition API provides markRaw
function to additionally prevent constant objects from being made reactive when they are used inside reactive ones like data
, in case this is unwanted. Vue composition API 提供
markRaw
function 以额外防止常量对象在反应性对象(如data
)中使用时变得反应性,以防这是不需要的。 The same is done for options API with Object.freeze
in linked question .链接问题中的选项 API 和
Object.freeze
也是如此。
TL;DR: the code in the question is ok, it's correct to use the constants like that in this case. TL;DR:问题中的代码没问题,在这种情况下使用这样的常量是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.