Vue中声明变量有什么区别?

What is the difference between declaring variables in Vue?

您能解释一下以不同方式声明变量的区别吗?我什么时候应该使用这些声明方式?

<script>
const someVariable = 12345

export default {
  name: 'App',
}
</script>
<script>

export default {
  name: 'App',
  data() {
    return {
      someVariable: 12345
    }
  }
}
</script>

在第一个中,您不能在模板中使用 someVariable

<script>
const someVariable = 12345

export default {
  name: 'App',
}
</script>
<template> <p> {{someVariable}} </p> </template> //doesn't work

在 Vue3 中可用:

要让它工作,您可以在脚本中添加一个 setup 关键字,但是如果您想让它 对变化有反应 More info

<script setup>
const someVariable = 12345

export default {
  name: 'App',
}
</script>
<template> <p> {{someVariable}} </p> </template> //works (you can see the data)

一个典型的单文件组件是这样的:

<template>
...
</template>

<script>
...
</script>
  1. 如果您在 export 语句之外定义一个变量,它只是一个普通的 javascript 变量,您可以在脚本标签内的任何地方使用。它不绑定到组件,也不以任何方式与 Vue 相关。 优点:
    • 您的变量存在于整个 <script> 元素的范围内。
    • 您可以在没有绑定到 this 的内部函数中使用它。
  2. 如果你在数据函数中定义一个变量,或者更准确地说,为组件实例的数据对象定义一个属性,然后它被绑定到组件,因此在[=16]中可用=] 标签。 优点:
    • 变量可以参考<template>
    • 您可以利用 Vue 的反应性。您可以在此变量上定义计算属性。当您在模板中使用它时,html 会更新以反映此变量中的任何更改。
    • 您可以将其作为 props 传递给子组件。
    • 您可以使用 Vue devtools 轻松调试,您可以观察变量的变化。您还可以像 $vm.data.someVarData 一样将变量登录到控制台,即将变量添加到 Vue 组件的实例中。
<template>
    <div>
        <div :class="someVarData"/> <!-- This is Ok -->
        <div :class="someVar"/> <!-- This is not Ok -->
    </div>
<template>
<script>
const someVar = "blah";
export default {
    data() {
        return {
            someVarData: "blahData",
        };
    },
    mounted() {
        const el = document.getElementById('myId');
        el.addEventListener('mouseenter', function () {
            console.log(someVar); // This is Ok
            console.log(this.someVarData); // This is not Ok
        });
    },
    beforeRouteEnter() { // <--- Vue-router's Navigation guard
        console.log(someVar); // This is Ok
        console.log(this.someVarData); // This is not Ok
    },
</script>

因此,您应该避免在 export 之外定义变量,因为它们会使您更难理解您的代码流。几乎总有 一些 方法可以重新设计您的方法,以便不在导出之外使用变量。

例如在上面的示例中,您仍然可以在 mounted 挂钩和导航守卫中使用数据变量,但需要进行一些更改:

    mounted() {
        const el = document.getElementById('myId');
        el.addEventListener('mouseenter', () => {
            console.log(someVar); // This is Ok
            console.log(this.someVarData); // Ok - works because we change the function to arrow function, so it is bound to the instance's `this`
        });
        el.addEventListener('mouseenter', function () {
            console.log(someVar); // This is Ok
            console.log(this.someVarData); // Ok - works because we have manually bound the function to the instance's `this`
        }.bind(this));
    },
    beforeRouteEnter(to, from, next) { // <--- Vue-router's Navigation guard
        console.log(someVar); // This is Ok
        console.log(this.someVarData); // This is not Ok
        next((vm) => {
            console.log(vm.someVarData); // Ok - Navigation guard's next function provides the instance's context as a callback parameter
        });
    },