Я изо всех сил пытаюсь понять, как передавать данные между компонентами в 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,
}
},
})
ОБНОВИТЬ
Хорошо, у меня есть второй шаг. Вот новая скрипка, показывающая прогресс: https://jsfiddle.net/retrogradeMT/9pffnmjp/
Поскольку я использую Vue-router, я не использую реквизиты для отправки данных в новый компонент. Вместо этого мне нужно установить параметры для v-ссылки, а затем использовать перехватчик перехода, чтобы принять его.
Изменения 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,
}
},
})
источник
params
это объект. Ключ имени может быть назначенthis.user.name
в вашем компоненте. Создайте скрипку, если вам нужна помощь, и дайте мне знать. Проверьте это: vuejs.github.io/vue-router/en/route.htmlЛучший способ отправить данные от родительского компонента к дочернему - использовать props .
Передача данных от родителя к потомку через
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/vue@2.5.13/dist/vue.min.js"></script> <div id="app"> <p>At Parent: {{ variableAtParent }}<br>And is reactive (edit it) <input v-model="variableAtParent"></p> <child-comp :message="variableAtParent"></child-comp> </div>
источник
Vue.set
, подробнее здесь: vuejs.org/v2/guide/reactivity.html#For-ArraysЯ думаю, проблема здесь:
<template id="newtemp" :name ="{{user.name}}">
Когда вы добавляете в опору префикс,
:
вы указываете Vue, что это переменная, а не строка. Так что вам не нужно{{}}
окружающееuser.name
. Пытаться:<template id="newtemp" :name ="user.name">
РЕДАКТИРОВАТЬ-----
Сказанное выше верно, но большая проблема здесь в том, что при изменении URL-адреса и переходе на новый маршрут исходный компонент исчезает. Чтобы второй компонент редактировал родительские данные, второй компонент должен быть дочерним компонентом первого или просто частью того же компонента.
источник
Я нашел способ передать родительские данные в область видимости компонента во Vue, я думаю, что это немного похоже на взлом, но, возможно, это поможет вам.
1) Справочные данные в экземпляре Vue как внешний объект
(data : dataObj)
2) Затем в функции возврата данных в дочернем компоненте просто вернитесь
parentScope = dataObj
и вуаля. Теперь вы не можете делать такие вещи,{{ parentScope.prop }}
и они будут работать как шарм.Удачи!
источник
Вышеупомянутые ответы работают хорошо, но если вы хотите передавать данные между двумя дочерними компонентами, то также можно использовать шину событий. Посетите этот блог, который поможет вам лучше понять.
Предположим для двух компонентов: CompA и CompB, имеющие одинаковый родительский и main.js для настройки основного приложения vue. Для передачи данных из CompA в CompB без участия родительского компонента вы можете сделать следующее.
в файле main.js объявите отдельный глобальный экземпляр Vue, который будет шиной событий.
export const bus = new Vue();
В CompA, где генерируется событие: вы должны отправить событие на шину.
methods: { somethingHappened (){ bus.$emit('changedSomething', 'new data'); } }
Теперь задача состоит в том, чтобы прослушать сгенерированное событие, поэтому в CompB вы можете слушать как.
created (){ bus.$on('changedSomething', (newData) => { console.log(newData); }) }
Преимущества:
источник
Я получаю доступ к основным свойствам, используя
$root
.Vue.component("example", { template: `<div>$root.message</div>` }); ... <example></example>
источник
Глобальная переменная (объект) 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>
источник