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

Как двустороннее связывание данных между родителями и внуками в Vue.js

У меня возникла проблема, я решаю ее с помощью файлов cookie, но я хочу решить проблему без файлов cookie. У меня есть компонент, который называется app-header, и у него есть другой компонент, который называется outmodal. Теперь для моего первого экземпляра Vue требуется компонентный заголовок приложения.

var vue = new Vue({
    el : "html",
    data : {
        title       : "Site Title",
        description : "description of page",
        keywords    : "my keywords",
        view        : "home",
        login       : "login"
    },
    components:{
        "app-header" :require("../../components/header"),
        "app-footer" :require("../../components/footer"),
        "home"       :require("../../views/home")
    },
});

код заголовка приложения

var Vue     = require("vue");

Vue.partial("login",require("../../partials/login.html"));
Vue.partial("logged",require("../../partials/logged.html"));

module.exports = {
    template    : require("./template.html"),
    replace     : true,
    components  : {
        outmodal : require("../outmodal")
    },
    props : ['login']
}

код outmodal

var Vue = require("vue");
Vue.partial("loginModal",require("../../partials/loginModal.html"));

module.exports = {
    template    : require("./template.html"),
    replace     : true,
    props       : ['name'],
    data        : function () {
            return  {
                userLogin : { mail  :   "", password    :   "", remember    :   ""}
            }

    },
    methods : {
        formSubmit : function(e){
                e.preventDefault();
                this.$http.post("http://example.com/auth/login",{ "email": this.userLogin.mail , "password": this.userLogin.password },function(data,status,request){
                    $.cookie("site_token",data.token,{expires : 1})
                }).error(function(data,status,request){

                });

        }
    }, ready  : function(){
        console.log("it works")
    }
}

В outmodal компоненте я подключаю API, и я проверяю логин. Если логин будет успешным, я хочу изменить значение переменной входа в моем экземпляре Vue. Я использую веб-пакет для создания всех запросов. Поэтому я не знаю, как привязывать данные между этими файлами.

Как я могу это решить? I

4b9b3361

Ответ 2

Есть несколько способов сделать это, и некоторые упоминаются в других ответах:

  1. Используйте реквизит на компонентах
  2. Использовать атрибут v-model
  3. Используйте модификатор синхронизации
  4. Используйте Vuex

При двустороннем связывании имейте в виду, что он может вызвать цепочку мутаций, которые трудно поддерживать, цитируется в документации:

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

Вот некоторые подробности о доступных методах:

1.) Используйте реквизит на компонентах

Реквизит прост в использовании и является идеальным способом решения наиболее распространенных проблем.
Из-за того, как Vue наблюдает за изменениями, все свойства должны быть доступны для объекта, иначе они не будут реактивными. Если какие-либо свойства будут добавлены после того, как Vue закончит делать их видимыми, нужно будет использовать "set".

 //Normal usage
 Vue.set(aVariable, 'aNewProp', 42);
 //This is how to use it in Nuxt
 this.$set(this.historyEntry, 'date', new Date());

Объект будет реактивным как для компонента, так и для родителя:

Если вы передаете объект/массив в качестве реквизита, он автоматически выполняет двустороннюю синхронизацию - изменяйте данные в дочернем элементе, он изменяется в родительском.

Если вы передаете простые значения (строки, числа) через реквизит, вы должны явно использовать модификатор .sync

Как цитируется → fooobar.com/questions/717067/...

2.) Используйте атрибут v-model

Атрибут v-model является синтаксическим сахаром, который обеспечивает простую двустороннюю привязку между родителем и потомком. Он делает то же самое, что и модификатор sync, только использует конкретную опору и конкретное событие для привязки.

Это:

<input v-model="searchText">

так же, как это:

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

Где реквизит должен быть значением, а событие должно быть введено

3.) Используйте модификатор sync

Модификатор sync также является синтаксическим сахаром и делает то же самое, что и v-модель, только то, что имена пропов и событий задаются тем, что используется.

В родительском это может быть использовано следующим образом:

<text-document v-bind:title.sync="doc.title"></text-document>

От ребенка может быть отправлено событие для уведомления родителя о любых изменениях:

 this.$emit('update:title', newTitle)

4.) Используйте Vuex

Vuex - это хранилище данных, доступное из каждого компонента. На изменения можно подписаться.

Используя хранилище Vuex, легче увидеть поток мутаций данных, и они явно определены. С помощью инструментов разработчика vue легко отладить и откатить внесенные изменения.

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

Смотрите руководство по началу работы

Ответ 3

я нашел это, чтобы быть более точным. https://vuejs.org/v2/guide/components.html#sync-Modifier только в версии 2.3. 0+ tho. и, честно говоря, это все еще не достаточно хорошо. просто должен быть простым вариантом для "двусторонней" привязки данных. так что ни один из этих вариантов не хорош.

попробуйте вместо этого использовать vuex. у них есть больше вариантов для этой цели. https://vuex.vuejs.org/en/state.html