当前位置: 首页 > news >正文

vue-2 组件传值

组件关系分类

  1. 父子关系
  2. 非父子关系
    在这里插入图片描述

父子通信流程

在这里插入图片描述

父组件通过props将数据传递给子组件

  1. 给子组件以添加属性的方式传值
  2. 子组件内部通过 props 接收
  3. 模板中直接使用 props 接收的值

在这里插入图片描述
父组件 Parent.vue

<template><div class="parent" style="border: 3px solid #f60202;text-align: center"><span>我是 父 组件</span><!-- 1.给组件标签,添加属性方式 赋值 --><div style="text-align: center"><Son :title="sonTitle"></Son></div></div>
</template><script>
import Son from '@/pages/test/Son.vue'
export default {name: 'Parent',data() {return {sonTitle: '父组件传给子组件',}},components: {Son,},
}
</script><style scoped>
.parent {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);height: 300px;width: 700px;
}
</style>

子组件 Son.vue

<template><div class="son" style="border:3px solid #000"><!-- 3.直接使用 props 的值 -->我是 子 组件-- {{title}}</div>
</template><script>
export default {name: 'Son',// 2.通过 props 来接收props: {title: {type: String,require: true}}
}
</script><style scoped>
.son {height: 200px;width: 300px;margin-left: calc((700px - 300px)/2);margin-top: calc((300px - 200px)/2);float: left;
}</style>

子组件利用$emit通知父组件修改更新

  1. $emit 触发事件,给父组件发送消息通知
  2. 父组件监听$emit 触发的事件
  3. 提供处理函数,在函数的性参中获取传过来的参数

在这里插入图片描述

代码省略样式

子组件 Son.vue

<template><div class="son" style="border:3px solid #000"><!-- 3.直接使用 props 的值 -->我是 子 组件-- {{title}}<br/><button @click="changeFu">修改title</button></div>
</template><script>
export default {name: 'Son',methods: {changeFu() {// 通过this.$emit向父组件发送通知 名字要保持一致 参数一事件,参数二:参数this.$emit('changeTitle','newtitle')}},// 通过 props 来接收props: {title: {type: String,require: true}}
}
</script>

父组件 Parent.vue

<template><div class="parent" style="border: 3px solid #f60202;text-align: center"><span>我是 父 组件</span><!-- 1.给组件标签,添加属性方式 赋值 --><div style="text-align: center"><Son :title="sonTitle" @changeTitle="handleChange"></Son></div></div>
</template><script>
import Son from '@/pages/test/Son.vue'export default {name: 'Parent',data() {return {sonTitle: '父组件传给子组件',}},methods: {// 提供处理函数,提供逻辑handleChange(newTitle) {this.sonTitle = newTitle}},components: {Son,},
}
</script>

props 示例

<script>export default {// 完整写法(类型、默认值、非空、自定义校验)props: {w: {type: Number,required: true,default: 0,validator(val) {// console.log(val)if (val >= 100 || val <= 0) {console.error('传入的范围必须是 0-100 之间')return false} else {return true}},},},}
</script>
  • default 和 required 一般不同时写(因为当时必填项时,肯定是有值的)
  • default后面如果是简单类型的值,可以直接写默认值。如果是复杂类型的值,则需要以函数的形式 return 一个默认值

props & data、单向数据流

共同点:都可以给组件提供数据。
区别:data 的数据是自己的 → 随便改;prop 的数据是外部的 → 不能直接改,要遵循 单向数据流。
单向数据流:父级 props 的数据更新,会向下流动,影响子组件。这个数据流动是单向的。


非父子通信 — event bus 事件总线

非父子组件之间,进行简易消息传递。(复杂场景→ Vuex)

步骤

  1. 创建一个都能访问的事件总线 (空 Vue 实例):
import Vue from 'vue'
const Bus = new Vue()
export default Bus
  1. A 组件(接受方),监听 Bus 的 $on 事件:
created () {Bus.$on('sendMsg', (msg) => {this.msg = msg})}
  1. B 组件(发送方),触发 Bus 的$emit 事件:
Bus.$emit('sendMsg', '这是一个消息')

在这里插入图片描述

代码示例

新建 EventBus.js

实例化一个新组件实例并向外暴露,作为兄弟组件传值的媒介:

import Vue from 'vue'
const Bus  =  new Vue()
export default Bus

新建 BaseA.vue(接收方)

<template><div class="base-a">我是 A 组件(接受方)<p>{{msg}}</p></div>
</template>
<script>
import Bus from '@/pages/test/EventBus'
export default {data() {return {msg: '',}},created() {Bus.$on('sendMsg', (msg) => {this.msg = msg})},
}
</script>
<style scoped>
.base-a {width: 200px;height: 200px;border: 3px solid #000;border-radius: 3px;margin: 10px;
}
</style>

新建 BaseB.vue(发送方)

<template><div class="base-b"><div>我是 B 组件(发布方)</div><button @click="sendMsgFn">发送消息</button></div>
</template><script>
import Bus from '@/pages/test/EventBus'
export default {methods: {sendMsgFn() {Bus.$emit('sendMsg', '今天天气不错,适合旅游')},},
}
</script><style scoped>
.base-b {width: 200px;height: 200px;border: 3px solid #000;border-radius: 3px;margin: 10px;
}
</style>

App.vue

<template><div class="app"><BaseA></BaseA><BaseB></BaseB></div>
</template>
<script>
import BaseA from "@/pages/test/BaseA.vue";
import BaseB from "@/pages/test/BaseB.vue";export default {components: {BaseB, BaseA}
}
</script>

非父子通信 — provide & inject

作用

跨层级共享数据,不只是父子之间,也可以是祖父与孙子之间,曾祖父与重孙之间……

1、父组件 provide 提供数据

export default {provide () {return {// 普通类型【非响应式】color: this.color, // 复杂类型【响应式】userInfo: this.userInfo, }}}

2、子/孙组件 inject 获取数据

export default {inject: ['color','userInfo'],created () {console.log(this.color, this.userInfo)}}

在这里插入图片描述

传递方式

export default {data(){return{obj:{name:'JavaScript',},developer:'布兰登·艾奇',year:1995,update:'2021 年 06 月',}},provide(){return {obj: this.obj, // 方式 1.传入一个可监听的对象developerFn:() => this.developer, // 方式 2.通过 computed 来计算注入的值year: this.year, // 方式 3.直接传值app: this, // 方式 4. 提供祖先组件的实例 缺点:实例上挂载很多没有必要的东西 比如:props,methods。}}
}

注意

无论点击多少次,孙组件中的诞生于 year 字段永远都是 1995 并不会发生变化,通过 方式 1、方式 2、方式 4 传值是可以响应的。

在孙组件中修改祖组件传递过来的值(方式 1、方式 4),发现对应的祖组件中的值也发生了变化。查看目录爷爷组件一,父组件一,孙组件一

代码示例

爷爷组件 Grandpa.vue

<template><div style="border: #fb0707 3px solid "><button @click="changeMsg">祖组件触发</button><h3>祖组件</h3><Parent></Parent></div>
</template><script>
import Parent from '@/pages/test/Parent.vue';
export default {data(){return{obj:{name:'JavaScript',},developer:'布兰登·艾奇',year:1995,update:'2021 年 06 月',}},provide(){return {obj: this.obj, // 方式 1.传入一个可监听的对象developerFn:() => this.developer, // 方式 2.通过 computed 来计算注入的值year: this.year, // 方式 3.直接传值app: this, // 方式 4. 提供祖先组件的实例 缺点:实例上挂载很多没有必要的东西 比如:props,methods。}},components: {Parent,},methods:{changeMsg(){this.obj.name = 'Vue';this.developer = '尤雨溪';this.year = 2014;this.update = '2021 年 6 月 7 日';},},
}
</script>

父组件 Parent.vue

<template><div class="wrap" style="border: #0759fb 3px solid "><h4>父组件(只做中转)</h4><Son/></div>
</template><script>
import Son from '@/pages/test/Son.vue';
export default {components:{Son,},
}
</script>

孙组件 Son.vue

<template><div style="border: #605d5d 3px solid "><h5>孙组件</h5><span>名称:{{obj.name}}</span> |<span>作者:{{developer}}</span> |<span>诞生于:{{year}}</span> |<span>最后更新于:{{this.app.update}}</span></div>
</template><script>
export default {computed:{developer(){return this.developerFn()}},inject:['obj','developerFn','year','app'],
}
</script>

爷爷组件一 Grandpa.vue

<template><div style="border: #f60202 3px solid "><h1>祖组件</h1><span>名称:{{obj.name}}</span> |<span>最后更新于:{{update}}</span><parent></parent></div>
</template><script>
import parent from '@/pages/test/Parent.vue';
export default {data(){return{obj: {name: 'JavaScript',},update: '2021 年 06 月',}},provide() {return {obj: this.obj,app: this,}},components: {parent,},
}
</script>

父组件一 Parent.vue

不变

孙组件一 Son.vue

<template><div style="border: #656567 3px solid "><button @click="changeMsg">孙组件触发</button><h3>孙组件</h3><span>名称:{{obj.name}}</span> |<span>最后更新于:{{this.app.update}}</span></div>
</template><script>
export default {inject:['obj','app'],methods: {changeMsg(){this.obj.name = 'React';this.app.update = '2020 年 10 月';}},
}
</script>

在这里插入图片描述

总结

慎用 provide / inject
Vuex 和 provide/inject 最大的区别:Vuex 中的全局状态的每次修改是可以追踪回溯的,而 provide/inject 中变量的修改是无法控制的。换句话说,不知道是哪个组件修改了这个全局状态。

相关文章:

  • Django学习(2)项目实战
  • React 18
  • ISO 19115-2:2019 第6章 获取和处理元数据
  • 【C++】STL中list的使用
  • powerdesigner各种字体设置
  • 深度解析:全流量分析与IP会话回溯在IT运维中的应用
  • matlab演示银河系转动动画
  • 进程概念(二)
  • pytest配置文件配置并通过allure生成报告
  • 使用difflib实现文件差异比较用html显示
  • Ansible离线部署 之 Zabbix
  • c语言基础篇C
  • linux centos consul1.15.2一键安装部署
  • 【差分数组】1674. 使数组互补的最少操作次数
  • 【文末附gpt升级秘笈】AI热潮降温与AGI场景普及的局限性
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • @angular/forms 源码解析之双向绑定
  • [ JavaScript ] 数据结构与算法 —— 链表
  • [译]如何构建服务器端web组件,为何要构建?
  • “大数据应用场景”之隔壁老王(连载四)
  • bootstrap创建登录注册页面
  • create-react-app项目添加less配置
  • docker容器内的网络抓包
  • github指令
  • Idea+maven+scala构建包并在spark on yarn 运行
  • JavaScript设计模式之工厂模式
  • Java新版本的开发已正式进入轨道,版本号18.3
  • js面向对象
  • maya建模与骨骼动画快速实现人工鱼
  • quasar-framework cnodejs社区
  • springMvc学习笔记(2)
  • vue自定义指令实现v-tap插件
  • 从重复到重用
  • 飞驰在Mesos的涡轮引擎上
  • 简单数学运算程序(不定期更新)
  • 免费小说阅读小程序
  • 悄悄地说一个bug
  • 使用 QuickBI 搭建酷炫可视化分析
  • 使用Gradle第一次构建Java程序
  • 通过git安装npm私有模块
  • 在Unity中实现一个简单的消息管理器
  • ​人工智能书单(数学基础篇)
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #define,static,const,三种常量的区别
  • #单片机(TB6600驱动42步进电机)
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (C11) 泛型表达式
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (四)图像的%2线性拉伸
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET 的程序集加载上下文
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题