如何在 Vue.js 中实现父孙之间的双向数据绑定

2024-03-21

我遇到了一个问题,我通过 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']
}

出站代码

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 来构建所有需求。所以我不知道如何在这些文件之间进行数据绑定。

我该如何解决它?我


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

  1. Use 组件上的 props https://v2.vuejs.org/v2/guide/components.html#Passing-Data-to-Child-Components-with-Props

  2. Use v-模型属性 https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components

  3. Use the 同步修饰符 https://v2.vuejs.org/v2/guide/components-custom-events.html#sync-Modifier (适用于 Vue 2.0)

  4. Use v 模型参数 https://v3-migration.vuejs.org/breaking-changes/v-model.html#_3-x-syntax (适用于 Vue 3.0)

  5. Use Pinia https://pinia.vuejs.org/

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

1.) 在组件上使用 props

理想情况下,道具应该仅用于将数据向下传递到组件中,而事件应该将数据传递回来。这就是系统的初衷。 (使用 v-model 或同步修饰符作为“简写”)

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

使用 props 进行双向绑定是通常不建议 https://v2.vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow但有可能,通过传递一个对象或数组,您可以更改该对象的属性,并且可以在子级和父级中观察到该属性,而无需 Vue 在控制台中打印警告。

因为Vue 如何观察变化 https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats所有属性都需要在对象上可用,否则它们将不会是反应性的。 如果在 Vue 完成使它们可观察后添加任何属性'set' https://v2.vuejs.org/v2/api/#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://v2.vuejs.org/v2/guide/components-custom-events.html#sync-Modifier

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

2.) 使用 v-model 属性

v-model 属性是语法糖,可以轻松实现父级和子级之间的双向绑定。它与同步修饰符执行相同的操作,只是它使用特定的 prop 和特定的事件进行绑定

This:

 <input v-model="searchText">

与此相同:

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

道具必须在哪里value并且该事件必须是input

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

同步修饰符也是语法糖,其作用与 v-model 相同,只是 prop 和事件名称由所使用的内容设置。

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

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

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

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

4.) 使用 v 模型参数 (适用于 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 https://pinia.vuejs.org/是官方的受到推崇的 https://vuejs.org/guide/scaling-up/state-management.html#pinia状态管理器/数据存储

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

通过使用 Pinia 存储,可以更轻松地查看数据突变流,并且它们是明确定义的。通过使用vue开发者工具 https://github.com/vuejs/vue-devtools调试和回滚所做的更改很容易。

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

看看他们的入门 https://pinia.vuejs.org/introduction.html#why-should-i-use-pinia section


**In case of legacy projects** :

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Vue.js 中实现父孙之间的双向数据绑定 的相关文章

随机推荐

  • python 中的前导零[重复]

    这个问题在这里已经有答案了 Python 似乎能够接受除 08 或 09 之外的任何数字的前导零 例如 a 04 在解释器中工作但是 a 08 returns SyntaxError invalid token 我在 OSX 上使用 pyt
  • 类常量的 PHP 表达式

    我试图找出为什么我会遇到此代码的异常 class Test const test Two rows 我在包含 const 的行上遇到异常 解析错误 语法错误 意外的 期望 或 在 home BZUMUL prog php 第 X 行 我本来
  • Java 客户端/服务器套接字

    我从 java 套接字开始 并且有奇怪的 缺乏 输出 这是我的套接字方法的来源 客户端源码 public void loginToServer String host String usnm try Socket testClient ne
  • Indy 可以运行 Javascript 吗?

    有一种名为 AnyChart 的软件产品 非常适合在网页中嵌入基于 Flashed 的图表 AnyCharts 还可以导出为 PNG 文件格式 这是一个例子
  • 如何使用 sublime 在终端上运行 ruby

    我什至不确定这个问题是否正确 我正在以下链接上编写 ruby 教程 www youtube com watch v Dji9ALCgfpM 他在sublime上编写代码 并在终端上显示运行的代码 我曾经在 Integrated ruby i
  • 带选择标签的 dataTables 列过滤插件

    我正在使用数据表 v1 92 以及列过滤插件 v1 5 0 问题 我需要为单个列过滤创建下拉列表 其标记将是
  • 如何上传图片并将其保存到数据库中? [复制]

    这个问题在这里已经有答案了 我必须使用 JavaScript 创建一个表单 用户将上传一个 JPG 文件并与其他信息 例如姓名 电子邮件等 一起提交 当用户单击 提交 时 表单中的所有信息都将加载到值对象中 对于图像文件我将其设置为byte
  • 在 JavaFX 中显示字符串/标签

    我需要帮助弄清楚如何在程序中显示文本 以便它可以在我创建的多边形形状的中间显示 停止 我想做的是创建一个停车标志 我已经负责创建和显示该停止标志 所以现在我只需要在 t 中显示 停止 package application public c
  • 在 django-rest 框架中使用原始 SQL?

    我使用 Django 1 8 和带有表和物化视图的 Postgres 9 4 后端 我有一个 80GB 的表 名为spending包含支出项目 每个项目都有一个组织代码和一个区域代码 class Prescription models Mo
  • C++11 中的可变参数模板和多重继承

    我正在努力实现这样的目标 我有一个模板化基类 我想动态继承它 template
  • MSVC 的 open_memstream 的等效项

    我在用打开内存流在我的一个库中 但我想将该库移植到 MSVC 似乎没有可用的等效功能 但是有足够相似的功能吗 What 打开内存流所做的是它需要一个 char 目的地和大小并返回一个您可以写入的 FILE 数据存储在动态分配的缓冲区中 可从
  • 如何在 OS X 中包含 FFI?

    我在构建时遇到问题这个项目 https github com metaeducation ren c启用 FFI 扩展 为了隔离问题 我正在尝试编译这个例子 http www chiark greenend org uk doc libff
  • OSError:图像文件被截断

    当我处理一堆图像时 其中一个图像出现此错误 File home tensorflowpython firstmodel yololoss py line 153 in data generator image box get random
  • ASP.NET MVC - 如何根据登录用户的角色权限隐藏或显示链接/按钮?

    我正在使用 ASP NET MVC4 这是我的用户角色 1 Administrator 2 L1 Admin 3 L2 Admin 管理员组用户有设置权限 用于添加 权限设置 查看日志 错误报告等 如果用户是管理员组的成员 他只能看到与上述
  • Typescript + React/Redux:类型“IntrinsicAttributes”和“IntrinsicClassAttributes”上不存在属性“XXX”

    我正在开发一个使用 Typescript React 和 Redux 全部在 Electron 中运行 的项目 当我将一个基于类的组件包含在另一个组件中并尝试在它们之间传递参数时 我遇到了问题 宽松地说 我的容器组件结构如下 class C
  • 如何使用类型提示指定多个返回类型

    我在 python 中有一个函数 它可以返回一个bool or a list 有没有办法使用类型提示指定返回类型 例如 这是正确的方法吗 def foo id gt list or bool 从文档中 联合型 https docs pyth
  • TSQL 仅显示第一行

    我有以下 SQL 查询 SELECT DISTINCT MyTable1 Date FROM MyTable1 INNER JOIN MyTable2 ON MyTable1 Id MyTable2 Id WHERE Name John O
  • 禁用 jquery 1.6 中的元素

    随着 jQuery 1 6 的发布 对 SO 的建议是普遍开始使用prop http api jquery com prop 你以前用过的地方attr 当我想禁用某个元素时会发生什么 control prop disabled disabl
  • 如何解决查询 ImportRange 错误

    希望能得到一个正确方向的小指点 我绝对不是程序员 但我正在努力学习 QUERY IMPORTRANGE 1ZKw8d7OKX LqnYx 84IHP2fuBo 6rzzZ7TuaQOfCjio Data A2 D7 select Col1
  • 如何在 Vue.js 中实现父孙之间的双向数据绑定

    我遇到了一个问题 我通过 cookie 解决它 但我想在没有 cookie 的情况下解决问题 我有一个名为 app header 的组件 它还有另一个名为 outmodal 的组件 现在 我的第一个 Vue 实例需要组件应用程序标头 var