4.从零开始学会Vue--{{组件通信}}

embedded/2025/2/21 8:44:46/

1.组件的注意点


1.template只能有一个根元素

约束:.vue文件中的template中如果写了两个元素,则会报如下错误


解决:保证template中只有一个根元素即可


2.scoped解决样式冲突

1全局样式: 默认组件中的样式会作用到全局,任何一个组件中都会受到此样式的影响
2局部样式: 可以给组件加上scoped 属性,可以让样式只作用于当前组件
默认情况:写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。


解决:在组件style标签上增加scoped来解决

scoped原理
1当前组件内标签都被添加data-v-hash值 的属性 ,每个组件的hash值是不同的
2css选择器都被添加 [data-v-hash值] 的属性选择器
最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到


3.data必须是一个函数

一个.vue组件的 data 选项必须是一个函数。否则会报错


这么要求的原因:保证每个组件实例,维护独立的一份数据对象,保证组件实例之间的数据相互隔离不受影响
每次创建新的组件实例,都会新执行一次data 函数,得到一个新对象。

2.组件通信

1.父子之间通信

1.用法

父向子传值步骤:

  1. 准备一个父组件 App.vue,一个子组件Son.vue
  2. 在App.vue中使用Son.vue让它们构成一个父子组件关系,在使用子组件的同时
    1. 通过 :自定义名字="需要传递的值" 将父组件中的数据传给子组件
  1. 子组件内部通过props接收 props:['父组件中自定义名字']
  2. 子组件内部模板中直接使用 props接收的值 {{ 父组件中自定义名字 }}

✨✨ 注意点:父组件中的响应式数据改变,会自动同步到子组件

子组件利用 $emit 将自己的数据传递给父组件

子向父传值步骤:

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

注意:上面代码其实是一个 父子通信的双向数据绑定

2.props校验

思考:组件的props数据类型可以乱传吗?不能

  • 比如进度条百分数只能是数字

props校验:为组件的 prop 指定验证要求,不符合要求,控制台就会有错误提示 → 帮助开发者,快速发现错误

props校验的类型:

  • 类型校验(常用)
  • 非空校验
  • 默认值
  • 自定义校验

语法:

① 只校验类型【常用】

② 完整写法

// ✨✨✨注意点:属性的类型必须使用大写 Number,Boolean,String,Array,Object

  1. default和required一般不同时写(因为当时必填项时,肯定是有值的)
  2. default后面如果是简单类型的值,可以直接写默认。如果是复杂类型的值,则需要以函数的形式return一个默认值

3.props与data

共同点:一个组件中props和data,都可以给组件提供数据

区别:

  • data 的数据是自己的 → 随便改
  • prop 的数据是外部的 → 不能直接改,要遵循 单向数据流

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

特点:子组件修改prop数据不会影响到父组件的数据

约定:谁的数据,谁负责修改

2.跨层级通信

1.事件总线-EventBus(传递事件)

作用:事件总线event bus可以用在非父子组件之间,进行简易消息传递 (复杂场景→ Vuex)

需求:B组件向C组件进行传递数据

使用步骤:(媒婆传话)

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

  1. C 组件(接收方),监听 Bus 实例的事件

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

2.provide与inject(传递数据)

作用:provide&inject可以实现组件的跨层级共享数据

provide&inject传递数据使用步骤:

  1. 父组件 provide 提供数据

  1. 子/孙组件 inject 取值使用

注意:

  1. provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式。(推荐提供复杂类型数据)
  2. 子/孙组件通过inject获取的数据,不能在自身组件内修改

3.v-model原理

思考:默认情况下我们可以给组件用上 v-model进行双向数据绑定吗? 不能 -> 那么如何做?

解决方法:

  1. 用vue实现 v-model 的写法(原理)
  2. v-bind:属性.sync 修饰符

1.v-model

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

作用:v-model是双向数据绑定

① 数据变,视图跟着变 :value

② 视图变,数据跟着变 @input

说明:$event 用于在模板中,获取事件的形参 (这里的$event就是事件对象e)

说明:

不同的表单元素, v-model在底层的处理机制不一样。

  • 给文本框,文本域 -> Vue框架底层是拆解成 value属性 + input事件来实现
  • 下拉框 -> Vue框架底层是拆解成 value属性 + change事件来实现
  • 给复选框,单选框 使用v-model ->Vue框架底层是拆解成 checked属性和change事件 来实现

javascript"><template><div id="main"><input type="text" v-model="value1" />{{ value1 }}<hr /><input type="text" :value="value2" @input="value2 = $event.target.value" />{{ value2 }}<hr /><MyTable v-model="value3"></MyTable></div>
</template><script>
import MyTable from "./components/MyTable.vue";export default {components: {MyTable,},data() {return {value1: "",value2: "",value3: "",};},
};
</script><style>
</style>
javascript"><template><div class="box"><input type="text" @input="change" />{{ value }}</div>
</template><script>
export default {props: {value: {type: String,},},methods: {change(e) {this.$emit("input", e.target.value);},},
};
</script><style  scoped>
.box {width: 200px;height: 200px;border: 1px solid pink;
}
</style>

2.sync修饰符

作用:可以实现 子组件 与 父组件数据 的 双向绑定

.sync修饰符原理: :属性名@update:属性名 的合写

本质上和v-model是一样的,也是一个父子组件通信的情况

3.ref与$refs

作用:利用 ref 和 $refs 可以用于 获取 dom 元素, 或 组件实例

ref和$refs特点:查找范围 → 当前组件内 (更精确稳定)

语法:

4.Vue异步更新 & $nextTick

Vue的异步更新特性

javascript"><template><div class="app"><span ref="span">{{ num }}</span><button @click="addone">+1</button></div>
</template><script>
export default {data() {return {num: 1,};},methods: {addone() {this.num++;this.num++;console.log(this.num);//打印3console.log(this.$refs.span.innerHTML)  //❌还是拿到上一次的值1},},
};
</script><style>
</style>

Vue 在更新 DOM 时是异步执行的(异步渲染)

  • 只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更
  • 如果同一个 watcher 被多次触发,只会被推入到队列中一次。
  • 在下一个的事件循环中(nextTick),Vue 刷新队列并执行实际 (已去重的) 任务(先进先执行)

上面代码中,当num的值改变时,由于dom更新是异步的,所以通过

this.$refs.span.innerHTML拿到的结果是不准确的。

如何解决?使用 $nextTick

$nextTick

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

语法:

  1. 回调函数写法: this.$nextTick(()=>{ })
  2. Promise写法: this.$nextTick().then(res=>{ })


http://www.ppmy.cn/embedded/164026.html

相关文章

Python 高级特性-切片

目录 切片 练习 小结 掌握了Python的数据类型、语句和函数&#xff0c;基本上就可以编写出很多有用的程序了。 比如构造一个1, 3, 5, 7, ..., 99的列表&#xff0c;可以通过循环实现&#xff1a; L [] n 1 while n < 99:L.append(n)n n 2 取list的前一半的元素&am…

pdf转换成word在线 简单好用 支持批量转换 效率高 100%还原

pdf转换成word在线 简单好用 支持批量转换 效率高 100%还原 在数字化办公的浪潮中&#xff0c;文档格式转换常常让人头疼不已&#xff0c;尤其是 PDF 转 Word 的需求极为常见。PDF 格式虽然方便阅读和传输&#xff0c;但难以编辑&#xff0c;而 Word 格式却能灵活地进行内容修…

Flask 发送邮件

下载 pip install flask-mail config.py MAIL_SERVER "smtp.qq.com" MAIL_USE_SSL True MAIL_PORT 465 MAIL_USERNAME "xxxxqq.com" MAIL_PASSWORD "xxxxx" MAIL_DEFAULT_SENDER "xxxxqq.com" 引入flask_mail exts.py fro…

LLM论文笔记 15: Transformers Can Achieve Length Generalization But Not Robustly

Arxiv日期&#xff1a;2024.2.14机构&#xff1a;Google DeepMind / University of Toronto 关键词 长度泛化位置编码数据格式 核心结论 1. 实验结论&#xff1a;十进制加法任务上的长度泛化最佳组合&#xff1a; FIRE位置编码 随机化位置编码 反向数据格式 索引提示&…

MySQL(1)基础篇

执行一条 select 语句&#xff0c;期间发生了什么&#xff1f; | 小林coding 目录 1、连接MySQL服务器 2、查询缓存 3、解析SQL语句 4、执行SQL语句 5、MySQL一行记录的存储结构 Server 层负责建立连接、分析和执行 SQL存储引擎层负责数据的存储和提取。支持InnoDB、MyIS…

前端编程基础开发规范

文章目录 项目创建目录结构 命名规范文件命名通用规则不同类型文件命名&#xff1a; 代码命名规范通用规范 代码规范HTML代码规范标签闭合标签语义化标签嵌套规则属性引号布尔属性注释规范避免内联样式和脚本减少不必要的标签和属性 CSS代码规范注释代码格式化 选择器规范1. 命…

代码随想录算法训练day59---图论系列4

代码随想录算法训练 —day59 文章目录 代码随想录算法训练前言一、110.字符串接龙二、105.有向图的完全可达性dfs版本1dfs版本2bfs版本 三、100. 岛屿的最大面积方法一方法二 总结 前言 今天是算法营的第59天&#xff0c;希望自己能够坚持下来&#xff01; 今天继续图论part&…

《95015网络安全应急响应分析报告(2024)》

2025年2月&#xff0c;95015服务平台发布了最新一期的《95015网络安全应急响应分析报告&#xff08;2024&#xff09;》。报告分别从整体形势、受害者特征、攻击者特征等方面&#xff0c;对2024年95015平台接报的739起网络安全应急响应事件展开分析&#xff0c;并给出了7个年度…