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")
    },
});

应用程序头代码

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']
}

非模态代码

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 实例中登录变量的值。我使用 web pack 来构建所有需求。所以我不知道如何在这些文件之间进行数据绑定。

我该如何解决?我

原文由 Kamuran Sönecek 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 418
2 个回答

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

  1. 在组件上使用道具

  2. 使用 v-model 属性

  3. 使用 同步修饰符 (适用于 Vue 2.0)

  4. 使用 v-model 参数 (适用于 Vue 3.0)

  5. 使用 松树

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

1.) 在组件上使用道具

理想情况下,道具应该只用于将数据向下传递到组件中,而事件应该将数据向上传递。这就是系统的预期方式。 (使用 v-model 或 sync 修饰符作为“速记”)

道具和事件易于使用,是解决最常见问题的理想方式。

通常不建议 使用 props 进行双向绑定,但可以这样做,通过传递一个对象或数组,您可以更改该对象的属性,并且它将在子级和父级中观察到,而 Vue 不会在控制台中打印警告。

由于 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());

该对象将对组件和父级都具有反应性:

如果您将对象/数组作为道具传递,它会自动进行双向同步 - 在子节点中更改数据,在父节点中更改。

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

引自 –> https://stackoverflow.com/a/35723888/1087372

2.) 使用 v-model 属性

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

这个:

  <input v-model="searchText">

与此相同:

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

prop 必须是 value 并且 event 必须 输入 的地方

3.) 使用同步修饰符 (适用于 Vue 2.0)

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

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

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

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

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

4.) 使用 v-model 参数 (适用于 Vue 3.0)

在 Vue 3.x 中,同步修饰符被移除。

相反,您可以使用解决相同问题的 v-model 参数

 <ChildComponent v-model:title="pageTitle" />

<!-- would be shorthand for: -->

<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />

5.) 使用 Pinia(或 Vuex)

截至目前 Pinia 是官方 推荐 的状态管理器/数据存储

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。

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

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

看看他们的 入门 部分


**如果是遗留项目**:

如果你的项目已经使用了 Vuex,你可以继续使用它。

Vuex 3 和 4 仍将被维护。但是,它不太可能为其添加新功能。 Vuex 和 Pinia 可以安装在同一个项目中。如果您要将现有的 Vuex 应用程序迁移到 Pinia,它可能是一个合适的选择。但是,如果您打算开始一个新项目,我们强烈建议您使用 Pinia。

原文由 SanBen 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题