#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>
- Если вы определяете переменную вне
export
оператора, это просто обычная переменная javascript, которую вы можете использовать в любом месте внутри тега сценария. Он не привязан к компоненту и никоим образом не связан с Vue.
Плюсы:- Ваша переменная существует во всей
<script>
области действия элемента. - Вы можете использовать его внутри внутренних функций, к которым нет привязки
this
.
- Ваша переменная существует во всей
- Если вы определяете переменную внутри функции данных или, точнее говоря, определяете свойство для объекта данных экземпляра компонента, то она привязана к компоненту и, следовательно, доступна внутри
<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
});
},