VueJS: доступ к родительскому объекту prop у child, когда дочерний объект посещается напрямую (с использованием vue-router) без централизованного хранилища (vuex или eventBus) - PullRequest
0 голосов
/ 15 мая 2019

В этой демонстрации codesandbox родительский компонент home имеет дочерний компонент addItem.Родительский массив передает (как prop) дочернему элементу, и таким образом дочерний элемент может добавить элемент в список родительского элемента, то есть обычный способ передачи данных из parent -> child, т.е. через props :fruitsArr="fruits".

* 1008.* 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>

Проблема заключается в том, что ребенка посещают напрямую, используя router-link (vue-router), тогда родительская опора :fruitsArr="fruits" недоступна.

Может кто-нибудь расскажет мне, как или как правильно передать реквизит родителя ребенку, когда текущий маршрут является дочерним, чтобы ребенок мог добавить элемент в список родителей.Я бы предпочел решение без использования VueX или любого другого централизованного магазина, такого как eventBus.

Спасибо

Ответы [ 2 ]

0 голосов
/ 15 мая 2019

Ответ Стивена Спангина хорош. Но вы должны принять во внимание, что данные, которые предоставляют / вводят, не являются реактивными.

Как говорится, вам нужно создать какой-то централизованный "источник истины". Если вы не хотите использовать Vuex - самое простое решение - объявить еще один экземпляр Vue и сохранить там ваши глобальные данные. Это было бы реактивным.

const myStore = new Vue({
  data:{
    fruits: ["Apple", "Mango", "Orange", "PineApple"]
  }
})
export myStore;

и в вашем компоненте

import {myStore} from 'somewhere';

//to use prop in your template - proxy it using computed prop
....
computed:{
  fruits(){
    return myStore.fruits;
  }
}
....
0 голосов
/ 15 мая 2019

Существует несколько решений.

Обеспечение / Внедрение

Вы можете использовать предоставление / внедрение для отправки данных по дочерней иерархии.Это рекомендуемый способ обмена данными из parent to non-immediate child, когда связь необходима только для одного parent-child branch, и вы не хотите использовать Vuex.

https://vuejs.org/v2/api/#provide-inject

Мета-поле

Вы можете хранить элементы в мета-полях маршрута и инициализировать их в навигационной системе.Тогда он доступен во всех компонентах.

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 }
        }
      ]
    }
  ]
})

С учетом сказанного, Vue способ состоит в emit events up и receive properties down, поэтому попробуйте поработать сэта архитектура, если позволяет ваш вариант использования.

...