Vue 组件通信及进阶语法

文章目录

  • 一、scoped 样式冲突
  • 二、data 是一个函数
  • 三、组件通信
    • 1. 父子通信
      • 1.1 props 校验
      • 1.2 props 比较 data
    • 2. 非父子通信
      • 2.1 event bus
      • 2.2 provide-inject
  • 四、进阶语法
    • 1. v-model 详解
    • 2. sync 修饰符
    • 3. ref 和 $refs
    • 4. $nextTick

一、scoped 样式冲突

注意点:
① 结构:只能有一个根元素;
② 样式:组件中定义的样式默认是全局生效的,会影响到所有组件,而 scoped 属性下的样式可以作用于当前组件;
③ 逻辑:el 是根实例所独有的,data 是一个函数。

默认情况下,写在组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题,而组件应该有着自己独立的样式,我们可以给组件加上 scoped 属性,让样式只作用于当前组件。

<style scoped>
</style>

scoped 原理:给当前组件中的所有元素都添加一个自定义属性(data-v-hash),不同的哈希值用于区分不同的组件!

二、data 是一个函数

在一个组件里面,data 选项必须是一个函数,保证每个组件实例维护独立的一份数据对象。 每次创建新的组件实例,都会执行一次 data 函数,得到一个新对象,各个对象之间互不影响。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三个实例对象各自独立,互不影响!

三、组件通信

组件通信就是指组件与组件之间的数据传递。 组件之间的数据是独立的,无法直接访问其他组件的数据,想要用其他组件的数据,就必须要组件通信。

组件关系分为父子关系和非父子关系:

在这里插入图片描述

1. 父子通信

父组件通过 props 将数据传递给子组件,子组件不能直接修改父组件中的数据,而是利用 $emit 通知父组件进行修改更新。

在这里插入图片描述

<!--App.vue-->
<template><div class="App"><Son :title="myTitle" @changeTitle="handleChange"></Son></div>
</template><script>
import Son from './components/Son.vue';
export default {data() {return {myTitle: '栈老师不回家'}},components: {Son},methods: {handleChange(newTitle) {this.myTitle = newTitle}}
}
</script><style scoped>
.App {width: 600px;height: 600px;background-color: rgb(193, 230, 248);margin: 0 auto;padding: 20px;
}
</style>
<!--Son.vue-->
<template><div class="son">{{ title }}<button @click="changeFn">修改</button></div> 
</template><script>
export default {props: ['title'],methods: {changeFn() {this.$emit('changeTitle', '新数据')}}
}
</script><style>
.son {width: 200px;height: 200px;background-color: #f8dd30;margin: 0, auto;
}
</style>

通过自定义属性和自定义事件来实现父子之间的通信。子组件通过 $emit 向父组件发送消息通知,第一个参数是父组件中自定义的监听事件,第二个参数是修改的新数据,父组件通过 @change Title 监听消息,并做出回应,即修改数据。

1.1 props 校验

props 用于向子组件传递数据,并且可以传递任意类型、任意数量的数据。

为了保证组件的正常运行,组件的 props 不可以乱传。我们可以给组件的 props 指定验证要求,不符合要求,控制台就会有错误提示,可以帮助开发者快速发现错误。

① 类型校验

props: {校验的属性名: 类型 //Number、String、Boolean、Array、Object...
}

② 更详细的校验

props: {校验的属性名: {type: 类型, //Number、String、Boolean、Array、Object...required: true, //是否必填default: 默认值, //默认值validator(value) { //value就是传过来的属性名//自定义校验逻辑return true //true通过校验,false不通过校验}}
} 

1.2 props 比较 data

共同点:都可以给组件提供数据。

区别:data 的数据是自己的,可以随便改;props 的数据是外部的,不能直接改,要遵循单向数据流原则,通知其父组件进行修改。

单向数据流:父组件的 props 更新,会单向向下流动,从而影响到子组件。

count++ 是 count 加 1 并重新赋值,会直接修改 count 的值,而 count + 1 并不会重新赋值,count 的值也不会被改变,所以对于 props 里的数据,不要使用 ++,直接让它 + 1 通知父组件即可!

谁的数据谁负责,数据一般提供在公共的父组件中!

2. 非父子通信

2.1 event bus

event bus 用于非父子组件之间,进行简易的消息传递。

① 创建一个双方都能访问到的事件总线(空 Vue 实例)→ utils/EventBus.js

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

② A 组件(接收方),监听 Bus 实例的事件

created() {Bus.$on('sendMsg', (msg) => {this.msg = msg})
}

③ B 组件(发送方),触发 Bus 实例的事件

Bus.$emit('sendMsg', '这是一个消息')

发送方发送消息,从而触发 Bus,而接收方时刻监听着 Bus,Bus 一旦被触发,接收方立马就可以接收到消息!

完整代码如下:

//EventBus.js
//创建一个都能访问到的事件总线(空的Vue实例)
import Vue from "vue";
const Bus = new Vue()
export default Bus
//BaseA.vue
<template><div class="baseA">我是A组件(接收方)<div>{{ msg }}</div></div></template><script>import Bus from '@/utils/EventBus';export default {data() {return {msg: ''}},created() {//订阅消息Bus.$on('sendMsg', (msg) => {this.msg = '收到消息了:'+ msg})}}</script><style scoped>.baseA {width: 200px;height: 150px;padding: 10px;margin-top: 10px;border: 3px solid #000;border-radius: 5px;font-size: 20px;}</style>
<template><div class="baseB">我是B组件(发布方)<button @click="publish">发布通知</button></div>
</template><script>
import Bus from '@/utils/EventBus';
export default {methods: {publish() {//发送方通过触发事件的方式发布消息Bus.$emit('sendMsg', '栈老师回家')}}
}
</script><style scoped>
.baseB {width: 200px;height: 150px;padding: 10px;margin-top: 10px;border: 3px solid #000;border-radius: 5px;font-size: 20px;
}
</style>

在这里插入图片描述

在这里插入图片描述

发送方发送的消息,可以被多个接收方订阅!

2.2 provide-inject

跨层级(孙子和爷爷)之间的通信用 provide-inject。

//发送方,爷爷
provide() {return {color: this.color, //简单类型,非响应式userInfo: this.userInfo //复杂类型,响应式}
},
data() {return {color: 'blue',userInfo: {name: '栈老师',age: 20}}
}
//接收方,孙子
inject: ['color', 'userInfo']

使用 provide-inject 共享数据的时候,通常以复杂类型的形式,把数据包装成一个对象进行传递,这样可以保证数据的响应式。

四、进阶语法

1. v-model 详解

原理:v-model 本质上是一个语法糖,例如应用在输入框上,就是 value 属性和事件的合写。

作用:提供数据的双向绑定。

注意:$event 用于在模版中获取事件的形参。

<!--两个input作用一样-->
<div class="App"><input v-model="msg" type="text"><input :value="msg" @input="msg=$event.target.value" type="text">
</div>

$event.target.value 就是输入框中的值!

表单类组件封装

① 父传子:数据应该是父组件 props 传递过来的,v-model 拆解绑定数据。
② 子传父:监听输入,子传父传值给父组件修改。

应用场景举例:此下拉框中所有的数据都来自它的父组件,所以数据是不能直接修改的,子组件中也不能使用 v-model,因为 v-model 会修改数据,解决办法就是拆解 v-model,让 value 和 @change 拆开写。

在这里插入图片描述

<select :value="cityId" @change="handleChange">
...
</select>
props: {cityId: String
},
methods: {handleChange(e) {this.$emit('父组件中的事件名', e.target.value)}
}
<!--父组件接收-->
<BaseSelect :cityId="selectId" @事件名="selectId=$event"/>

2. sync 修饰符

作用:可以实现子组件与父组件数据的双向绑定,简化代码。

特点:props 属性名可以自定义,非固定为 value。

场景:封装弹框类的基础组件,visible 属性,true 显示,false 隐藏。

:属性名.sync,本质上就是 :属性名和 @update:属性名的合写。

<!--父组件与子组件通过:visible.sync即可实现数据的双向绑定-->
<BaseDialog :visible.sync = "isShow"/>
//子组件正常用props接收数据,emit发出修改申请
props: {visible: Boolean
},
methods: {close() {this.$emit('update:visible', false) //'update:属性名', 修改后的数据}
}

3. ref 和 $refs

作用:ref 和 $refs 用于获取 dom 元素或组件实例。

查询范围:当前组件内(更精准确定)。

① 获取 dom 元素

<!--给目标标签添加ref属性-->
<div ref="chartRef">我是渲染图标的容器</div>
//dom渲染完成后(mounted),通过this.$refs.属性值,获取目标标签
mouted() {console.log(this.$refs.chartRef)
}

② 获取组件

<!--给目标组件添加ref属性-->
<BaseForm ref="baseForm">我是一个组件</BaseForm>
//使用this.$refs.baseForm可以获取目标组件
this.$refs.baseForm.组件方法()

获取到目标组件后,就可以直接调用组件对象里面的方法!

4. $nextTick

需求:点击编辑,编辑框自动显示并聚焦。

this.isShowEdit = true //显示输入框
this.$refs.inp.focu() //获取焦点

问题:以上代码并不能立刻获取焦点。

原因Vue 是异步更新(提升性能)。并不会读一行就执行一行,它要等全部代码都读完了才开始执行,所以此处 dom 还没更新出来,就去获取焦点,显然是不可能成功的。

$nextTick:等 DOM 更新后,才会触发执行此方法里的函数体。

将获取焦点的操作放在 $nextTick 里面就可以了:

this.$nextTick(() => {this.$refs.inp.focus()
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/471722.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode105.从前序与中序遍历构造二叉树

题目要求 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 提示: 1 < preorder.length < 3000inorder.length preorder.length-3000 < pr…

【问卷调研】HarmonyOS SDK开发者社区用户需求有奖调研

问卷请点击&#xff1a;HarmonyOS SDK开发者社区用户需求有奖调研

IOT物联网低代码可视化大屏解决方案汇总

目录 参考来源云服务商阿里云物联网平台产品主页产品文档 开源项目DGIOT | 轻量级工业物联网开源平台项目特点项目地址开源许可 IoTGateway | 基于.NET6的跨平台工业物联网网关项目特点项目地址开源许可 IoTSharp | 基于.Net Core开源的物联网基础平台项目特点项目地址开源许可…

如何在Mac上切换到JDK 17开发环境

在本文中&#xff0c;我将为您介绍如何在Mac上切换到JDK 17&#xff0c;包括下载和安装JDK 17、设置环境变量、在IntelliJ IDEA中配置项目、修改Maven编译配置&#xff0c;并最终使用mvn clean install重新编译项目。通过这个流程&#xff0c;您可以顺利地将开发环境升级到JDK …

玩转ChatGPT:文献阅读 v2.0

一、写在前面 好久不更新咯。 因为最近ChatGPT更新了不少功能&#xff08;水一篇刷存在感&#xff09;&#xff1a; 上线ChatGPT-4o模型&#xff0c;说推理能力还不错&#xff1b;上线联网功能&#xff0c;类似Kimi那种。 所以呢&#xff0c;用它来读文献就挺舒服的了。例如…

自动驾驶系列—从数据采集到存储:解密自动驾驶传感器数据采集盒子的关键技术

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

HarmonyOS本地存储-Preferences(用户首选项)的使用

一&#xff0c;用户首选项简述 ohos.data.preferences (用户首选项) 用户首选项为应用提供Key-Value键值型的数据处理能力&#xff0c;支持应用持久化轻量级数据&#xff0c;并对其修改和查询。 数据存储形式为键值对&#xff0c;键的类型为字符串型&#xff0c;值的存储数据…

SpringCloud 微服务消息队列灰度方案 (RocketMQ 4.x)

目录 背景遇到的问题 RocketMQ 基础基础消息模型扩展后的消息模型部署模型相关概念点 方案对比影子Topic的方案Tag的方案UserProperty的方案影子Group的方案灰度分区的方案方案对比 灰度分区方案设计适配只有部分灰度的情况所做的功能扩展消费者&#xff08;无灰度&#xff09;…

「QT」文件类 之 QDataStream 数据流类

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「QT」QT5程序设计&#x1f4da;全部专栏「Win」Windows程序设计「IDE」集成开发环境「UG/NX」BlockUI集合「C/C」C/C程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「UG/NX」NX定制…

QT<30> Qt中使鼠标变为转圈忙状态

前言&#xff1a;当我们在写软件时&#xff0c;在等待阻塞耗时操作时可以将鼠标变为忙状态&#xff0c;并在一段时间后恢复状态&#xff0c;可以用到GxtWaitCursor&#xff1a;Qt下基于RAII的鼠标等待光标类。 一、效果演示 二、详细代码 在项目中添加C文件&#xff0c;命名为…

Vue的基础使用

一、为什么要学习Vue 1.前端必备技能 2.岗位多&#xff0c;绝大互联网公司都在使用Vue 3.提高开发效率 4.高薪必备技能&#xff08;Vue2Vue3&#xff09; 二、什么是Vue 概念&#xff1a;Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套 构建用户界面 的 渐进式 框架…

数据结构Python版

2.3.3 双链表 双链表和链表一样&#xff0c;只不过每个节点有两个链接——一个指向后一个节点&#xff0c;一个指向前一个节点。此外&#xff0c;除了第一个节点&#xff0c;双链表还需要记录最后一个节点。 每个结点为DLinkNode类对象&#xff0c;包括存储元素的列表data、…

FBX福币交易所恒指收跌1.96% 半导体股继续回调

查查配分析11月14日电 周四,港股三大指数集体下跌。截至收盘,恒生指数跌1.96%,恒生科技指数跌3.08%,恒生中国企业指数跌2.21%。大市成交额1733亿港元。 FBX福币凭借用户友好的界面和对透明度的承诺,迅速在加密货币市场中崭露头角,成为广大用户信赖的平台。 来源:Wind 盘面上,科…

【学习日记】notebook添加JAVA支持

作者是个大学生 这个专栏主要收集课时常用的软件 以及女朋友上课用的软件的教程 新开了gitcode 用于上传安装包 环境说明 windows11 java23.0.1 ijava1.1.2 Anaconda-2024.02 需提前配置好java环境 本篇仅对添加支持进行说明 ijava的GitCode链接NotebookAddsSupportForJava:no…

RabbitMQ 篇-深入了解延迟消息、MQ 可靠性(生产者可靠性、MQ 可靠性、消费者可靠性)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 RabbitMQ 的可靠性 2.0 发送者的可靠性 2.1 生产者重试机制 2.2 生产者确认机制 2.2.1 开启生产者确认机制 2.2.2 定义 ReturnCallback 机制 2.2.3 定义 ConfirmC…

【数据结构】AVL树

引言&#xff1a;在实际情况中&#xff0c;数据不仅仅要存储起来&#xff0c;还要进行对数据进行搜索&#xff0c;为了方便进行高效搜索(在此之前的数据结构的搜索基本都是暴力搜索)二叉搜索树应运而生。但是在极端情况下(我们按照有序的方式进行插入)&#xff0c;二叉搜索树就…

CSS的综合应用例子(网页制作)

这是html的一些最基本内容的代码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <t…

MySQL查询某个数据库中特定表的空间占用大小

如果您也想要查询某个数据库中特定表的空间占用大小&#xff0c;包括数据和索引的大小&#xff0c;那么您可以使用以下SQL查询。这个查询将显示特定表在数据库中的数据大小、索引大小以及总大小。 SELECT table_name AS Table,ROUND(((data_length index_length) / 1024 / 10…

Towards Reasoning in Large Language Models: A Survey

文章目录 题目摘要引言什么是推理?走向大型语言模型中的推理测量大型语言模型中的推理发现与启示反思、讨论和未来方向 为什么要推理?结论题目 大型语言模型中的推理:一项调查 论文地址:https://arxiv.org/abs/2212.10403 项目地址: https://github.com/jeffhj/LM-reason…

进入未来城:第五周游戏指南

欢迎来到 Alpha 第 4 季第五周&#xff01; 走进霓虹闪烁的未来城街道&#xff0c;这是一座科技至上的赛博朋克大都市。鳞次栉比的摩天大楼熠熠生辉&#xff0c;拥挤的街道下则是阴森恐怖的地下世界。在这里&#xff0c;像激光鹰队长这样的超级战士正在巡逻&#xff0c;而 Ago…