#vue.js #vue-router #vue-composition-api
#vue.js #vue-маршрутизатор #vue-composition-api
Вопрос:
У меня есть компонент Vue, который раньше работал с наблюдателем $route
.
Поскольку я сделал некоторые обновления, он больше не работает, и я получаю сообщение :
[Предупреждение Vue]: Недопустимый источник просмотра: «$ route». Источником просмотра может быть только функция получения / эффекта, ссылка, реактивный объект или массив этих типов.
Вот мой package.json
:
{
"name": "prix-de-gros.vue",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@vue/composition-api": "0.6.6",
"axios": "^0.19.2",
"chart.js": "^2.9.3",
"core-js": "^3.6.5",
"moment": "^2.27.0",
"regenerator-runtime": "^0.13.7",
"remove": "^0.1.5",
"slugify": "^1.4.5",
"tiptap-vuetify": "^2.24.0",
"vue": "^2.6.12",
"vue-i18n": "^8.21.0",
"vue-router": "^3.4.3",
"vuetify": "^2.3.9",
"vuex": "^3.5.1",
"webpack": "^4.44.1"
},
"devDependencies": {
"@mdi/js": "^5.5.55",
"@vue/cli-plugin-babel": "^4.5.4",
"@vue/cli-plugin-eslint": "^4.5.4",
"@vue/cli-plugin-router": "^4.5.4",
"@vue/cli-plugin-vuex": "^4.5.4",
"@vue/cli-service": "^4.5.4",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^7.7.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-vue": "^6.2.2",
"moment-locales-webpack-plugin": "^1.2.0",
"prettier": "^2.1.0",
"sass": "^1.26.10",
"sass-loader": "^9.0.3",
"vue-cli-plugin-vuetify": "^2.0.7",
"vue-template-compiler": "^2.6.12",
"vuetify-loader": "^1.6.0"
},
"resolutions": {
"prosemirror-model": "^1.11.0",
"prosemirror-tables": "^0.9.0"
}
}
и мой компонент Vue (Vue 2 с @vue/composition-api
):
<template>
<div class="container">
<v-card>
<v-toolbar dark color="primary" dense class="mb-2">
<v-btn text @click="goToRoute({ name: 'account' })">{{ $tc("Account", 2) }}</v-btn>
{{formatInt( data.id) }} - {{ data.label }}
<v-spacer></v-spacer>
<v-btn
v-if="data.editable"
:aria-label="$tc('Update')"
icon
@click="
goToRoute({
name: 'account-update',
params: { id: data.id }
})
"
>
<v-icon aria-hidden="true">{{ mdiPencil }}</v-icon>
</v-btn>
</v-toolbar>
<v-card-text>
<v-row dense>
<v-col cols="12" sm="3" class="label-col">{{ $tc("Account") }}</v-col>
<v-col>{{ formatInt(data.id) }}</v-col>
</v-row>
<v-row dense>
<v-col cols="12" sm="3" class="label-col">{{ $tc("Label") }}</v-col>
<v-col>{{ data.label }}</v-col>
</v-row>
<v-row dense class="my-4">
<v-col cols="12" sm="3" class="label-col">{{ $tc("Status") }}</v-col>
<v-col>{{ data.status ? $tc("On") : $tc("Off") }}</v-col>
</v-row>
<v-row v-if="data.info" dense>
<v-col cols="12" sm="3" class="label-col">{{ $tc("Info") }}</v-col>
<v-col v-html="nl2br(data.info)"></v-col>
</v-row>
</v-card-text>
</v-card>
</div>
</template>
<script>
import axios from "axios";
import { mdiPencil } from "@mdi/js";
import { formatInt, nl2br } from "@/plugins/ob-helper";
import { ref, watch } from "@vue/composition-api";
export default {
name: "AccountView",
setup(props, { root: { $i18n, $router, $i18nRoute, $route } }) {
const data = ref({});
function dataGet() {
axios
.get("/backend/accounts/" $route.params.id)
.then(r => {
if (r.data) {
data.value = r.data.data;
document.title = $i18n.tc("Account", 2) " : " data.value.id;
}
})
.catch(error => {
if (error.response.status !== 400 amp;amp; error.response.status !== 401) {
alert(error.response.statusText);
}
});
}
function goToRoute(o) {
$router.push($i18nRoute(o));
}
watch("$route", () => dataGet());
return {
data,
formatInt,
goToRoute,
mdiPencil,
nl2br
};
}
};
</script>
Комментарии:
1.
watch
Функция не принимает строку в качестве первого аргумента. Изменитеwatch("$route", ...)
с помощью функции, которая возвращает объект маршрута, подобныйwatch(() => $route, ...)
.2. Я попробовал watch(() => $route, …), я не получаю сообщение об ошибке, но ничего не происходит, например, если watch не обнаруживает изменение параметров.
3. Это будет просто наблюдать за
$route
объектом, а не за каким-либо из дочерних элементов. Вы можете перейти{ deep: true }
к таким параметрам, какwatch(() => $route, ..., { deep: true })
или просто наблюдать только за объектом parameters,watch(() => $route.params, ...)
4. Я пробовал их, и раньше это работало, но больше не работает, похоже, что watch не обнаруживает изменения $ route
Ответ №1:
Реактивность $route
теряется, когда объект реактивного контекста разрушается (как описано в @vue/composition-api
выпуске # 264). watch
Метод должен сохранять ссылку на реактивный объект для поддержания его реактивности:
export default {
// DON'T DO THIS
// setup(props, { root: { $route } }) { // reactivity lost!
// DON'T DO THIS
// setup(props, context) {
// const { root: { $route } } = context // reactivity lost!
// }
setup(props, context) {
// reactive!
watch(() => context.root.$route, () => dataGet())
}
}
Проверено с @vue/composition-api
1.0.0-beta.11 и Vue 2.6.11
Ответ №2:
Вам нужно указать объект наблюдения, а затем назвать объект наблюдения ключом к этому объекту. Итак:
watch: {
$route(to, from) {
// react to route changes...
}
}
Смотрите здесь:https://router.vuejs.org/guide/essentials/dynamic-matching.html#reacting-to-params-changes
Комментарии:
1. спасибо за ваш ответ, но я использую composition-api, и функция просмотра немного отличается. composition-api.vuejs.org/api.html#watch
2. Ах, я понимаю, извините. Я никогда не использовал composition-api. Возможно, это поможет (если вы его еще не видели): medium.com/better-programming /…