VueJS:在没有集中存储(vuex 或 eventBus)的情况下直接访问子项时(使用 vue-router)访问子项中的父项 [英] VueJS: Access parent prop in child when the child is visited directly (using vue-router) without a centralized store (vuex or eventBus)
问题描述
在这个 codesandbox 演示中,父home
组件有一个子 addItem
组件.父级将数组(作为道具)传递给子级,因此子级可以将项目添加到父级列表中,即从父级传递数据的正常方式 -> 子级,即通过 props :fruitsArr="fruits"
.
Main.js
从vue"导入Vue;从vue-router"导入VueRouter;从./App.vue"导入应用程序;从./components/Home.vue"导入Home;从./components/addItem.vue"导入addItem;Vue.use(VueRouter);var 路由器 = 新的 VueRouter({模式:历史",路线:[{ path: "", 组件: Home, name: "Home" },{路径:"/addItem",组件:添加项目,名称:添加项目"}]});Vue.config.productionTip = false;新的 Vue({路由器,渲染:h =>h(应用程序)}).$mount("#app");
App.vue
<div id="应用程序"><app-header></app-header><br><路由器视图></路由器视图>
</模板><脚本>从./components/common/appHeader"导入 appHeader;导出默认{名称:应用程序",成分: {应用头}};
appHeader.vue
<ul class="nav nav-pills"><router-link tag="li" to="/" active-class="active" exact><a>家</a></路由器链接><router-link tag="li" to="/addItem" active-class="active"><a>添加项目</a></路由器链接></模板>
Home.vue
<div><addItem :fruitsArr="fruits"/><h3>水果列表</h3><ul><li v-for="(fruit, idx) in Fruits" :key="idx">{{fruit}}</li>
</模板><脚本>从 "./addItem" 导入 addItem;导出默认{名称:应用程序",数据() {返回 {水果:[苹果"、芒果"、橙子"、松果"]};},成分: {新增项目}};
addItem.vue
<div class="input-wrapper">输入水果名称:<input type="text" v-model="fruitItem"><button @click="addFruit">添加水果</button>
</模板><脚本>导出默认{数据() {返回 {水果项目:"};},道具:["fruitsArr"],方法: {添加水果(){this.fruitsArr.push(this.fruitItem);}},};
问题是当使用 router-link
(vue-router) 直接访问孩子时,父母的道具 :fruitsArr="fruits"
不可用.
任何朋友能告诉我,当当前路线是孩子时,如何或正确的方式将父母的道具传递给孩子,以便孩子能够将项目添加到父母的列表中.我更喜欢不使用 VueX 或任何其他集中式存储(例如 eventBus)的解决方案.
谢谢
有几个解决方案.
提供/注入
您可以使用提供/注入将数据向下发送到子层次结构.当只需要在单个 父子分支
上进行通信并且您不想去时,这是从父级到非直接子级
共享数据的推荐方式使用 Vuex
.
https://vuejs.org/v2/api/#provide-inject一个>
元字段
您可以将项目存储在路由的元字段中并在导航守卫中对其进行初始化.然后它在所有组件中都可用.
https://router.vuejs.org/guide/advanced/navigation-guards.html
const router = new VueRouter({路线:[{路径:'/foo',组件:Foo,孩子们: [{路径:'酒吧',组件:酒吧,//一个元字段元:{ requiresAuth:真}}]}]})
话虽如此,Vue
的方式是向上发射事件
和向下接收属性
,所以如果你用例允许.
In this codesandbox demo, the parent home
component has a child addItem
component. Parent's passes array (as prop) to the child and so the child is able to add item to the parent's list i.e. the normal way of passing data from parent -> child i.e. via props :fruitsArr="fruits"
.
Main.js
import Vue from "vue";
import VueRouter from "vue-router";
import App from "./App.vue";
import Home from "./components/Home.vue";
import addItem from "./components/addItem.vue";
Vue.use(VueRouter);
var router = new VueRouter({
mode: "history",
routes: [
{ path: "", component: Home, name: "Home" },
{
path: "/addItem",
component: addItem,
name: "Add Item"
}
]
});
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App)
}).$mount("#app");
App.vue
<template>
<div id="app">
<app-header></app-header>
<br>
<router-view></router-view>
</div>
</template>
<script>
import appHeader from "./components/common/appHeader";
export default {
name: "App",
components: {
appHeader
}
};
</script>
appHeader.vue
<template>
<ul class="nav nav-pills">
<router-link tag="li" to="/" active-class="active" exact>
<a>Home</a>
</router-link>
<router-link tag="li" to="/addItem" active-class="active">
<a>Add Item</a>
</router-link>
</ul>
</template>
Home.vue
<template>
<div>
<addItem :fruitsArr="fruits"/>
<h3>Fruits List</h3>
<ul>
<li v-for="(fruit, idx) in fruits" :key="idx">{{fruit}}</li>
</ul>
</div>
</template>
<script>
import addItem from "./addItem";
export default {
name: "App",
data() {
return {
fruits: ["Apple", "Mango", "Orange", "PineApple"]
};
},
components: {
addItem
}
};
</script>
addItem.vue
<template>
<div class="input-wrapper">
Enter Fruit Name:
<input type="text" v-model="fruitItem">
<button @click="addFruit">Add Fruit</button>
</div>
</template>
<script>
export default {
data() {
return {
fruitItem: ""
};
},
props: ["fruitsArr"],
methods: {
addFruit() {
this.fruitsArr.push(this.fruitItem);
}
},
};
</script>
The problem is when the child is visited directly using router-link
(vue-router) then parent's prop :fruitsArr="fruits"
is not available.
Can anybuddy tell me, how to or the correct way to pass parent's prop to the child when the current route is the child, such that child is able to add item to the parent's list. I'd prefer a solution WITHOUT using VueX or any other centralized store such as eventBus.
Thanks
There are a couple of solutions.
Provide/Inject
You can use provide/inject to send data down the child hierarchy. This is the recommended way to share data from parent to non-immediate child
when the communication is only needed on a single parent-child branch
, and you do not want to go with Vuex
.
https://vuejs.org/v2/api/#provide-inject
Meta Field
You can store items in the route's meta fields and initialize it in a navigation guard. Then it is available in all components.
https://router.vuejs.org/guide/advanced/navigation-guards.html
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
With that said, the Vue
way is to emit events up
and receive properties down
, so try to work with that architecture if your use-case allows.
这篇关于VueJS:在没有集中存储(vuex 或 eventBus)的情况下直接访问子项时(使用 vue-router)访问子项中的父项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!