vue重修004上部
文章目录
- 版权声明
- 组件的三大组成部分
- scoped解决样式冲突
- scoped原理
- 2.代码演示
- 组件data函数
- 说明
- 演示
- 组件通信
- 组件关系分类
- 通信解决方案
- 父子通信流程
- 子向父通信代
- props详解
- props校验
- props&data、单向数据流
- 小黑记事本(组件版)
- 基础组件结构
- 需求和实现思路
- 完整代码
- App.vue
- TodoHeader.vue
- TodoBody.vue
- TodoFoot.vue
版权声明
- 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明,所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用,并非商业用途。
- 我在整理学习笔记的过程中尽力确保准确性,但无法保证内容的完整性和时效性。本博客的内容可能会随着时间的推移而过时或需要更新。
- 若您是黑马程序员或相关权利人,如有任何侵犯版权的地方,请您及时联系我,我将立即予以删除或进行必要的修改。
- 对于其他读者,请在阅读本博客内容时保持遵守相关法律法规和道德准则,谨慎参考,并自行承担因此产生的风险和责任。本博客中的部分观点和意见仅代表我个人,不代表黑马程序员的立场。
组件的三大组成部分
- 结构、样式、逻辑

scoped解决样式冲突
- 默认情况:写在组件中的样式会 全局生效,很容易造成多个组件之间的样式冲突问题。
- 全局样式: 默认组件中的样式会作用到全局,任何一个组件中都会受到此样式的影响
- 局部样式: 可以给组件加上scoped 属性,可以让样式只作用于当前组件
scoped原理
- 当前组件内标签都被添加data-v-hash值 的属性
- css选择器都被添加 [data-v-hash值] 的属性选择器
- 最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到

2.代码演示
- BaseOne.vue
<template><div class="base-one">BaseOne</div>
</template><script>
export default {}
</script><style scoped>
/* 1.style中的样式 默认是作用到全局的2.加上scoped可以让样式变成局部样式组件都应该有独立的样式,推荐加scoped(原理)-----------------------------------------------------scoped原理:1.给当前组件模板的所有元素,都会添加上一个自定义属性data-v-hash值data-v-5f6a9d56 用于区分开不通的组件2.css选择器后面,被自动处理,添加上了属性选择器div[data-v-5f6a9d56]
*/
div{border: 3px solid blue;margin: 30px;
}
</style>
- BaseTwo.vue
<template><div class="base-one">BaseTwo</div>
</template><script>
export default {}
</script><style scoped>div{border: 3px solid red;margin: 30px;}
</style>
- App.vue
<template><div id="app"><BaseOne></BaseOne><BaseTwo></BaseTwo></div>
</template><script>
import BaseOne from './components/BaseOne'
import BaseTwo from './components/BaseTwo'
export default {name: 'App',components: {BaseOne,BaseTwo}
}
</script>
组件data函数
说明
- 在之前的基础阶段的练习中,data使用的是对象的写法,这是因为方便基础练习,全局只有唯一一个data对象
- data对象写法
Vue.component('my-component', {data: {message: 'Hello, Vue!'},template: '<div>{{ message }}</div>'
})
- data函数写法
Vue.component('my-component', {data: function () {return {count: 0}},template: '<div>{{ count }}</div>'
})
- 在Vue.js中,一个组件的data选项必须是一个函数,而不是一个对象。为了确保每个组件实例都能维护独立的数据对象,避免数据共享和潜在的问题。
- 每次创建一个新的组件实例时,Vue会调用这个函数来返回一个新的数据对象,以保证实例之间的数据隔离。

Vue.component('my-component', {data() {return {message: 'Hello, Vue!'}},template: '<div>{{ message }}</div>'
})
演示
- BaseCount.vue
<template><div class="base-count"><button @click="count--">-</button><span>{{ count }}</span><button @click="count++">+</button></div> </template><script> export default {data: function () {return {count: 100,}}, } </script><style> .base-count {margin: 20px; } </style> - App.vue
<template><div class="app"><baseCount></baseCount><baseCount></baseCount><baseCount></baseCount></div>
</template><script>
import baseCount from './components/BaseCount'
export default {components: {baseCount,},
}
</script>
<style>
</style>
组件通信
- 组件通信,就是指组件与组件之间的数据传递
- 组件的数据是独立的,无法直接访问其他组件的数据。想使用其他组件的数据,就需要组件通信

组件关系分类

通信解决方案

父子通信流程
- 父组件通过 props 将数据传递给子组件
- 子组件利用 $emit 通知父组件修改更新
-
原因:再vue设定中数据是有属主的,只有创建数据其的属主组件可以修改该数据

-
父向子传值步骤:
- 给子组件以添加属性的方式传值
- 子组件内部通过props接收
- 模板中直接使用 props接收的值

- 父组件代码
<template><div class="app" style="border: 3px solid #000; margin: 10px">我是APP组件<!-- 1.给组件标签,添加属性方式 赋值 --><Son :title="myTitle"></Son></div>
</template><script>
import Son from './components/Son.vue'
export default {name: 'App',data() {return {myTitle: '学前端',}},components: {Son,},
}
</script><style>
</style>
- 子组件代码
<template><div class="son" style="border:3px solid #000;margin:10px"><!-- 3.直接使用props的值 -->我是Son组件 {{title}}</div>
</template><script>
export default {name: 'Son-Child',// 2.通过props来接受props:['title']
}
</script><style></style>
子向父通信代
-
子组件利用 $emit 通知父组件,进行修改更新
-
子向父传值步骤
- $emit触发事件,给父组件发送消息通知
- 父组件监听$emit触发的事件
- 提供处理函数,在函数的形参中获取传过来的参数

- 子组件代码
<template><div class="son" style="border: 3px solid #000; margin: 10px">我是Son组件 {{ title }}<button @click="changeFn">修改title</button></div>
</template><script>
export default {name: 'Son-Child',props: ['title'],methods: {changeFn() {// 通过this.$emit() 向父组件发送通知this.$emit('changTitle','son')},},
}
</script><style>
</style>
- 父组件代码
<template><div class="app" style="border: 3px solid #000; margin: 10px">我是APP组件<!-- 2.父组件对子组件的消息进行监听 --><Son :title="myTitle" @changTitle="handleChange"></Son></div>
</template><script>
import Son from './components/Son.vue'
export default {name: 'App',data() {return {myTitle: 'father',}},components: {Son,},methods: {// 3.提供处理函数,提供逻辑handleChange(newTitle) {this.myTitle = newTitle},},
}
</script><style>
</style>
props详解
- 在Vue.js中,props(属性)是一种用于从父组件向子组件传递数据的机制。
- props 定义:组件上 注册的一些 自定义属性
- props 作用:向子组件传递数据
- 特点
- 可以 传递 任意数量 的prop
- 可以 传递 任意类型 的prop

props校验
- 作用:为组件的 prop 指定验证要求,不符合要求,控制台就会有错误提示 → 帮助开发者,快速发现错误
- 语法:
① 类型校验
② 非空校验
③ 默认值
④ 自定义校验 - 基础写法:

- 完整写法

- default和required一般不同时写(因为当时必填项时,肯定是有值的)
- default后面如果是简单类型的值,可以直接写默认。如果是复杂类型的值,则需要以函数的形式return一个默认值
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}},},}
props&data、单向数据流
-
共同点:都可以给组件提供数据
-
区别
- data 的数据是自己的 → 随便改
- prop 的数据是外部的 → 不能直接改,要遵循 单向数据流
-
单向数据流:父级props 的数据更新,会向下流动,影响子组件。这个数据流动是单向的

-
父组件代码
<template><div class="app"><BaseCount :count="count" @changeCount="handleChange"></BaseCount></div>
</template><script>
import BaseCount from './components/BaseCount.vue'
export default {components:{BaseCount},data(){return {count:100}},methods:{handleChange(newVal){this.count = newVal}}
}
</script><style></style>
- 子组件代码
<template><div class="base-count"><button @click="handleSub">-</button><span>{{ count }}</span><button @click="handleAdd">+</button></div>
</template><script>
export default {props: {count: {type: Number,},},methods: {handleSub() {this.$emit('changeCount', this.count - 1)},handleAdd() {this.$emit('changeCount', this.count + 1)},},
}
</script><style>
.base-count {margin: 20px;
}
</style>
小黑记事本(组件版)
基础组件结构

需求和实现思路
需求说明:
① 拆分基础组件
② 渲染待办任务
③ 添加任务
④ 删除任务
⑤ 底部合计 和 清空功能
⑥ 持久化存储
- 列表渲染思路分析:
- 提供数据:提供在公共的父组件 App.vue
- 通过父传子,将数据传递给TodoMain
- 利用v-for进行渲染
- 添加功能思路分析:
- 收集表单数据 v-model
- 监听时间 (回车+点击 都要进行添加)
- 子传父,将任务名称传递给父组件App.vue
- 父组件接受到数据后 进行添加 unshift(自己的数据自己负责)
- 删除功能思路分析:
- 监听时间(监听删除的点击)携带id
- 子传父,将删除的id传递给父组件App.vue
- 进行删除 filter (自己的数据自己负责)
- 底部功能及持久化存储思路分析:
- 底部合计:父组件传递list到底部组件 —>展示合计
- 清空功能:监听事件 —> 子组件通知父组件 —>父组件清空
- 持久化存储:watch监听数据变化,持久化到本地
完整代码
App.vue
<template><!-- 主体区域 --><section id="app"><TodoHeader @add="handleAdd"></TodoHeader><TodoBody :list="list" @del="handleDel"></TodoBody><TodoFoot :len="list.length" @clear="handleClear"></TodoFoot></section>
</template><script>
import TodoHeader from "@/components/TodoHeader";
import TodoBody from "@/components/TodoBody";
import TodoFoot from "@/components/TodoFoot";// 渲染功能:
// 1.提供数据: 提供在公共的父组件 App.vue
// 2.通过父传子,将数据传递给TodoMain
// 3.利用 v-for渲染// 添加功能:
// 1.手机表单数据 v-model
// 2.监听事件(回车+点击都要添加)
// 3.子传父,讲任务名称传递给父组件 App.vue
// 4.进行添加 unshift(自己的数据自己负责)
// 5.清空文本框输入的内容
// 6.对输入的空数据 进行判断// 删除功能
// 1.监听事件(监听删除的点击) 携带id
// 2.子传父,讲删除的id传递给父组件的App.vue
// 3.进行删除filter(自己的数据 自己负责)// 底部合计:父传子 传list.length 渲染
// 清空功能:子传父 通知父组件 → 父组件进行更新
// 持久化存储:watch深度监视list的变化 -> 往本地存储 ->进入页面优先读取本地数据export default {components:{TodoHeader,TodoBody,TodoFoot},data () {return {//优先从本地存储读取list: JSON.parse(localStorage.getItem('list')) || [{id:1, name: "干饭"},{id:2, name: "干饭"},{id:3, name: "干饭"}]}},methods:{handleAdd(newVal) {//console.log(newVal)this.list.unshift({id: +new Date(),name: newVal})},handleDel(id) {this.list=this.list.filter(item=> item.id!==id)},handleClear() {this.list=[]}},watch:{list:{deep: true,handle(newValue) {localStorage.setItem('list',JSON.stringify(newValue))}}}
}
</script><style></style>
TodoHeader.vue
<template><!-- 输入框 --><header class="header"><h1>小黑记事本</h1><input placeholder="请输入任务" class="new-todo" v-model="todoname" @keyup.enter="handleAdd"/><button class="add" @click="handleAdd">添加任务</button></header></template><script>
export default {name: "TodoHeader",data() {return{todoname: ''}},methods:{handleAdd() {if(this.todoname.trim()===''){alert("任务名称为空")return}this.$emit("add",this.todoname)this.todoname=''}}
}</script><style scoped></style>
TodoBody.vue
<template><!-- 列表区域 --><section class="main"><ul v-for="(item,index) in list" :key="item.id" class="todo-list"><li class="todo"><div class="view"><span class="index">{{index+1}}.</span> <label>{{item.name}}</label><button class="destroy" @click="handeleDel(item.id)"></button></div></li></ul></section>
</template><script>
export default {name: "TodoBody",props: {list: {type: Array}},methods:{handeleDel(id) {this.$emit('del',id)}}
}
</script><style scoped></style>
TodoFoot.vue
<template><!-- 统计和清空 --><footer class="footer"><!-- 统计 --><span class="todo-count">合 计:<strong> {{len}} </strong></span><!-- 清空 --><button class="clear-completed" @click="clear">清空任务</button></footer></template><script>
export default {name: "TodoFoot",props:{len: Number},methods:{clear() {this.$emit('clear')}}
}
</script><style scoped></style>相关文章:
vue重修004上部
文章目录 版权声明组件的三大组成部分scoped解决样式冲突scoped原理2.代码演示 组件data函数说明演示 组件通信组件关系分类通信解决方案父子通信流程子向父通信代 props详解props校验props&data、单向数据流 小黑记事本(组件版)基础组件结构需求和实…...
【C++ techniques】要求/禁止/判断—对象产生于堆中
有时候我们想让某种对象具有“自杀”的能力,所以我们必须要求对象存在堆中,以便我们调用delete this;另一些时候,我们要求拥有某种确定性,保证某一些类型绝不会发生内存泄漏,原因是没有任何一个该类型的对象…...
吃鸡高手亲授:玩转绝地求生,分享顶级游戏干货!
绝地求生(PUBG)自上线以来,成为了全球热门游戏。作为吃鸡行家,我将分享一些独家技巧和干货,帮助您提高游戏战斗力,享受顶级游戏作战体验! 首先,让我们谈一谈战斗力升级。想要在吃鸡游…...
Vue中如何进行自定义图表与可视化图形设计
Vue中如何进行自定义图表与可视化图形设计 在现代Web应用程序开发中,数据可视化图表和图形设计是至关重要的一部分。Vue.js是一个流行的JavaScript框架,它提供了强大的工具来构建交互性强大的用户界面。本文将探讨如何在Vue.js中进行自定义图表和可视化…...
学信息系统项目管理师第4版系列19_质量管理
1. 公差 1.1. 质量测量中公差是测量指标的可允许变动范围,而不是实际测量值与预期值的差 1.1.1. 【高22下选35】 1.2. 结果的的可接受范围 2. 控制界限 2.1. 统计意义上稳定的过程或过程绩效的普通偏差的边界 3. 3版 3.1. 质量控制新七工具 3.1.1. 【高19下…...
react库的基础学习
React介绍 React.js是前端三大新框架:Angular.js、React.js、Vue.js之一,这三大新框架的很多理念是相同的,但是也有各自的特点。 React起源于Facebook的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满…...
FFmpeg 基础模块:容器相关的 API 操作
目录 AVFormat 模块 AVFormat 前处理部分 AVFormat 读写处理部分 小结 思考 FFmpeg 目录中包含了 FFmpeg 库代码目录、构建工程目录、自测子系统目录等,具体内容如下: 现在你知道 FFmpeg 的源代码目录中都包含了哪些内容,在之后使用 FFm…...
SpringMVC+统一表现层返回值+异常处理器
一、统一表现层返回值 根据我们不同的处理方法,返回的数据格式都会不同,例如添加只返回true|false,删除同理,而查询却返回数据。 Result类 为此我们封装一个result类来用于表现层的返回。 public class Result {//描述统一格式…...
2023年地理信息系统与遥感专业就业前景与升学高校排名选择
活动地址:毕业季进击的技术er 地理信息系统(GIS,Geographic Information System),又称“地理信息科学”(Geographic Information Science),是一种具有信息系统空间专业形式的数据管理…...
第五章:最新版零基础学习 PYTHON 教程—Python 字符串操作指南(第二节 - Python 字符串—Python 字符串 len()的语法)
Python len() 函数返回字符串的长度。 目录 Python len() 语法 Python len() 示例 示例 1:带有元组和字符串的 Len() 函数...
ubuntu22.04使用共享文件设置
从ubuntu20.04开始,设置共享文件就很麻烦 第一步: 安装samba: sudo apt install samba第二步; 创建一个共享文件夹 我以桌面Desktop为例子 第三步: 设置密码: sudo smbpasswd -a ygc第四步: sudo vim …...
pycharm配置python3.8版本专门用于undecteded_chromedriver测试
pycharm配置python3.8版本专门用于undecteded_chromedriver测试 作者:虚坏叔叔 博客:https://pay.xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 一、Pycharm及python环境的配置 1.安装python-3.8.7rc1-amd64.e…...
基于SpringBoot的民宿在线预定平台
目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 民宿信息管理 民宿资讯管理 民宿分类管理 用户注册 民宿信息 我的订单 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实…...
CTFHUB SSRF
目录 web351 编辑 web352 web353 web354 sudo.cc 代表 127 web355 host长度 web356 web357 DNS 重定向 web358 bypass web359 mysql ssrf web360 web351 POST查看 flag.php即可 web352 <?php error_reporting(0); highlight_file(__FILE__); $url$_…...
FreeRTOS入门教程(队列详细使用示例)
文章目录 前言一、队列基本使用二、如何分辨数据源三、传输大块数据总结 前言 上篇文章我们已经讲解了队列的概念和队列相关的API函数,那么本篇文章的话就开始带大家来学习使用队列。 一、队列基本使用 这个例子将会创建三个任务,其中两个任务用来发送…...
【Kafka专题】Kafka收发消息核心参数详解
目录 前置知识课程内容一、从基础的客户端说起(Java代码集成使用)1.1 消息发送者源码示例1.2 消息消费者源码示例1.3 客户端使用小总结 *二、从客户端属性来梳理客户端工作机制*2.1 消费者分组消费机制2.2 生产者拦截器机制2.3 消息序列化机制2.4 消息分…...
matlab 使用激光雷达检测、分类和跟踪车辆
目录 1、算法概述2、加载数据3、地平面分割4、语义分割5、聚类和边界盒拟合6、可视化设置7、循环遍历数据8、面向跟踪的包围盒9、 总结10、 支持功能11、 参考</...
代码随想录训练营二刷第四十八天 | 139.单词拆分 背包问题总结
代码随想录训练营二刷第四十八天 | 139.单词拆分 背包问题总结 一、139.单词拆分 题目链接:https://leetcode.cn/problems/word-break/ 思路:单词拼字符串,完全背包。定义dp[i],为true表示可以拆分为一或多个单词。可能会出现ab…...
【数据挖掘】2017年 Quiz 1-3 整理 带答案
目录 Quiz 1Quiz 2Quiz 3Quiz 1 Answer Problems 1-2 based on the following training set, where A , B , C A, B, C A,B,</...
吃鸡高手必备工具大揭秘!提高战斗力,分享干货,一站满足!
大家好!你是否想提高吃鸡游戏的战斗力,分享顶级的游戏作战干货,方便进行吃鸡作图和查询装备皮肤库存?是否也担心被骗,希望查询游戏账号是否在黑名单上,或者查询失信人和VAC封禁情况?在这段视频中…...
WarcraftHelper终极指南:让魔兽争霸3在现代系统完美重生
WarcraftHelper终极指南:让魔兽争霸3在现代系统完美重生 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3在现代电脑上的各…...
G-Helper:释放华硕笔记本性能潜能的轻量级控制工具
G-Helper:释放华硕笔记本性能潜能的轻量级控制工具 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址: …...
【紧急预警】CPython 3.12升级后,3款主流内存工具失效!2024最稳选型组合(含兼容性补丁与迁移路径)
第一章:Python 内存检测工具选型的底层逻辑与演进脉络Python 内存管理机制以引用计数为核心,辅以循环垃圾回收器(GC)和内存池(pymalloc),这决定了内存问题往往隐匿于对象生命周期、引用链异常或…...
Buildroot构建根文件系统时,为什么你的rootfs.tar总比别人的大?深度解析裁剪技巧
Buildroot构建根文件系统时rootfs.tar体积优化实战指南 当你在嵌入式Linux开发中使用Buildroot构建根文件系统时,是否经常遇到生成的rootfs.tar文件体积过大的问题?本文将深入解析Buildroot的打包机制,揭示那些容易被忽视的体积膨胀陷阱&…...
紧急通知:2024年Q3起欧盟EDPS已将差分隐私实现纳入DPIA强制审查项——Python开发者必须立即核查的4个代码检查点
第一章:差分隐私合规性背景与EDPS新规解读随着欧盟数据保护监管体系持续演进,欧洲数据保护监督机构(EDPS)于2024年7月发布《关于匿名化与假名化技术在公共部门应用的指导意见》,首次将差分隐私(Differentia…...
Windows下OpenClaw实战:30分钟接入Qwen3.5-4B-Claude模型
Windows下OpenClaw实战:30分钟接入Qwen3.5-4B-Claude模型 1. 为什么选择WindowsOpenClaw组合 去年我在尝试自动化办公流程时,发现很多AI工具对Windows支持并不友好。直到遇到OpenClaw,这个开源的智能体框架让我眼前一亮——它不仅能像人类一…...
【Mojo+Python混合部署失效真相】:92%开发者忽略的编译期符号冲突、运行时上下文隔离与调试断点丢失问题
第一章:MojoPython混合部署失效真相全景概览Mojo 作为新兴的高性能系统编程语言,设计初衷是与 Python 生态无缝互操作;然而在真实生产部署中,“Mojo Python 混合部署”常出现静默失败、ABI 不兼容、运行时崩溃或性能断崖式下降等…...
【开源鸿蒙Flutter跨平台开发实战复盘】从零到一:GitCode口袋工具项目构建全记录
1. 环境搭建:从零开始的跨平台开发之旅 作为一个有Android开发背景但完全没接触过Flutter的开发者,我最初面对开源鸿蒙和Flutter跨平台开发时也是一头雾水。环境搭建这个看似简单的第一步,就让我深刻体会到"万事开头难"的含义。 在…...
SEO_全面介绍SEO从入门到精通的关键知识点
<h2>什么是SEO?</h2> <p>SEO(Search Engine Optimization,搜索引擎优化)是一套通过优化网站内容和结构,以提高其在搜索引擎结果页面(SERP)中的自然排名的技术和策略。SEO不仅…...
学术PDF处理神器:OpenClaw+GLM-4.7-Flash自动提取关键结论
学术PDF处理神器:OpenClawGLM-4.7-Flash自动提取关键结论 1. 为什么需要自动化文献处理? 作为一名经常需要阅读大量学术文献的研究者,我发现自己花费在整理文献上的时间甚至超过了实际阅读时间。每次下载几十篇PDF后,手动提取目…...
