IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 如何在vue 中使用组件,以及组件通信的方式(父传子/子传父/兄弟传) -> 正文阅读

[JavaScript知识库]如何在vue 中使用组件,以及组件通信的方式(父传子/子传父/兄弟传)


前言

组件可以说是 vue 中最为核心的一部分了,通过组件化,可以使得整个项目的创建更加的高效和便捷。下面我主要是介绍学习的关于组件的通信方式。


零、如何使用封装组件

一般我们在一个 vue 项目中,项目的结构就如官网给出的下图这般:

在这里插入图片描述

我们的项目分为由很多个组件来构成一个整体,这有什么好处呢?我个人觉得,有下面几点:

  • 可复用:往往某些部分我们会多次用到,通过抽离成组件,我们只需要引用,不仅减少工作量,还减少了
  • 结构化,我们对整个项目更加的条理和清晰,当出现问题也能便捷的定位和处理更换。

简单介绍在项目中使用吧!我们用脚手架创建了一个项目,那么里面会有一个 components文件夹就是用来存放组件的。我们可以在这里创建我们使用到的组件。组件的格式以下面:

<template>
  
</template>

<script>
export default {
  name: 'TemplateExplainDialog',
 }
</script>

<style scoped>

</style>

组件的几个注意点就是:

  • 命名一般以大写字母开头
  • date里面是函数
  • 每一个组件相当于一个vue的实例,所以有独立的生命周期等等

在使用上,我们创建好组件后,我们在需要使用到该组件的地方中

  • 引入该组件文件
  • components声明
  • 然后使用就好了
  1. 建立组件的模板,根据需求实现结果和样式
  2. 分析数据的接收和输出,比如使用到的 props 和 emit
  3. 父组件中调用和实例化

完整的使用方式,可以参考下方的代码案例。

一、为什么需要下面的通信方式

首先我们需要知道,在 vue 中组件间的信息是遵循数据的单向流通的,因为要是子组件的实例化很可能是多个的,要是组件间双向的,那会导致数据乱成一团了,一个子组件改变了父组件的数据,会导致与该组件有关的所有子组件的数据发生变化,所以是应该避免的。

二、父组件给子组件通信

  • 首先在子组件中使用 props,来接收对应的属性
  • 在父组件中使用子组件的地方,添加上面定义的属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <Parents></Parents>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        const ABorder = {
            //用props来接收父组件传来的值,同时父组件要绑定属性
            props: {
                name:{
                    //设置类型,符合才接收
                    type: String,
                    //不传默认为这个
                    default: '我也不知道呀'
                }
            },
            template: `<div>我是儿子A
                        <div>我的名字叫:{{name}}</div>
                       </div>`
        };
        const BBorder = {
            template: `<div>我是儿子B</div>`
        }
        const Parents = {
            data() {
                return {
                    msg: '孩儿们好呀!',
                    aName: '大花猫',
                    bName: '大黄狗'
                }
            },
            //可以有下面两种形式来调用组件
            template: `<div>我是父组件:{{msg}}
          		<hr/>
                <a-border :name= 'this.aName'></a-border>
                <hr/>
                <BBorder></BBorder></div>`,
            components: {
                ABorder,
                BBorder 
            }
        }
        //实例化一个vue,并且绑定到app这个元素
        const vm = new Vue({
            el: '#app',
            components: {
                Parents,
            }
        })
    </script>
</body>
</html>

输出的效果图如下:
在这里插入图片描述
这里子组件A接收到了,来自父组件的值(大花猫)

那么我们在这里又另外个需求了,儿子A, 他不想叫大花猫,他想给自己命名为小黄鸭,他进行了,下面的操作:

<script>
    const ABorder = {
        template: `<div>我是儿子A
        <div>我的名字叫:{{name}}</div>
        <button @click="newName">给自己命名</button>
        </div>`,
        //用props来接收父组件传来的值,同时父组件要绑定属性
        props: {
            name:{
                //设置类型,符合才接收
                type: String,
                //不传默认为这个
                default: '我也不知道呀'
            }
        },
        methods: {
          newName() {
              this.name = '小黄鸭'
          }
        }
    };

这时候就报错了!
在这里插入图片描述
想知道具体为啥吗?看我的另外一篇文章,里面详细的讲解了这个问题,以及给出了,解决的办法哦。点击链接

当然,我们也可以通过下面即将讲到的方法来解决。

三、子组件给父组件通信

我们父组件可以通过 props 来向子组件传递值,那么要是我们子组件需要向父组件传递值呢?如果我们可以实现向父组件传递值,那么两个组件间,不就形成一个闭环啦,数据就可以根据我们的需要来进行传递了!!方法如下:

  • 子组件中声明对应饿事件,通过 this.$emit(‘事件’ , ‘数据’)
  • 在父组件中使用子组件的地方,添加上面定义的事件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<div id="app">
    <Parents></Parents>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const ABorder = {
        template: `<div>我是儿子A
        <div>我的名字叫:{{name}}</div>
        <button @click="newName">给自己命名</button>
        </div>`,
        //用props来接收父组件传来的值,同时父组件要绑定属性
        props: {
            name:{
                //设置类型,符合才接收
                type: String,
                //不传默认为这个
                default: '我也不知道呀'
            }
        },
        methods: {
          newName() {
              this.$emit('newName','大黄狗')
          }
        }
    };
    const BBorder = {
        template: `<div>我是儿子B</div>`
    }
    const Parents = {
        data() {
            return {
                msg: '孩儿们好呀!',
                aName: '大花猫',
                bName: '大黄狗'
            }
        },
        methods: {
            chang(value) {
                this.aName = value
            }
        },
        //可以有下面两种形式来调用组件
        template: `<div>我是父组件:{{msg}}
        <hr/>
        <a-border :name= 'this.aName'  @newName = 'chang'></a-border>
        <hr/>
        <BBorder></BBorder></div>`,
        components: {
            ABorder,
            BBorder
        }
    }
    //实例化一个vue,并且绑定到app这个元素
    const vm = new Vue({
        el: '#app',
        components: {
            Parents,
        }
    })
</script>
</body>
</html>

实现的效果如下:
在这里插入图片描述
点击按键后:
在这里插入图片描述
这时成功把子组件中的值(大黄狗)传递给了父组件,同时父组件传递给子组件,实现了数据的更新。

四、兄弟组件通信

上面我们说的是爸爸和儿子A他们为名字的争论过程,可是我们是不是忘了个人,那就是儿子B呢?儿子B他觉得大黄狗这个名字真好听,也想给自己命名为大黄狗呀!这么一来,父亲就不高兴了,老子起给你们的名字,你们都不要,自己搞去吧!

现在就面临一个问题了,儿子A 需要和 儿子B 大家讨论,谁叫大黄狗这个名字?那么他们如何决定呢?他老爸不肯来参与了,那么我们就需要第三方来沟通协商两者了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<div id="app">
    <Parents></Parents>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    //创建一个媒介来连通两个是组件
    const medium = new  Vue()

    const ABorder = {
        template: `<div>我是儿子A
        <div>我的名字叫:{{name}}</div>
        <button @click="newName">给自己命名</button>
        </div>`,
        created () {
            medium.$on('letDiscussionName',(val)=>{
              alert(val)
            })
        },
        //用props来接收父组件传来的值,同时父组件要绑定属性
        props: {
            name:{
                //设置类型,符合才接收
                type: String,
                //不传默认为这个
                default: '我也不知道呀'
            }
        },
        methods: {
          newName() {
              this.$emit('newName','大黄狗')
          }
        }
    };
    const BBorder = {
        template: `<div>我是儿子B
                    <button @click="discussionName">讨论</button>
                   </div>`,
        methods: {
            discussionName() {
                medium.$emit('letDiscussionName','儿子A来讨论')
            }
        }
    }

    const Parents = {
        data() {
            return {
                msg: '孩儿们好呀!',
                aName: '大花猫',
                bName: '大黄狗'
            }
        },
        methods: {
            chang(value) {
                this.aName = value
            }
        },
        //可以有下面两种形式来调用组件
        template: `<div>我是父组件:{{msg}}
        <hr/>
        <a-border :name= 'this.aName'  @newName = 'chang'></a-border>
        <hr/>
        <BBorder></BBorder></div>`,
        components: {
            ABorder,
            BBorder
        }
    }
    //实例化一个vue,并且绑定到app这个元素
    const vm = new Vue({
        el: '#app',
        components: {
            Parents,
        }
    })
</script>
</body>
</html>

我们点击儿子B里的 discussionName 那么就会去触发 儿子A里的letDiscussionName,正常来说,我们是用 this.xxxxx 的,但是我们这里是创建了一个Vue的实例对象 medium来连接两者,因为使用 this 的话,只是分别指向他们组件本身们这里我们通过 medium 就相当于给两者之间搭了条桥(第三者)。这是中间事件总线的思想。

同样的我们也可以用父组件来做中转的,也是可以的!

五、多层组件之间的通信

当我们构建一个大点的项目时,往往会有很多个组件构成的,A组件下可能还有 B组件 ,B组件下有C组件…E组件.,那么我们如果要是需要在E组件中拿到A组件的值该如何做呢?

那么其实这里很简单,我们在父组件中使用 provide ,在子组件中使用 inject

// 父级组件提供 name
var Parent= {
  provide: {
    name: '大花猫'
  },
  // ...
}

// 子组件引入 name
var Son = {
  inject: ['name'],
  created () {
    console.log(this.name) // 大花猫
  }

}



总结

到这里,组件间传递值的基本方法就介绍完了,后面在来补充一些遇到的技巧和知识点要注意的地方。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-20 15:00:21  更:2021-08-20 15:00:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:07:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码