Передача данных компонентам в vue.js




(4)

------------- Следующее применимо только к Vue 1 --------------

Передача данных может быть выполнена несколькими способами. Способ зависит от типа использования.

Если вы хотите передать данные из вашего HTML, пока вы добавляете новый компонент. Это делается с помощью реквизита.

<my-component prop-name="value"></my-component>

Это значение prop будет доступно вашему компоненту, только если вы добавите имя prop-name в свой атрибут props .

Когда данные передаются от компонента к другому компоненту из-за некоторого динамического или статического события. Это делается с помощью диспетчеров событий и вещателей. Так, например, если у вас есть такая структура компонентов:

<my-parent>
    <my-child-A></my-child-A>
    <my-child-B></my-child-B>
</my-parent>

И вы хотите отправить данные из <my-child-A> в <my-child-B> затем в <my-child-A> вам нужно будет отправить событие:

this.$dispatch('event_name', data);

Это событие пройдет весь путь до родительской цепочки. И от того, у кого из родителей есть ветвь к <my-child-B> вы транслировали событие вместе с данными. Итак, в родительском:

events:{
    'event_name' : function(data){
        this.$broadcast('event_name', data);
    },

Теперь эта трансляция пройдет по детской цепочке. И в зависимости от того, какой ребенок захочет захватить событие, в нашем случае <my-child-B> мы добавим еще одно событие:

events: {
    'event_name' : function(data){
        // Your code. 
    },
},

Третий способ передачи данных - через параметры в v-линках. Этот метод используется, когда цепочки компонентов полностью разрушены или когда изменяется URI. И я вижу, вы уже поняли их.

Решите, какой тип передачи данных вы хотите, и выберите соответственно.

Я пытаюсь понять, как передавать данные между компонентами в vue.js. Я несколько раз прочитал документы и посмотрел на многие вопросы и руководства, связанные с Vue, но я все еще не понимаю.

Чтобы обдумать это, я надеюсь на помощь в завершении довольно простого примера

  1. отобразить список пользователей в одном компоненте (готово)
  2. отправить пользовательские данные в новый компонент, когда ссылка нажата (сделано) - см. обновление внизу.
  3. отредактируйте данные пользователя и отправьте их обратно в исходный компонент (пока не получили)

Вот скрипка, которая не выполняется на втором этапе: https://jsfiddle.net/retrogradeMT/d1a8hps0/

Я понимаю, что мне нужно использовать реквизит для передачи данных в новый компонент, но я не уверен, как это сделать функционально. Как связать данные с новым компонентом?

HTML:

    <div id="page-content">
       <router-view></router-view>
     </div>

 <template id="userBlock" >
   <ul>
     <li v-for="user in users">{{user.name}} - <a v-link="{ path: '/new' }"> Show new component</a>
     </li>
   </ul>
 </template>

  <template id="newtemp" :name ="{{user.name}}">
    <form>
      <label>Name: </label><input v-model="name">
      <input type="submit" value="Submit">
    </form>
  </template>

JS для основного компонента:

Vue.component('app-page', {
  template: '#userBlock',

  data: function() {
    return{

        users: []
      }
    },

ready: function () {
    this.fetchUsers();
},

methods: {
    fetchUsers: function(){
        var users = [
          {
            id: 1,
            name: 'tom'
          },
          {
            id: 2,
            name: 'brian'
          },
          {
            id: 3,
            name: 'sam'
          },
        ];

        this.$set('users', users);
     }
    }
  })

JS для второго компонента:

Vue.component('newtemp', {
  template: '#newtemp',
  props: 'name',
  data: function() {
    return {
        name: name,
        }
   },
})

ОБНОВИТЬ

Хорошо, я понял второй шаг. Вот новая скрипка, показывающая прогресс: https://jsfiddle.net/retrogradeMT/9pffnmjp/

Поскольку я использую Vue-router, я не использую реквизиты для отправки данных новому компоненту. Вместо этого мне нужно установить параметры в V-Link, а затем использовать переходный крюк, чтобы принять его.

Изменения V-Link см. Поименованные маршруты в документации vue-router :

<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>

Затем в компоненте добавьте данные к параметрам маршрута, см. Переходные хуки :

Vue.component('newtemp', {
  template: '#newtemp',
  route: {
   data: function(transition) {
        transition.next({
            // saving the id which is passed in url
            name: transition.to.params.name
        });
     }
  },
 data: function() {
    return {
        name:name,
        }
   },
})

Глобальная переменная JS (объект) может использоваться для передачи данных между компонентами. Пример: передача данных из Ammlogin.vue в Options.vue. В Ammlogin.vue rspData установлен на ответ от сервера. В Options.vue ответ от сервера доступен через rspData.

index.html:

<script>
    var rspData; // global - transfer data between components
</script>

Ammlogin.vue:

....    
export default {
data: function() {return vueData}, 
methods: {
    login: function(event){
        event.preventDefault(); // otherwise the page is submitted...
        vueData.errortxt = "";
        axios.post('http://vueamm...../actions.php', { action: this.$data.action, user: this.$data.user, password: this.$data.password})
            .then(function (response) {
                vueData.user = '';
                vueData.password = '';
                // activate v-link via JS click...
                // JSON.parse is not needed because it is already an object
                if (response.data.result === "ok") {
                    rspData = response.data; // set global rspData
                    document.getElementById("loginid").click();
                } else {
                    vueData.errortxt = "Felaktig avändare eller lösenord!"
                }
            })
            .catch(function (error) {
                // Wu oh! Something went wrong
                vueData.errortxt = error.message;
            });
    },
....

Options.vue:

<template>
<main-layout>
  <p>Alternativ</p>
  <p>Resultat: {{rspData.result}}</p>
  <p>Meddelande: {{rspData.data}}</p>
  <v-link href='/'>Logga ut</v-link>
</main-layout>
</template>
<script>
 import MainLayout from '../layouts/Main.vue'
 import VLink from '../components/VLink.vue'
 var optData = { rspData: rspData}; // rspData is global
 export default {
   data: function() {return optData},
   components: {
     MainLayout,
     VLink
   }
 }
</script>

Я думаю, что проблема здесь:

<template id="newtemp" :name ="{{user.name}}">

Когда вы ставите перед пропеллером знак : вы указываете Vue, что это переменная, а не строка. Таким образом, вам не нужно {{}} вокруг user.name . Пытаться:

<template id="newtemp" :name ="user.name">

РЕДАКТИРОВАТЬ-----

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


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

1) Справочные данные в Vue Instance как внешний объект (data : dataObj)

2) Затем в функции возврата данных в дочернем компоненте просто верните parentScope = dataObj и вуаля. Теперь вы не можете делать что-то вроде {{ parentScope.prop }} и работать как шарм.

Удачи!