Передача данных в компоненты в 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,
}
},
})
Ответы
Ответ 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>