Web前端-Vue2+Vue3基础入门到实战项目-Day4(组件的三大组成部分, 组件通信, 案例-组件版小黑记事本, 进阶语法)
Web前端-Vue2+Vue3基础入门到实战项目-Day4
- 组件的三大组成部分(结构/样式/逻辑)
- scoped样式冲突
- data是一个函数
- 组件通信
- 组件通信语法
- 父传子
- 子传父
- props详解
- 什么是props
- props检验
- props与data的区别
- 非父子(扩展)
- 事件总线 (event bus)
- provide - inject
- 案例 - 小黑记事本(组件版)
- App.vue
- TodoHeader.vue
- TodoMain.vue
- TodoFooter.vue
- 进阶语法
- v-model详解
- v-model原理
- 表单类组件封装
- v-model简化代码
- sync修饰符
- ref和$refs
- $nextTick
- 来源
组件的三大组成部分(结构/样式/逻辑)
scoped样式冲突
- 全局样式: 默认的style样式, 会作用于全局
- 局部样式: 加上scoped属性的style样式, 只会作用于当前组件
- scoped原理:
- 给当前组件模板的所有元素, 添加一个自定义属性
data-v-hash值: 根据hash值区分不同的组件 - css选择器后面, 被自动处理, 添加上了属性选择器
div[data-v-hash]
- 给当前组件模板的所有元素, 添加一个自定义属性
<template><div class="base-one">BaseOne</div>
</template><script>
export default {}
</script><style scoped>
div {border: 3px solid blue;margin: 30px;
}
</style>
data是一个函数
- data必须是一个函数 -> 保证每个组件实例, 维护独立的一个数据对象
- 每次创建新的组件实例, 都会新执行一次data函数, 得到一个新对象
<template><div class="base-count"><button @click="count--">-</button><span>{{ count }}</span><button @click="count++">+</button></div>
</template><script>
export default {data() {return {count: 100,}},
}
</script><style>
.base-count {margin: 20px;
}
</style>
组件通信
组件通信语法
- 组件关系和对应的通信方案
- 父子关系:
props, $emit - 非父子关系:
provide, inject或eventbus - 通用方案:
vuex
- 父子关系:
- 父子通信方案的核心流程
- 父传子props:
- 父中给子添加属性传值
- 子props接收
- 使用
- 子传父$emit
- 子$emit发送消息
- 父中给子添加消息监听
- 父中实现处理函数
- 父传子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",components: {Son,},data() {return {myTitle: "学前端,就来黑马程序员",}},
}
</script><style>
</style><!-- Son.vue -->
<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>
子传父
<template><div class="app" style="border: 3px solid #000; margin: 10px">我是APP组件<!-- 2. 父组件, 对消息进行监听 --><Son :title="myTitle" @changeTitle="handleChange"></Son></div>
</template><script>
import Son from "./components/Son.vue"
export default {name: "App",components: {Son,},data() {return {myTitle: "学前端,就来黑马程序员",}},methods: {// 3. 提供处理函数, 提供逻辑handleChange(newTitle){this.myTitle = newTitle}}
}
</script><style>
</style><!-- Son.vue -->
<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(){// 1. 通过$emit, 向父组件发送消息通知this.$emit('changeTitle', "传智教育")}}
}
</script><style></style>
props详解
什么是props
- 定义: 组件上注册的一些自定义属性
- 作用: 向子组件传递数据
- 特点:
- 可以传递任意数量的prop
- 可以传递任意类型的prop
父组件
<template><div class="app"><UserInfo:username="username":age="age":isSingle="isSingle":car="car":hobby="hobby"></UserInfo></div>
</template><script>
import UserInfo from './components/UserInfo.vue'
export default {data() {return {username: '小帅',age: 28,isSingle: true,car: {brand: '宝马',},hobby: ['篮球', '足球', '羽毛球'],}},components: {UserInfo,},
}
</script><style>
</style>
子组件
<template><div class="userinfo"><h3>我是个人信息组件</h3><div>姓名:{{username}} </div><div>年龄:{{age}} </div><div>是否单身:{{isSingle ? '是' : '否'}} </div><div>座驾:{{car.brand}} </div><div>兴趣爱好:{{hobby.join(', ')}} </div></div>
</template><script>
export default {props: ['username', 'age', 'isSingle', 'car', 'hobby']
}
</script><style>
.userinfo {width: 300px;border: 3px solid #000;padding: 20px;
}
.userinfo > div {margin: 20px 10px;
}
</style>
props检验
- 作用: 为组件的prop指定验证要求, 不符合要求, 控制台会有错误提示
- 语法
- 类型检验
- 非空检验
- 默认值
- 自定义检验
父组件
<template><div class="app"><BaseProgress :w="width"></BaseProgress></div>
</template><script>
import BaseProgress from './components/BaseProgress.vue'
export default {data() {return {width: 23,}},components: {BaseProgress,},
}
</script><style>
</style>
子组件
<template><div class="base-progress"><div class="inner" :style="{ width: w + '%' }"><span>{{ w }}%</span></div></div>
</template><script>
export default {// props: ["w"],// 1.基础写法(类型校验)// props: {// w: Number // Number String Boolean Array Object// }// 2.完整写法(类型、是否必填、默认值、自定义校验)props: {w: {type: Number,// required: truedefault: 0,validator (value) {if(value >= 0 && value <= 100){return true}console.error('传入的prop w, 必须是0-100的数字')return false}}}
}
</script><style scoped>
.base-progress {height: 26px;width: 400px;border-radius: 15px;background-color: #272425;border: 3px solid #272425;box-sizing: border-box;margin-bottom: 30px;
}
.inner {position: relative;background: #379bff;border-radius: 15px;height: 25px;box-sizing: border-box;left: -3px;top: -2px;
}
.inner span {position: absolute;right: 0;top: 26px;
}
</style>
props与data的区别
- 共同点: 都可以给组件提供数据
- 区别:
- data的数据是自己的 -> 随便改
- prop的数据是外部的 -> 不能直接改, 要遵循单向数据流
- 单向数据流: 父级prop的数据更新, 会向下流动, 影响子组件. 这个数据流动是单向的.
父组件
<template><div class="app"><BaseCount @changeCount="handleChange":count="count"></BaseCount></div>
</template><script>
import BaseCount from './components/BaseCount.vue'
export default {components:{BaseCount},data(){return {count:100}},methods:{handleChange(value){this.count = value}}
}
</script><style></style>
子组件
<template><div class="base-count"><button @click="handleSub">-</button><span>{{ count }}</span><button @click="handleAdd">+</button></div>
</template><script>
export default {// 1.自己的数据随便修改 (谁的数据 谁负责)// data () {// return {// count: 100,// }// },// 2.外部传过来的数据 不能随便修改// 单向数据流: 父组件的prop更新, 会单向向下流动, 影响到子组件.props: {count: Number},methods: {handleAdd(){this.$emit('changeCount', this.count+1)},handleSub(){this.$emit('changeCount', this.count-1)}}}
</script><style>
.base-count {margin: 20px;
}
</style>
非父子(扩展)
事件总线 (event bus)
- 作用: 非父子组件之间, 进行简易消息传递(复杂场景 -> vuex)
- 语法:
- 创建一个都能访问的事件总线(空vue实例) -> utils/EventBus.js
import Vue from 'vue' const Bus = new Vue() export default Bus- A组件(接受方), 监听Bus实例的事件
created() {Bus.$on('sendMsg', (msg) => {// console.log(msg)this.msg = msg}) }- B组件(发送方), 触发Bus实例的事件
Bus.$emit('sendMsg', '今天天气不错,适合旅游')
provide - inject
- 作用: 跨层级共享数据
- 语法:
- 父组件provide提供数据
provide() {return {// 简单类型 是非响应式的color: this.color,// 复杂类型 是响应式的userInfo: this.userInfo,} }- 子/孙组件 inject 取值使用
<script> export default {inject: ['color', 'userInfo'], } </script>
案例 - 小黑记事本(组件版)
核心步骤
- 拆分基础组件
新建组件 -> 拆分存放结构 -> 导入注册使用 - 渲染待办任务
提供数据(公共父组件) -> 父传子传递list -> v-for渲染 - 添加任务
收集数据v-model -> 监听事件 -> 子传父传递任务 -> 父组件unshift - 删除任务
监听删除id -> 子传父传递id -> 父组件filter删除 - 底部合计和清空功能
底部合计: 父传子list -> 合计展示
清空功能: 监听点击 -> 子传父通知父组件 -> 父组件清空 - 持久化存储: watch监视数据变化, 持久化到本地
App.vue
<template><!-- 主体区域 --><section id="app"><TodoHeaderVue @add="handleAdd"></TodoHeaderVue><TodoMainVue @del="handleDel" :list="list"></TodoMainVue><TodoFooterVue @clear="handleClear" :list="list"></TodoFooterVue></section>
</template><script>
import TodoHeaderVue from './components/TodoHeader.vue'
import TodoMainVue from './components/TodoMain.vue'
import TodoFooterVue from './components/TodoFooter.vue'// 渲染功能:
// 1. 提供数据-> 提供在公共的父组件 App.vue
// 2. 通过父传子, 奖数据传递给 TodoMain
// 3. 利用v-for渲染// 添加功能
// 1. 收集表单数据 -> v-model
// 2. 监听事件 (回车 + 点击都要进行添加)
// 3. 子传父, 将任务名称传递给父组件App.vue
// 4. 进行添加 unshift// 删除功能
// 1. 监听事件 (监听删除的点击) 携带id
// 2. 子传父, 将删除的id传递给父组件App.vue
// 3. 进行删除 filter// 底部合计: 父传子list -> 渲染
// 清空功能: 子传父 通知父组件 -> 父组件进行清空
// 持久化存储: watch深度监视list的变化 -> 往本地存储 -> 进入页面优先读取本地存储
export default {data () {return {list: JSON.parse(localStorage.getItem('list')) || [{id: 1, name: '打篮球'},{id: 2, name: '看电影'},{id: 3, name: '逛街'},]}},methods: {handleAdd(todoName){this.list.unshift({id: +new Date(),name: todoName})},handleDel(id){this.list = this.list.filter(item => item.id!==id)},handleClear(){this.list = []}},watch: {list: {deep: true,handler(newValue){localStorage.setItem('list', JSON.stringify(newValue))}}},components: {TodoHeaderVue,TodoMainVue,TodoFooterVue}
}
</script><style></style>
TodoHeader.vue
<template><div><!-- 输入框 --><header class="header"><h1>小黑记事本</h1><input v-model.trim="todoName" @keyup.enter="handleAdd" placeholder="请输入任务" class="new-todo"/><button @click="handleAdd" class="add">添加任务</button></header></div>
</template><script>
export default {data(){return {todoName: ''}},methods: {handleAdd(){if(this.todoName.trim() === ''){alert('任务名称不能为空')return }this.$emit('add', this.todoName)this.todoName = ''}}
}
</script><style>
</style>
TodoMain.vue
<template><div><!-- 列表区域 --><section class="main"><ul class="todo-list"><li class="todo" v-for="(item, index) in list" :key="item.id"><div class="view"><span class="index"> {{index+1}}. </span> <label> {{item.name}} </label><button @click="handleDel(item.id)" class="destroy"></button></div></li></ul></section></div>
</template><script>
export default {props: {list: Array},methods: {handleDel(id){this.$emit('del', id)}}
}
</script><style></style>
TodoFooter.vue
<template><div><!-- 统计和清空 --><footer class="footer"><!-- 统计 --><span class="todo-count">合 计:<strong> {{list.length}} </strong></span><!-- 清空 --><button @click="clear" class="clear-completed">清空任务</button></footer></div>
</template><script>
export default {props: {list: Array},methods: {clear(){this.$emit('clear')}}
}
</script><style></style>
进阶语法
v-model详解
v-model原理
- 原理: v-model本质上是一个语法糖. 例如应用在输入框上, 就是value属性和input事件的合写.
- 作用: 提供数据的双向绑定
- 数据发生变化, 视图自动变化: value
- 视图发生变化, 数据自动变化: @input
$event: 用在模板中, 获取事件的形参
<div class="app"><input v-model="msg1" type="text" /> <br /><input :value="msg2" @input="msg2 = $event.target.value" type="text" >
</div>
表单类组件封装
实现子组件和父组件数据的双向绑定
- 父传子: 数据 由父组件props传递, v-model拆解绑定数据
- 子传父: 监听输入, 子传父传值给父组件修改
父组件
<template><div class="app"><BaseSelect :selectId="selectId" @change="selectId = $event"></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {selectId: '102',}},components: {BaseSelect,},methods: {}
}
</script><style>
</style>
子组件
<template><div><select :value="selectId" @change="handleChange"><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {props: {selectId: String},methods: {handleChange(e){this.$emit('change', e.target.value)}}
}
</script><style>
</style>
v-model简化代码
父组件v-model简化实现子组件和父组件数据双向绑定
- 子组件: props通过value接收, 事件触发input
- 父组件: v-model绑定数据 (:value + @input)
父组件
<template><div class="app"><BaseSelect v-model="selectId"></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {selectId: '102',}},components: {BaseSelect,},
}
</script><style>
</style>
子组件
<template><div><select :value="value" @change="handleChange"><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {props: {value: String},methods: {handleChange(e){this.$emit('input', e.target.value)}}
}
</script><style>
</style>
sync修饰符
- 作用: 实现子组件与父组件的数据双向绑定, 简化代码
- 特点: prop属性名, 可以自定义, 非固定为value
- 场景: 封装弹框类的基础组件, visible属性 true显示 false隐藏
- 本质:
:属性名 + @update:属性名
父组件
<template><div class="app"><button @click="isShow = true">退出按钮</button><BaseDialog :visible.sync="isShow"></BaseDialog></div>
</template><script>
import BaseDialog from "./components/BaseDialog.vue"
export default {data() {return {isShow: false}},methods: {},components: {BaseDialog,},
}
</script><style>
</style>
子组件
<template><div v-show="visible" class="base-dialog-wrap"><div class="base-dialog"><div class="title"><h3>温馨提示:</h3><button @click="close" class="close">x</button></div><div class="content"><p>你确认要退出本系统么?</p></div><div class="footer"><button>确认</button><button>取消</button></div></div></div>
</template><script>
export default {props: {visible: Boolean},methods: {close(){this.$emit('update:visible', false)}}
}
</script><style scoped>
.base-dialog-wrap {width: 300px;height: 200px;box-shadow: 2px 2px 2px 2px #ccc;position: fixed;left: 50%;top: 50%;transform: translate(-50%, -50%);padding: 0 10px;
}
.base-dialog .title {display: flex;justify-content: space-between;align-items: center;border-bottom: 2px solid #000;
}
.base-dialog .content {margin-top: 38px;
}
.base-dialog .title .close {width: 20px;height: 20px;cursor: pointer;line-height: 10px;
}
.footer {display: flex;justify-content: flex-end;margin-top: 26px;
}
.footer button {width: 80px;height: 40px;
}
.footer button:nth-child(1) {margin-right: 10px;cursor: pointer;
}
</style>
ref和$refs
- 作用: 通过
ref和$refs可以获取dom元素和组件实例 - 使用:
- 目标组件 - 添加ref属性
<div ref="test"></div>- 通过this.$refs.
ref属性值获取目标组件
this.$refs.test - 获取dom
<div ref="mychart" class="base-chart-box">子组件</div>const myChart = echarts.init(this.$refs.mychart) - 获取组件
父组件
子组件<template><div class="app"><BaseForm ref="baseFrom"></BaseForm><button @click="handleGet">获取数据</button><button @click="handleReset">重置数据</button></div></template><script> import BaseForm from './components/BaseForm.vue' export default {components: {BaseForm,},methods: {handleGet(){console.log(this.$refs.baseFrom.getValues())},handleReset(){this.$refs.baseFrom.resetValues()}} } </script><style> </style><template><div class="app"><div>账号: <input v-model="username" type="text"></div><div>密码: <input v-model="password" type="text"></div></div> </template><script> export default {data() {return {username: 'admin',password: '123456',}},methods: {getValues() {return {username: this.username,password: this.password}},resetValues() {this.username = ''this.password = ''console.log('重置表单数据成功');},} } </script><style scoped> .app {border: 2px solid #ccc;padding: 10px; } .app div{margin: 10px 0; } .app div button{margin-right: 8px; } </style>
$nextTick
- Vue是异步更新DOM的
$nextTick: 在DOM更新完成之后做某件事
<template><div class="app"><div v-if="isShowEdit"><input type="text" v-model="editValue" ref="inp" /><button>确认</button></div><div v-else><span>{{ title }}</span><button @click="handleEdit">编辑</button></div></div>
</template><script>
export default {data() {return {title: '大标题',isShowEdit: false,editValue: '',}},methods: {handleEdit(){// 1. 显示输入框 (异步dom更新)this.isShowEdit = true// 2. 让输入框显示焦点// console.log(this.$refs.inp) // undefinedthis.$nextTick(()=>{this.$refs.inp.focus()})}},
}
</script><style>
</style>
来源
黑马程序员. Vue2+Vue3基础入门到实战项目
相关文章:
Web前端-Vue2+Vue3基础入门到实战项目-Day4(组件的三大组成部分, 组件通信, 案例-组件版小黑记事本, 进阶语法)
Web前端-Vue2Vue3基础入门到实战项目-Day4 组件的三大组成部分(结构/样式/逻辑)scoped样式冲突data是一个函数 组件通信组件通信语法父传子子传父props详解什么是propsprops检验props与data的区别 非父子(扩展)事件总线 (event bus)provide - inject 案例 - 小黑记事本(组件版)…...
【大模型应用开发教程】01_大模型简介
C1 大模型简介 一. 什么是LLM(大语言模型)?1. 发展历程2. 大语言模型的概念LLM的应用和影响 二、大模型的能力和特点1. 大模型的能力1.1 涌现能力(emergent abilities)1.2 作为基座模型支持多元应用的能力1.3 支持对话…...
Flume 简介及基本使用
1.Flume简介 Apache Flume 是一个分布式,高可用的数据收集系统。它可以从不同的数据源收集数据,经过聚合后发送到存储系统中,通常用于日志数据的收集。Flume 分为 NG 和 OG (1.0 之前) 两个版本,NG 在 OG 的基础上进行了完全的重构…...
行业追踪,2023-10-11
自动复盘 2023-10-11 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…...
Linux:进程控制
目录 一、进程创建 写时拷贝 二、进程终止 echo $? 如何终止进程 _exit与exit 三、进程等待 进程等待的必要性 进程等待的操作 wait waitpid status 异常退出情况 status相关宏 options 四、进程程序替换 1、关于进程程序替换 2、如何进行进程程序替换 程序…...
HTTP中的GET方法与POST方法
1、GET 和 POST方法之间的区别 根据 RFC 规范,GET 的语义是从服务器获取指定的资源,这个资源可以是静态的文本、页面、图片视频等。GET 请求的参数位置一般是写在 URL 中,URL 规定只能支持 ASCII,所以 GET 请求的参数只允许 ASCI…...
2023年10月16日-10月22日,(光追+ue+osg继续按部就班进行即可。)
根据月计划, 本周计划如下: 2023年10月16日-10月22日,光追10.7-10.13,ue rpg(p47-p53),ue5底层渲染01A19-01B4,osg29,osg30,filament文档每天看 落实到天就是 2023年10月16日光追10.7,ue rpg(p47),ue5底层渲染01A19,o…...
【Docker】命令使用大全
【Docker】命令使用大全 目录 【Docker】命令使用大全 简述 Docker 的主要用途 基本概念 容器周期管理 run start/stop/restart kill rm pause/unpause create exec 容器操作 ps inspect top attach events logs wait export port 容器 rootfs 命令 c…...
查找算法:二分查找、插值查找、斐波那契查找
二分查找 查找的前提是数组有序 思路分析 代码实现 # 二分查找(递归法实现) # 找到一个相等的值就返回该值的下标 def binary_search(arr: list, find_val: int, left: int, right: int):mid (left right) // 2 # 寻找数组中间位置的下标if left &…...
python+django高校教室资源预约管理系统lqg8u
技术栈 后端:pythondjango 前端:vueCSSJavaScriptjQueryelementui 开发语言:Python 框架:django/flask Python版本:python3.7.7 数据库:mysql 数据库工具:Navicat 开发软件:PyChar…...
Potato靶机
信息搜集 设备发现 扫描端口 综合扫描 开放了80端口的HTTP服务和7120端口的SSH服务 目录扫描 扫描目录 看看这个info.php,发现只有php的版本信息,没有可以利用的注入点 SSH突破 hydra 爆破 考虑到 7120 端口是 ssh 服务,尝试利用 hydra …...
【环境搭建】linux docker-compose安装gitlab和redis
gitlab需要redis,一起安装了 新建gitlab和redis挂载目录 mkdir -p /data/docker/redis/data mkdir -p /data/docker/redis/logs mkdir -p /data/docker/redis/confmkdir -p /data/docker/gitlab/data mkdir -p /data/docker/gitlab/logs mkdir -p /data/docker/gi…...
JAVAEE初阶相关内容第十三弹--文件操作 IO
写在前 终于完成了!!!!内容不多就是本人太拖拉! 这里主要介绍文件input,output操作。File类,流对象(分为字节流、字符流) 需要掌握每个流对象的使用方式:打…...
POI报表的高级应用
POI报表的高级应用 掌握基于模板打印的POI报表导出理解自定义工具类的执行流程 熟练使用SXSSFWorkbook完成百万数据报表打印理解基于事件驱动的POI报表导入 模板打印 概述 自定义生成Excel报表文件还是有很多不尽如意的地方,特别是针对复杂报表头,单…...
【计算机毕设选题推荐】超市管理系统SpringBoot+SSM+Vue
前言:我是IT源码社,从事计算机开发行业数年,专注Java领域,专业提供程序设计开发、源码分享、技术指导讲解、定制和毕业设计服务 项目名 基于SpringBoot的超市管理系统 技术栈 SpringBootVueMySQLMaven 文章目录 一、超市管理系统…...
【算法1-4】递推与递归-P1002 [NOIP2002 普及组] 过河卒
## 题目描述 棋盘上 A 点有一个过河卒,需要走到目标 B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。 棋盘用坐标表示&#…...
浅谈压力测试的作用是什么
随着现代应用程序变得越来越复杂,用户的期望也在不断提高,对性能和可靠性的要求变得更加苛刻。在应用程序开发和维护的过程中,压力测试是一项至关重要的活动,它可以帮助发现潜在的问题、评估系统的性能极限,以及确保在…...
互联网Java工程师面试题·Java 总结篇·第一弹
目录 1、面向对象的特征有哪些方面? 2、访问修饰符 public,private,protected,以及不写(默认)时的区别? 3、String 是最基本的数据类型吗? 4、float f3.4;是否正确? 5、short s1 1; s1 s1 1;有错吗…...
Anylogic 读取和写入Excel文件
1、选择面板-连接-Excel文件,拖入到视图中 然后在excel文件的属性中进行绑定外部excel文件。 绑定完之后,在你需要读取的地方进行写代码, //定义开始读取的行数 //这里设为2,是因为第一行是数据名称 int row12; //读取excel文件信…...
茶百道全链路可观测实战
作者:山猎 茶百道是四川成都的本土茶饮连锁品牌,创立于 2008 年 。经过 15 年的发展,茶百道已成为餐饮标杆品牌,全国门店超 7000 家,遍布全国 31 个省市,实现中国大陆所有省份及各线级城市的全覆盖。2021 …...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
