Подтвердить что ты не робот

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

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

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

  • отобразить список пользователей в одном компоненте (сделано)
  • отправьте данные пользователя новому компоненту при щелчке ссылки (сделано) - см. обновление внизу.
  • отредактируйте пользовательские данные и отправьте их обратно в исходный компонент (не получили этого).

Вот скрипка, которая не работает на втором шаге: 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,
        }
   },
})

UPDATE

Хорошо, у меня есть второй шаг. Вот новая скрипка, показывающая прогресс: 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,
        }
   },
})
4b9b3361

Ответ 1

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

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


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

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

Это значение prop будет доступно вашему компоненту, только если вы добавите имя 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 изменяется. И я вижу, что вы уже понимаете их.


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

Ответ 2

Лучший способ отправить данные из родительского компонента ребенку - использовать реквизиты.

Передача данных от родителя к ребенку через props

  • Объявите props (массив или объект) в дочернем элементе
  • Передайте это ребенку через <child :name="variableOnParent">

Смотрите демо ниже:

Vue.component('child-comp', {
  props: ['message'], // declare the props
  template: '<p>At child-comp, using props in the template: {{ message }}</p>',
  mounted: function () {
    console.log('The props are also available in JS:', this.message);
  }
})

new Vue({
  el: '#app',
  data: {
    variableAtParent: 'DATA FROM PARENT!'
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>

<div id="app">
  <p>At Parent: {{ variableAtParent }}</p>
  <child-comp :message="variableAtParent"></child-comp>
</div>

Ответ 3

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

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

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

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

ИЗМЕНИТЬ -----

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

Ответ 4

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

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

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

Удачи!

Ответ 5

Глобальная переменная 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>