В чем разница между объявлением переменных в Vue?

#javascript #vue.js #vuejs2

Вопрос:

Не могли бы вы объяснить разницу между объявлением переменных по-разному. Когда я должен использовать эти способы декларирования?

 <script>
const someVariable = 12345

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

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

Комментарии:

1. Первый из них недоступен в шаблоне и не реагирует (т. е. ничего не обновляется автоматически при его изменении).

Ответ №1:

В первом случае вы не можете использовать someVariable в своем шаблоне

 <script>
const someVariable = 12345

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

Доступно в Vue3:

чтобы это сработало, вы можете добавить setup ключевое слово в свой скрипт, но вам нужно обернуть значение переменной ref(...) или reactive(...) , если вы хотите, чтобы оно реагировало на изменения, Дополнительная информация

 <script setup>
const someVariable = 12345

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

Ответ №2:

Типичный компонент с одним файлом будет выглядеть так:

 <template>
...
</template>

<script>
...
</script>
 
  1. Если вы определяете переменную вне export оператора, это просто обычная переменная javascript, которую вы можете использовать в любом месте внутри тега сценария. Он не привязан к компоненту и никоим образом не связан с Vue.
    Плюсы:

    • Ваша переменная существует во всей <script> области действия элемента.
    • Вы можете использовать его внутри внутренних функций, к которым нет привязки this .
  2. Если вы определяете переменную внутри функции данных или, точнее говоря, определяете свойство для объекта данных экземпляра компонента, то она привязана к компоненту и, следовательно, доступна внутри <template> тегов. Плюсы:
    • На переменную можно ссылаться из <template>
    • Вы можете воспользоваться реактивностью Vue. Вы можете определить вычисляемые свойства для этой переменной. Когда вы используете его в шаблоне, html обновляется, чтобы отразить любые изменения в этой переменной.
    • Вы можете передать его в качестве реквизита дочерним компонентам.
    • Вы можете легко отлаживать вещи с помощью 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>
 

Таким образом, вам следует избегать определения переменных вне экспорта, поскольку они затрудняют понимание потока вашего кода. Почти всегда есть какой-то способ изменить свой подход, чтобы не использовать переменные вне экспорта.

Например, в приведенном выше примере вы все еще можете использовать переменную данных внутри 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
        });
    },