前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >7.vue组件(二)--双向绑定,父子组件访问

7.vue组件(二)--双向绑定,父子组件访问

作者头像
用户7798898
发布于 2021-03-04 06:47:23
发布于 2021-03-04 06:47:23
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

本文主要说两件事

1. 如何实现父子组件之间的双向绑定

2. 父组件如何访问子组件的data,method, 子组件如何访问父组件的data,method等


一. 如何实现父子组件之间的双向绑定

案例描述:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
父子组件双向绑定
父组件有一个message,
子组件有一个文本框
让他们两个同步变化

实现思路:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1. 子组件接收父组件传递过来的参数
2. 先实现子组件的双向绑定
3. 子组件将数据传给父组件

实现步骤:

第一步: 子组件接收父组件的data

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../js/vue.js"></script>
</head>
<body>
    <div id="app">
        父组件的值: {{message}}
        <br>
        <input type="text" v-model="message"></input>
        <comp1 :cmessage="message" ></comp1>
    </div>

    <template id="comp1">
        <div style=" width: 600px; background-color: #085e7d; color: antiquewhite">
            <h2>子组件cmessage的值:{{cmessage}}</h2>
            <br>
        </div>
    </template>
    <script>
        Vue.component("comp1", {
            template: "#comp1",
            props: ["cmessage"],

        })
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello"
            }
        });
    </script>
</body>
</html>

子组件通过属性props: ["cmessage"], 来接收父组件的message属性. 并且父组件修改message的值, 子组件跟随改变

效果如下:

第二步: 实现子组件属性的双向绑定

组件的数据绑定, 使用的也是data属性.但在组件中, data定义为一个方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../js/vue.js"></script>
</head>
<body>
    <div id="app">
        父组件的值: {{message}}
        <br>
        <input type="text" v-model="message"></input>
        <comp1 :cmessage="message" ></comp1>
    </div>

    <template id="comp1">
        <div style=" width: 600px; background-color: #085e7d; color: antiquewhite">
            <h2>子组件cmessage的值:{{cmessage}}</h2>
            <h2>子组件cmess的值: {{cmess}}</h2>
            <br>
            cmess:<input type="text"  v-model="cmess" ></input>
            <br>
        </div>
    </template>
    <script>
        Vue.component("comp1", {
            template: "#comp1",
            props: ["cmessage"],
            data() {
                return {
                    "cmess": this.cmessage
                }
            }

        })
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello"
            }
        });
    </script>
</body>
</html>

data中定义了属性cmess, 其值是属性cmessage的值. 我们实现cmess属性的双向绑定.cmess:<input type="text" v-model="cmess" ></input>

效果如下:

这样子组件cmess的双向绑定实现了, 但是我们发现修改父组件的时候,子组件没有变化. 修改子组件的时候, 父组件也没有变化

第三步: 子组件属性变化同步给父组件

子组件属性的改变同步给父组件, 使用的是自定义事件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../js/vue.js"></script>
</head>
<body>
    <div id="app">
        父组件的值: {{message}}
        <br>
        <input type="text" v-model="message"></input>
        <comp1 :cmessage="message" @csyncchange="syncchange"></comp1>
    </div>

    <template id="comp1">
        <div style=" width: 600px; background-color: #085e7d; color: antiquewhite">
            <h2>子组件cmessage的值:{{cmessage}}</h2>
            <h2>子组件cmess的值: {{cmess}}</h2>
            <br>
            cmess:<input type="text"  v-model="cmess"  @input="changeMessage"></input>
            <br>
        </div>
    </template>
    <script>
        Vue.component("comp1", {
            template: "#comp1",
            props: ["cmessage"],
            data() {
                return {
                    "cmess": this.cmessage
                }
            },
            methods: {
                changeMessage(event) {
                    console.log(event.target.value)
                    this.$emit("csyncchange", event.target.value)
                }
            },
            watch: {
                cmessage(val, oldval) {
                    console.log(val, oldval)
                    console.log()
                    this.cmess = val
                }
            }

        })
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello"
            },
            methods: {
                syncchange(value) {
                    this.message = value
                }
            }
        });
    </script>
</body>
</html>

添加子组件的input事件: @input="changeMessage".

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
changeMessage(event) {
    console.log(event.target.value)
    this.$emit("csyncchange", event.target.value)
}

然后自定义一个csyncchange事件, 父组件监听这个事件的变化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<comp1 :cmessage="message" @csyncchange="syncchange"></comp1>

父组件自定义一个method方法, 接收事件传递的数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
methods: {
    syncchange(value) {
        this.message = value
    }
}    

这样就实现了子组件修改cmess的值, 同步给父组件. 效果如下:

但是, 我们发现,在组建同步给父组件没问题, 组件只同步数据给了props属性, 而没有同步给cmess

第四步: 使用watch方法监听props属性的变化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../js/vue.js"></script>
</head>
<body>
    <div id="app">
        父组件的值: {{message}}
        <br>
        <input type="text" v-model="message"></input>
        <comp1 :cmessage="message" @csyncchange="syncchange"></comp1>
    </div>

    <template id="comp1">
        <div style=" width: 600px; background-color: #085e7d; color: antiquewhite">
            <h2>子组件cmessage的值:{{cmessage}}</h2>
            <h2>子组件cmess的值: {{cmess}}</h2>
            <br>
            cmess:<input type="text"  v-model="cmess"  @input="changeMessage"></input>
            <br>
        </div>
    </template>
    <script>
        Vue.component("comp1", {
            template: "#comp1",
            props: ["cmessage"],
            data() {
                return {
                    "cmess": this.cmessage
                }
            },
            methods: {
                changeMessage(event) {
                    console.log(event.target.value)
                    this.$emit("csyncchange", event.target.value)
                }
            },
            watch: {
                cmessage(val, oldval) {
                    console.log(val, oldval)
                    console.log()
                    this.cmess = val
                }
            }

        })
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello"
            },
            methods: {
                syncchange(value) {
                    this.message = value
                }
            }
        });
    </script>
</body>
</html>

这一步的重点是watch方法. 同步cmessage的值给cmess. 看看效果

以上,完美实现了,父子组件的双向数据绑定.

二. 父子组件的相互访问

如果父组件想要访问子组件的属性和方法, 或者子组件想要访问父组件的属性和方法怎么办呢? 下面来看看:

1. 父组件访问子组件

父组件访问子组件有两种方式

  • 1. 使用$children
  • 2. 使用@refs

案例: 现在有一个父组件, 想要拿到子组件的方法或者变量.

  • 使用$children获取
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
获取所有的子组件: this.$children
获取某个子组件的属性: this.$children.属性名
获取某个子组件的方法: this.$children.方法名()
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>第一种方法: 使用children访问子组件</h1>
    <app1-comp></app1-comp>
    <app1-comp></app1-comp>
    <app1-comp></app1-comp>
    <button @click="btnclick">按钮</button>

</div>

<template id="comp1">
    <div>
        <p>只有app1才能使用的组件</p>
        <h2>{{name}}</h2>
    </div>
</template>
<script src="../../js/vue.js"></script>
<script>
    const app1Comp = Vue.extend({
        template: comp1,
        data() {
            return {
                name : "name名称"
            }
        },
        methods: {
            getchange() {
                console.log("getchange方法")
            }
        }

    })

    let app = new Vue({
        el: "#app",
        data: {
            message: "hello"
        },
        components:{
            app1Comp: app1Comp
        },
        methods: {
            btnclick() {
                console.log("点击事件", this.$children)
                console.log("父组件访问子组件的data数据: ",this.$children[1].name)
                console.log("父组件访问子组件的方法: ",this.$children[1].getchange())

            }
        }
    });

</script>
</body>
</html>

在dom中使用了三个comp1组件. 我们可以使用this.$children来获取所有的组件

这里获取到了3个组件, 并打印了第二个组件的名称和方法

  • 使用@refs获取属性

使用refs的好处是可以根据组件名称获取. 而不是遍历, 因为遍历的下标时可能修改的.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--
    父组件访问子组件有两种方式
    1. 使用$children
    2. 使用@refs

    需求: 现在有一个父组件, 想要拿到子组件的方法或者变量.
    所以, 我们先定义一个组件.

-->
<div id="app">
    <h1>第二种方法: 使用refs访问子组件</h1>
    <app2-comp ref="app21"></app2-comp>
    <app2-comp ref="app22"></app2-comp>
    <app2-comp ref="app23"></app2-comp>
    <button @click="btnclick">按钮</button>

</div>

<template id="comp1">
    <div>
        <p>只有app1才能使用的组件</p>
        <h2>{{name}}</h2>
    </div>
</template>
<script src="../../js/vue.js"></script>
<script>
    const app1Comp = Vue.extend({
        template: comp1,
        data() {
            return {
                name : "name名称"
            }
        },
        methods: {
            getchange() {
                console.log("getchange方法")
            }
        }

    })

    let app = new Vue({
        el: "#app",
        data: {
            message: "hello"
        },
        components:{
            app1Comp: app1Comp,
            app2Comp: app1Comp
        },
        methods: {
            btnclick() {

                console.log(this.$refs.app21.name)
                console.log(this.$refs.app21.getchange())
            }
        }
    });

</script>
</body>
</html>

这一次我们给组件起了名字, 通过$refs可以指定组件名,获取属性和方法

2. 子组件访问父组件

  • 子组件访问父组件使用的是$parent
  • 子组件访问根组件使用$root

通常new Vue()也是一个组件, 他是根组件. 如果子组件想要获取根组件的属性和方法,使用@root

下面这个例子, 是子组件comp1里面引用了另一个组件comp2. 在comp2中获取comp1的属性和方法, 使用@parent, 这就是子组件获取父组件的属性和方法

comp2要想获取new Vue()对象的属性和方法, 使用的是$root.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--
    父组件访问子组件有两种方式
    1. 使用$children
    2. 使用@refs

    需求: 现在有一个父组件, 想要拿到子组件的方法或者变量.
    所以, 我们先定义一个组件.

-->
<div id="app">
    <h1>子组件访问父组件</h1>
    <comp1></comp1>


</div>
<template id="comp1">
    <div>
        <comp2></comp2>
    </div>

</template>
<template id="comp2">
    <div>
        <p>组件comp2</p>
        <button  type="text" @click="btnClick">按钮</button>
    </div>
</template>
<script src="../../js/vue.js"></script>
<script>
    const app1Comp = Vue.extend({
        template: comp1,
        data() {
            return {
                name: "name名称"
            }
        },
        components: {
            comp2: {
                template: comp2,

                methods: {
                    btnClick() {
                        console.log(this.$parent)
                        console.log(this.$parent.name)

                        // 获取root元素, 也就是vue元素
                        console.log(this.$root)
                        console.log(this.$root.message)
                    }
                }
            }
        }
    })

    let app = new Vue({
        el: "#app",
        data: {
            message: "hello"
        },
        components:{
            comp1: app1Comp
        },
        methods: {
            btnclick() {

            }
        }
    });

</script>
</body>
</html>

以上就是父子组件之间相互访问的情况

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
6. vue组件详解(一)
组件系统是 Vue 的一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。几乎任意类型的应用界面都可以抽象为一个组件树:
用户7798898
2021/03/04
1.5K0
6. vue组件详解(一)
Vue组件化 模板 语法糖 函数 父子组件通信
支持:String、Number、Boolean、Array、Object、Date、Function、Symbol
有勇气的牛排
2023/06/25
2210
Vue进阶——组件化开发
类似微服务的软件架构,在前端开发中,一个页面的实现往往十分复杂,我们可以将一个页面划分为多个块,每个块负责相应的功能,块之间通过通信来交互。这样的前端开发方式正是组件化开发,一个页面是一个大的组件树,其下又划分有很多小的组件。这样一来,不仅降低了一次开发的难度,而且避免了重复造轮子,组件可以灵活的嵌入其他的Vue项目中进行使用。
matt
2022/10/25
1.2K0
Vue进阶——组件化开发
4.vue 的双向绑定的原理是什么?_vue双向绑定底层原理
但是,我想通过反向传到父组件中,也就是改变number1的值,也就是改变data中的num1,怎么整?
全栈程序员站长
2022/11/02
1.5K0
4.vue 的双向绑定的原理是什么?_vue双向绑定底层原理
Vue之组件化(三)
每个组件的数据都存放在自己的data函数中,不可以直接使用其他组件或Vue实例(根组件)中的data数据。 在开发时,页面中展示的数据都是通过网络请求获取而来的动态数据。因为每个组件都是独立存在,即每个组件中的数据都是独立存储的,那每个组件所需要的动态数据都是通过各自发送网络请求而获取来的吗? 由于组件化的思想,一个完整的页面可以根据功能划分成若干个组件,而这些组件也可以根据逻辑功能再次细分。所以一个页面是由许多个组件集成的。
yuanshuai
2022/08/22
5750
Vue之组件化(三)
从零开始学VUE之组件化开发(父子组件的访问方式)
父子组件的访问方式 有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件 父组件访问子组件:使用children或者refs 子组件访问父组件:使用$parent 子组件访问根组件:使用$root 父组件访问子组件[$children] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../../js/vu
彼岸舞
2021/06/07
6340
从零开始学VUE之组件化开发(父子组件的访问方式)
Vue学习-组件化开发
将一个页面拆分成一个个小的功能块,每个功能块完成自己独立的功能,这样在之后的页面维护和管理就会方便许多。
花猪
2022/02/17
1.5K0
Vue学习-组件化开发
【Vue.js】017-Vue组件:基本使用、组件注册、父子组件、父子组件通信
人的大脑处理问题的能力是有限的,当人们面对复杂问题的时候,很难一次性解决,但人的大脑也天生具有将问题拆解的能力,化繁为简,逐个解决,这种复杂问题拆解成多个小问题在程序中的表现就是组件化。在程序开发中,如果我们将一个复杂页面的所有逻辑都放在一起,势必导致逻辑混乱,难以阅读,不利于后续的管理和扩展。但如果我们将页面拆解成一个个小的功能块,每个功能块完成自己独立的功能,且这些功能块能够被应用到其他页面(可复用),那么程序的开发就会非常易于管理和扩展。
訾博ZiBo
2025/01/06
1970
【Vue.js】017-Vue组件:基本使用、组件注册、父子组件、父子组件通信
vue父组件操作子组件的方法_vue父组件获取子组件数据
我们经常分不清什么是父组件,什么是子组件。现在来简单总结下:我们将某段代码封装成一个组件,而这个组件又在另一个组件中引入,而引入该封装的组件的文件叫做父组件,被引入的组件叫做子组件。具体代码如下
全栈程序员站长
2022/09/19
7.2K0
vue父组件操作子组件的方法_vue父组件获取子组件数据
理解Vue中的组件化开发
主要从ui界面上进行划分。例如前端的组件化,方便ui组件的调用。类似于以前的导航栏。
代码天才TTT
2023/08/01
6690
Vue 组件数据通信方案总结
初识 Vue.js ,了解到组件是 Vue 的主要构成部分,但组件内部的作用域是相对独立的部分,组件之间的关系一般如下图:
前端迷
2019/09/25
4480
Vue 组件数据通信方案总结
Vue基础语法(四)
④同时在父与子关联的cpn标签,进行v-bind动态绑定将父组件的变量city值传递给子组件自定义绑定名,子组件就可以直接通过使用自定义绑定名,直接显示父组件传递的城市
申小兮
2023/05/12
2190
Vue基础语法(四)
vue-组件通讯
vue组件系统提供了⼀种抽象,让我们可以使⽤独⽴可复⽤的组件来构建⼤型应⽤,任意类型的应⽤界 ⾯都可以抽象为⼀个组件树。组件化能提⾼开发效率,⽅便重复使⽤,简化调试步骤,提升项⽬可维护 性,便于多⼈协同开发
刘嘿哈
2022/10/25
3350
vue-组件通讯
重学巩固你的Vuejs知识(上)
https://github.com/webVueBlog/interview-answe/issues/156
达达前端
2020/10/28
3.7K0
11. webpack配置Vue
webpack原理和用法详解链接: cnblogs.com/ITPower/p/14467745.html
用户7798898
2021/03/05
6220
11. webpack配置Vue
Vue组件数据通信方案总结
初识Vue.js,了解到组件是Vue的主要构成部分,但组件内部的作用域是相对独立的部分,组件之间的关系一般如下图:
青梅煮码
2023/01/12
1.7K0
VUE——vue中组件之间的通信方式有哪些
这种方式,从严格意义上讲不是值的传递,而是一种“取”(不推荐直接通过实例进行值的获取)
思索
2024/08/16
1500
vue父子组件传值
父组件可以在引用子组件的时候, 通过属性绑定(v-bind:) 的形式, 把需要传递给子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用。
砖业洋__
2023/05/06
5200
vue父子组件传值
Vue3从入门到精通(二)
在Vue3中,侦听器的使用方式与Vue2相同,可以使用watch选项或$watch方法来创建侦听器。不同之处在于,Vue3中取消了immediate选项,同时提供了新的选项和API。
明志德道
2023/10/21
4460
Vue3 | 父子组件间通信、组件间双向绑定的高级内容、插槽详解、动态组件、异步组件
前面的笔记 —— 《Vue3 | 组件的定义及复用性、局部组件、全局组件、组件间传值及其校验、单项数据流、Non-props属性》,单向数据流的概念, 即子组件无法修改来自父组件的数据字段, 如果确要修改,可以使用下面说的方式进行通信: 首先,在子组件的UI点击回调方法中,调用this.$emit('【自定义事件名】'), 向外发送一个事件; 接着各级父组件会收到这个事件, 则在父组件中 调用 子组件标签处, 以 @【事件名】= "回调方法名"的形式,监听该事件以及配置回调方法; 回调方法中即可 对 子组件意图修改 的 父组件数据字段 进行修改;
凌川江雪
2021/03/23
6.4K0
Vue3 | 父子组件间通信、组件间双向绑定的高级内容、插槽详解、动态组件、异步组件
相关推荐
6. vue组件详解(一)
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验