如何在Vue.js中的父母和孙子之间进行双向数据绑定

Kam*_*cek 24 data-binding components vue.js

我遇到了一个问题,我通过cookie来解决它,但我想解决没有cookie的问题.我有一个名为app-header的组件,它有另一个叫做outmodal的组件.现在,我的第一个Vue实例需要组件app-header.

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")
    },
});
Run Code Online (Sandbox Code Playgroud)

app-header的代码

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']
}
Run Code Online (Sandbox Code Playgroud)

出口代码

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")
    }
}
Run Code Online (Sandbox Code Playgroud)

在outmodal组件我连接API,我检查登录,如果登录将成功,我想在我的Vue实例中更改登录变量的值.我使用web pack来构建所有需求.所以我不知道如何在这些文件之间进行数据绑定.

我怎么解决呢?一世

San*_*Ben 14

有几种方法可以做到,其他答案中提到了一些:

  1. 在组件上使用props
  2. 使用v-model 属性
  3. 使用同步修饰符
  4. 使用Vuex

对于双向绑定,请记住,它会导致一系列难以维护的突变,引用自文档:

不幸的是,真正的双向绑定会产生维护问题,因为子组件可以对父组件进行变异,而该变异的来源在父组件和子组件中都不明显。

以下是可用方法的一些详细信息:

1.) 在组件上使用 props

道具易于使用,是解决大多数常见问题的理想方式。
由于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());
Run Code Online (Sandbox Code Playgroud)

该对象将对组件和父级都是反应式的:

我将一个对象/数组作为道具传递,它自动双向同步 - 更改子项中的数据,更改父项中的数据。

如果通过 props 传递简单的值(字符串、数字),则必须显式使用.sync 修饰符

引自--> /sf/answers/2500672191/

2.) 使用 v-model 属性

v-model 属性是一种语法糖,可以在父子之间轻松进行双向绑定。它与同步修饰符的作用相同,只是它使用特定的道具和特定的事件进行绑定

这个:

 <input v-model="searchText">
Run Code Online (Sandbox Code Playgroud)

与此相同:

 <input
   v-bind:value="searchText"
   v-on:input="searchText = $event.target.value"
 >
Run Code Online (Sandbox Code Playgroud)

其中 prop 必须是value并且 event 必须是input

3.) 使用同步修饰符

sync 修饰符也是语法糖,与 v-model 的作用相同,只是 prop 和 event 名称由正在使用的任何内容设置。

在父级中,它可以按如下方式使用:

 <text-document v-bind:title.sync="doc.title"></text-document>
Run Code Online (Sandbox Code Playgroud)

可以从子进程发出一个事件以通知父进程任何更改:

 this.$emit('update:title', newTitle)
Run Code Online (Sandbox Code Playgroud)

4.) 使用 Vuex

Vuex 是一个可以从每个组件访问的数据存储。可以订阅更改。

通过使用 Vuex 存储,可以更容易地查看数据突变的流程,并且它们是明确定义的。通过使用vue 开发人员工具,可以轻松调试和回滚所做的更改。

这种方法需要更多的样板文件,但如果在整个项目中使用,它就会成为一种更清晰的方式来定义如何进行更改以及从何处进行更改。

请参阅入门指南