懂个锤子Vue 项目工程化进阶⏫:

Vue项目工程化进阶⏫:

前言: 紧跟前文,目标学习Vue2.0——3.0: 懂个锤子Vue、WebPack5.0、WebPack高级进阶 涉及的技术栈…

当然既然学习框架的了,HTML+CSS+JS三件套必须的就不说了: JavaScript 快速入门

学习前置链接: 懂个锤子Vue 项目工程化

组件的样式冲突:

在 Vue 开发中,组件样式冲突是一个常见的问题: 为什么会发生组件样式冲突⁉️

我们都知道,组件是由:模板Template\脚本Script\样式Style 组成,每个组件都是有自己的三件套)

但,因为Vue在运行过程中,本质是将多个组件合并成一个:html文件

所以,多个组件样式,相互匹配就发生组件样式冲突:

在这里插入图片描述

解决样式冲突

Vue支持定义全局\局部样式:

默认情况: 组件中的样式会,全局生效 → 很容易造成多个组件之间的样式冲突问题,

  • 全局样式: 默认组件中的样式会作用到全局
  • 局部样式: 可以给组件加上 scoped 属性, 可以让样式只作用于当前组件

在这里插入图片描述

scoped原理

scoped可以让组件样式变成局部样式: 组件都应该有独立的样式

  • scoped: 给当前组件模板的所有元素,都会添加上一个自定义属性data-v-hash值
  • data-v-hash值:用于区分开不通的组件,渲染样式时css选择器 后面,被自动处理,添加上了属性选择器;

组件的 data函数:

在 Vue 组件中,data 函数的主要作用是为每个组件实例提供独立的数据对象:

  • 因为: 一个组件可能会使用多次, 如果通过原始属性定义,多个组件会依赖一个数据源;
  • 通过: date(函数){ return {} } return返回对象,确保每一个组件都是独立的数据源;

**访问组件实例: ** 在 data(){ //函数内部 } 你可以访问组件实例的其他属性和方法;

响应式系统: Vue响应式系统,会将 data 函数 返回的对象包裹起来,

并以 $data 的形式存储在组件实例;数据发生变化,自动更新视图;

<!-- 模板结构 -->
<template><div><P>A组件: 声明成功!</P><button @click="count--">-</button><span>{{ count }}</span><button @click="count++">+</button></div>
</template><!-- 脚本结构 -->
<script> export default {//原始定义:组件不支持\报错x)// data: {//     //基本数据类型使用//     count:1// },//组件函数式定义:data(){//因为: 一个组件可能会使用多次,如果通过原始属性,多个组件会依赖一个数据源;//通过: date(函数){ return {} } return返回对象,确保每一个组件都是独立的数据源;return {count:1}}}
</script><!-- 样式结构 -->
<!-- style中的样式,默认是作用到全局的scoped可以让样式变成局部样式,组件都应该有独立的样式,推荐scoped 原理)scoped给当前组件模板的所有元素,都会添加上一个自定义属性data-v-hash值 用于区分开不通的组件,css选择器后面,被自动处理,添加上了属性选择器;
-->
<style scoped>div{border: 3px solid red;margin: 30px;}
</style>

在这里插入图片描述

组件的通信📶

Vue.js 是一个基于组件的框架,应用通常由多个组件组成:

组件通信是指在 Vue.js 应用中,不同组件之间传递数据和消息的过程:

组件之间的数据是独立的,无法直接访问其他组件的数据,组件通信的主要目的是:

  • 数据共享:在父子组件之间或兄弟组件之间共享数据;
  • 事件传递:在组件之间传递事件,以响应用户操作或其他事件;

组件之间有哪些关系?

  • 父子关系: 一个组件包含另一个组件

    例如,组件A 包含组件B +组件C,那么 A 和 B、C 是父子关系;

  • 非父子关系: 也有开发者称为兄弟\隔代关系,同一个父组件下的多个子组件之间的关系;

    组件B组件C 都是组件A 的子组件,那么 B 和 C 是兄弟关系;

    组件A 包含组件B组件B 又包含组件D,那么 A 和 D 是隔代关系;

在这里插入图片描述

对应的组件通信方案有哪几类? 这里简单介绍,常用的几种;

  • Props 和 $emit:用于父子组件之间的通信;
  • provide 和 inject:用于祖先组件和后代组件之间的通信;
  • 事件总线(Event Bus):通过创建一个空的 Vue 实例作为中央事件总线,用它来触发和监听事件,实现任意组件间的通信;
  • Vuex:用于全局状态管理,适用于大型应用,通过 Vuex 的 store 来管理全局状态,实现组件间的通信;

父子组件通信:

父—>子通信:

Props 是父组件向子组件传递数据的机制,

父组件通过在子组件标签上绑定属性来传递数据,子组件通过声明 props 来接收这些数据;

在这里插入图片描述

  • Prop 定义\使用: 父组件在子组件上,注册的一些 自定义属性:<组件名 :属性名='传递值' ></组件名>
  • 子组件通过:props 获取父组件的数据,props:['属性名']props中的属性可以像data中数据一样使用;

props 详解\校验:

Props 作用: 向子组件传递数据,可以传递任意数量、可以传递任意类型

在这里插入图片描述

props 校验是确保传递给组件的数据符合预期的一种机制: 通过定义 props 的类型和验证规则,提高组件可靠性和可维护性;

'props': {'校验属性名1': '类型', 		// Number String Boolean ...'校验属性名2': {type: '类型', 			// Number String Boolean ...required: true, 	 	 // 是否必填default: '默认值', 	   // 默认值validator (value) {// 自定义校验逻辑return 是否通过校验;};}
},

在这里插入图片描述

data & props 区别:

在 Vue.js 中,propsdata 都是用于管理组件数据的重要机制,但它们有一些显著的区别:

  • data:用于组件内部管理数据,组件可以自由修改

  • props:用于父组件向子组件传递数据,子组件只能读取,不能修改

    单向数据流: 父级 props 的数据更新,会向下流动,影响子组件,这个数据流动是单向的

    父组件更新 props,子组件会接收到最新的数据,但子组件不能直接修改 props 的值,子组件修改值报错

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

检测到props 中数据修改报错,Vue直接抛出异常! 那么如何修改父组件的数据呢?

子—>父通信:

👆这就涉及到子——父 通信了,那么如何: 子—>父通信:

BaseCount.vue: 子组件通过调用 $emit 方法触发一个@自定义事件

并传递需要发送的数据:this.$emit('自定义事件名', 传递给父组件数据)

<!-- 模板结构 -->
<template><div class="base-count"><button @click="handleSub">-</button><span>{{ count }}</span><button @click="handleAdd">+</button></div>
</template>
<!-- 脚本结构 -->
<script>
export default {//子组件data数据data(){ return { dcount:0 } },props: {//props获取父组件数据;count: { type: Number, },},methods: {handleSub() {//子组件通过调用 $emit 方法触发一个自定义事件,并传递需要发送的数据this.$emit('changeCount', this.count - 1)},handleAdd() {this.$emit('changeCount', this.count + 1)},},
}
</script>
<!-- 样式结构 -->
<style></style>

App.vue: 父组件通过在:子组件标签上自定义监听事件,并绑定一个函数来接收处理数据;

<子组件 :属性名='传递值' @自定义监听事件="处理函数" >,当子组件调用:this.$emit('自定义事件名', 传递父组件数据)

父组件监听事件触发,并执行对应处理函数,函数内部可以获取子组件传递的数据: 处理函数(value){ //内部执行相应处理 }

<!-- 模板结构 -->
<template><div id="app" style="border: 3px solid #000; margin: 10px">App 父组件<!-- 加减组件 --><!-- 父组件通过在子组件标签上监听自定义事件,并绑定一个触发函数 --><BaseCount :count="count" @changeCount="handleChange" ></BaseCount></div>
</template><!-- 脚本结构 -->
<script>
import BaseCount from './components/BaseCount.vue'
export default {name: 'App',data(){ return { count:1, } },components: {BaseCount},methods:{handleChange(newVal){//函数获取: 子组件传递的数据,给其赋值count;this.count = newVal;}}
}
</script>
<!-- 样式结构 -->
<style></style>

在这里插入图片描述

  1. 用户点击:+\- 触发对应的子组件函数,
  2. 子组件函数内部执行:this.$emit('父组件自定义监听函数',传递值) 给父组件传递修改后的值;
  3. 父组件,事先定义子组件时: 设置,自定义监听函数,并绑定对应处理函数;
  4. 父组件,监听@自定义函数执行,并触发函数
  5. 获取子组件传递最新值,重新赋值: count
  6. 子组件页面同步数据更新;

非父子组件通信:

event bus 事件总线

在 Vue.js 中,事件总线(Event Bus)是一种用于实现非父子组件之间通信的机制

它允许我们在 Vue 应用中 创建一个全局的事件中心 ,组件通过该 事件中心来:发送\接收事件 ,实现数据的传递和共享

创建事件总线:

首先,我们需要创建一个事件总线:

  • 通常是在主文件如 main.js,中创建一个新的 Vue 实例,并将其挂载到 Vue 的原型上,以便所有组件都可以访问;
  • 还有另一种方式是直接在组件中创建和使用事件总线, 这种方法适用于局部通信需求,不需要全局事件总线;
//全局工具包
//utils/EventBus.js
import Vue from 'vue';
const EventBus = new Vue();
export default EventBus;       	//对外暴漏公共实例;	//main.js
//const EventBus = new Vue();
//Vue.prototype.$bus = EventBus;
//将一个新的 Vue 实例即EventBus)挂载到Vue的原型上,并命名为 $bus
//这样,所有的 Vue 组件都可以通过 this.$bus 访问这个事件总线;

发送事件:

在需要发送事件的组件中,通过 实例.$emit 方法发送事件,并传递数据;

<template><div class="base-b"><div>我是B组件(发布方)</div><button @click="sendMsgFn">发送消息1</button><button @click="sendMsgFn2">发送消息2</button></div>
</template><script>
//引入局部事件总线
import Bus from '../utils/EventBus'
export default {methods: {//通过 `$bus.$emit` 方法发送事件,并传递数据;sendMsgFn() { Bus.$emit('sendMsg', '引入局部事件总线') },sendMsgFn2() { this.$bus.$emit('sendMsg2', 'this.$Bus全局事件总线') },},
}
</script>
<style scoped><!-- 省略Css样式 --></style>	

监听事件:

在需要接收事件的组件中,通过 $bus.$on 方法监听事件,并处理接收到的数据;

<template><div class="base-a">我是A组件(接受方)<p>{{msg}}</p>  </div>
</template><script>
import Bus from '../utils/EventBus'
export default {data() { return { msg: '', } },created() {Bus.$on('sendMsg', (msg) => { this.msg = msg });		//接受局部事件总线消息this.$bus.$on('sendMsg2', (msg) => { this.msg = msg });	//接受全局事件总线消息},
}
</script>
<style scoped><!-- 省略Css样式 --></style>	

在这里插入图片描述

注意事项

事件移除:在组件销毁前,应该移除事件监听,以避免内存泄漏和重复监听,

全局事件总线: 虽然事件总线使用方便,但在大型应用中可能会导致难以维护的“灾难”,

因此需要谨慎使用,对于复杂的状态管理,推荐使用 Vuex:

provide & inject 跨层级共享数据

在 Vue.js 中,provideinject 是一种高级的数据传递机制:

主要用于解决组件树中深层组件间通信的问题,特别是当不直接存在父子关系时

它们允许父组件提供一个值,而任何后代组件都可以通过 inject 来接收这个值;如:上图D—A的隔代通信;

根组件发送消息:

父组件使用 provide 提供数据: 父组件通过 provide(){ return { 发送数据 } } 选项将数据提供给子组件及其后代组件;

<template><div id="app" style="border: 3px solid #000; margin: 10px">App 父组件<Son3></Son3></div>
</template><script>
import Son3 from './components/Son3.vue';
export default {name: 'App',components: { Son3, },data() { return { color: 'pink', userInfo: { name: 'zs', age: 18, }, } },//父组件使用 provide 提供数据:provide() {return {// 简单类型是非响应式的color: this.color,// 复杂类型 是响应式的userInfo: this.userInfo,}},
}
</script>

后代组件接受消息:

子组件使用 inject 接收数据: 子组件通过 inject: ['匹配数据名', '匹配数据名','...'] 选项注入这些数据;

<template><div class="grandSon">我是GrandSon{{ color }} -{{ userInfo.name }} -{{ userInfo.age }}</div>
</template><script>
export default {//子组件使用 inject 接收数据:inject: ['color', 'userInfo'],
}
</script>

在这里插入图片描述

响应式数据、问题:

需要注意的是,provide 提供的简单类型数据(如字符串、数字)是非响应式的,

而复杂类型数据(如对象、数组)是响应式的,这意味着子组件可以监听到复杂类型数据的变化;

版本管理:

本代码已经使用Git进行管理: 公众号回复:Vue项目工程化

在这里插入图片描述

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

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

相关文章

react中如何mock数据

1.需求说明 因为前后端分离开发项目&#xff0c;就会存在前端静态页面写好了&#xff0c;后端数据接口还没写好&#xff1b;这时候前端就需要自己定义数据来使用。 定义数据有三种方式&#xff1a;直接写死数据、使用mock软件、json-server工具 这里讲解通过json-server工具…

面向对象程序设计(C++)模版初阶

1. 函数模版 1.1 函数模版概念 函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&#xff0c;根据实参类型产生函数的特定类型版本&#xff0c;可以类比函数参数&#xff0c;函数模版就是将函数参数替换为特定类型版本 1.2 函数模版格…

基于ant-design-vue3多功能操作表格,表头序号为动态添加记录按钮,鼠标在表格记录行,当前行序号显示删除按钮

由于项目需要&#xff0c;并考虑到尽可能让空间利用率高&#xff0c;因此定制开发一个表格组件&#xff0c;组件功能主要是在序号表头位置为添加按钮&#xff0c;点击按钮&#xff0c;新增一行表格数据&#xff1b;表格数据删除不同于以往表格在操作栏定义删除按钮&#xff0c;…

问题解决|如何优雅展示层级或关联数据?

一、8种可用图表类型及配套教程 &#xff08;一&#xff09;包珠图 &#xff08;1&#xff09;功能介绍 包珠图&#xff08;Circular Packing&#xff09;&#xff0c;是一类较特殊的分类树状图&#xff0c;以气泡之间的包含关系展示层级关系&#xff0c;以气泡面积&#xf…

Spring事件机制

文章目录 一、Spring事件二、实现Spring事件1、自定义事件2、事件监听器2.1 实现ApplicationListener接口2.2 EventListener2.3 TransactionalEventListener 3、事件发布4、异步使用 三、EventBus1、事件模式2、EventBus三要素3、同步事件3.1 定义事件类3.2 定义事件监听3.3 测…

解析西门子PLC的String和WString

西门子PLC有两种字符串类型&#xff0c;String与WString String 用于存放英文数字标点符号等ASCII字符&#xff0c;每个字符占用一个字节 WString宽字符串用于存放中文、英文、数字等Unicode字符&#xff0c;每个字符占用两个字节 之前我搞过一篇解析String的 关于使用TCP-…

Kotlin 的优势:现代编程语言的卓越选择

文章目录 简洁与优雅的语法空安全特性函数式编程&#xff0c;支持高阶函数、lambdaKotlin 内联函数与 Java 的互操作性强大的类型推断协程支持lazy 委托object 单例模式区间表达式现代的开发工具支持 本文首发地址 https://h89.cn/archives/301.html 最新更新地址 https://gite…

包装类和泛型

&#x1f389;欢迎大家收看&#xff0c;请多多支持&#x1f339; &#x1f970;关注小哇&#xff0c;和我一起成长&#x1f680;个人主页&#x1f680; 包装类&#x1f319; Java中每个基本数据类型都对应了一个包装类&#xff0c; 除了int的包装类是Integer&#xff0c;char…

微信小程序开发 快速学习 这篇就够了

目录 一、配置篇 &#xff08;1&#xff09;官网链接&#xff1a; &#xff08;2&#xff09;项目分析 &#xff08;3&#xff09;调试器 &#xff08;4&#xff09;预览体验 &#xff08;5&#xff09;配置文件 &#xff08;6&#xff09;配置pages &#xff08;7&…

【开发问题记录】启动某个微服务时无法连接到seata(seata启动或配置异常)

问题记录 一、问题描述1.1 问题复现1.1.1 将Linux中的部分微服务启动1.1.2 在本地启动当时出错的服务 1.2 解决思路1.2.1 Nacos中seata相关的信息1.2.2 Linux中seata相关的信息 二、问题解决2.1 seata的配置错误2.1.1 Nacos中seata的配置问题2.1.2 命名空间问题的发现 2.2 网络…

Matlab编程资源库(10)离散傅立叶变换

一、离散傅立叶变换算法简要 给定一个N点的离散信号序列x(n)&#xff0c;其中n表示时刻&#xff0c;n 0, 1, 2, ..., N-1。 定义离散傅立叶变换的频域序列X(k)&#xff0c;其中k表示频率&#xff0c;k 0, 1, 2, ..., N-1。 通过以下公式计算每个频率对应的复数值&#xff…

生鲜云订单零售系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商品分类管理&#xff0c;商品信息管理&#xff0c;订单评价管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品信息&#…

[Unity] ShaderGraph实现镜头加速线/残血效果 URP

效果如下所示&#xff1a;残血状态时&#xff0c;画面会压暗角&#xff0c;并出现速度线营造紧迫感。 使用到的素材如下&#xff0c;换别的当然也可以。[这是张白色的png放射图&#xff0c;并非皇帝的新图hhh] 这个效果的实现逻辑&#xff0c;其实就是利用time向圆心做透明度的…

2024经济师考试报名『注册流程』图解!

⏰报名时间&#xff1a;8月12日—9月11日 ☑️报名注册流程 1、经济师考试报名注册网站&#xff1a;中国人事考试网. 2、点击考生登录栏目中的【新用户注册】按钮&#xff0c;进行注册。 3、进入用户注册界面&#xff0c;填写注册信息。 4、填写完毕确认无误后点击【提交】&…

Unity UGUI 之 Mask

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本&#xff0c;请注意分别 1.什么是遮罩 遮罩是一…

深度解读大语言模型中的Transformer架构

一、Transformer的诞生背景 传统的循环神经网络&#xff08;RNN&#xff09;和长短期记忆网络&#xff08;LSTM&#xff09;在处理自然语言时存在诸多局限性。RNN 由于其递归的结构&#xff0c;在处理长序列时容易出现梯度消失和梯度爆炸的问题。这导致模型难以捕捉长距离的依…

学习react-登录状态验证

1.创建三个页面LoginPage, HomePage,NotFoundPage用于Router 创建LoginPage.tsx用于做登录页面 // LoginPage.tsx const LoginPage (props:LoginProp) > {const navigate useNavigate();return( <h1 onClick{ ()>{navigate("/");}}>Hello Login, {pr…

02 Go语言操作MySQL基础教程_20240729 课程笔记

概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728 基础不好的同学每节课的代码最好配合视频进行阅读和学习&#xff0c;如果基础比较扎实&#xff0c;则阅读本教程巩固一下相…

微信小游戏之 三消(一)

首先设定一下 单个 方块 cell 类&#xff1a; 类定义和属性 init 方法 用于初始化方块&#xff0c;接收游戏实例、数据、宽度、道具类型和位置。 onWarning 方法 设置警告精灵的帧&#xff0c;并播放闪烁动作&#xff0c;用于显示方块的警告状态。 grow 方法 根据传入的方向…

21.发布确认模式-高级

问题 生产环境中由于一些不明原因&#xff0c;导致rabbitmq重启&#xff0c;在重启的期间生产者消息投递失败&#xff0c;导致消息丢失&#xff0c;需要手动处理恢复。那么如何才能进行rabbitmq的消息可靠性投递&#xff1f;特别是在极端的情况&#xff0c;rabbitmq集群不可用…