简体   繁体   English

在 Vue 中设置非反应性 const 变量的最佳实践?

[英]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 中。我们还有colourswidthheightscale ,它们不是反应性的,也永远不会是。 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)问题

  • Where is the best place to be for these const declarations?这些 const 声明的最佳位置在哪里?
  • What scope are these const-declared variables currently in? scope 这些const 声明的变量当前在什么地方?
  • More generally, how does scope work for the <script> tag in Vue in a multi-component app?更一般地说,scope 如何在多组件应用程序中为 Vue 中的<script>标签工作? Is each script/component a separate scope from the global one?每个脚本/组件是否与全局脚本/组件分开 scope? And where is the global scope?全局 scope 在哪里?

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:相关主题以及为什么我不认为他们回答了我的问题:

  1. How to set a component non-reactive data in Vue 2? 如何在 Vue 2 中设置组件非反应性数据? , How to make a template variable non-reactive in Vue , How could I use const in vue template? , 如何在 Vue 中使模板变量成为非反应式, 如何在 Vue 模板中使用 const? . . I don't call my const variables in my <template> tag, and I don't need it to be responsive.我不在我的<template>标签中调用我的 const 变量,我不需要它来响应。
  2. What is the best way to create a constant, that can be accessible from entire application in VueJs? 创建一个可以从 VueJs 中的整个应用程序访问的常量的最佳方法是什么? . . Maybe I don't understand this fully.也许我不完全理解这一点。 Why would I need to run a 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>块的主体大致相同, namerender选项由编译器添加。 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.如果常量应该在模板中使用,它们可以从datasetup 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM