当前位置: 首页 > news >正文

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原理:
    1. 给当前组件模板的所有元素, 添加一个自定义属性
      data-v-hash值: 根据hash值区分不同的组件
    2. 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, injecteventbus
    • 通用方案: vuex
  • 父子通信方案的核心流程
    • 父传子props:
      1. 父中给子添加属性传值
      2. 子props接收
      3. 使用
    • 子传父$emit
      1. 子$emit发送消息
      2. 父中给子添加消息监听
      3. 父中实现处理函数

父传子

<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指定验证要求, 不符合要求, 控制台会有错误提示
  • 语法
    1. 类型检验
    2. 非空检验
    3. 默认值
    4. 自定义检验

父组件

<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)
  • 语法:
    1. 创建一个都能访问的事件总线(空vue实例) -> utils/EventBus.js
    import Vue from 'vue'
    const Bus  =  new Vue()
    export default Bus
    
    1. A组件(接受方), 监听Bus实例的事件
    created() {Bus.$on('sendMsg', (msg) => {// console.log(msg)this.msg = msg})
    }
    
    1. B组件(发送方), 触发Bus实例的事件
    Bus.$emit('sendMsg', '今天天气不错,适合旅游')
    

provide - inject

  • 作用: 跨层级共享数据
  • 语法:
    1. 父组件provide提供数据
    provide() {return {// 简单类型 是非响应式的color: this.color,// 复杂类型 是响应式的userInfo: this.userInfo,}
    }
    
    1. 子/孙组件 inject 取值使用
    <script>
    export default {inject: ['color', 'userInfo'],
    }
    </script>
    

案例 - 小黑记事本(组件版)

核心步骤

  1. 拆分基础组件
    新建组件 -> 拆分存放结构 -> 导入注册使用
  2. 渲染待办任务
    提供数据(公共父组件) -> 父传子传递list -> v-for渲染
  3. 添加任务
    收集数据v-model -> 监听事件 -> 子传父传递任务 -> 父组件unshift
  4. 删除任务
    监听删除id -> 子传父传递id -> 父组件filter删除
  5. 底部合计和清空功能
    底部合计: 父传子list -> 合计展示
    清空功能: 监听点击 -> 子传父通知父组件 -> 父组件清空
  6. 持久化存储: 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事件的合写.
  • 作用: 提供数据的双向绑定
    1. 数据发生变化, 视图自动变化: value
    2. 视图发生变化, 数据自动变化: @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元素和组件实例
  • 使用:
    1. 目标组件 - 添加ref属性
    <div ref="test"></div>
    
    1. 通过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&#xff08;大语言模型&#xff09;&#xff1f;1. 发展历程2. 大语言模型的概念LLM的应用和影响 二、大模型的能力和特点1. 大模型的能力1.1 涌现能力&#xff08;emergent abilities&#xff09;1.2 作为基座模型支持多元应用的能力1.3 支持对话…...

Flume 简介及基本使用

1.Flume简介 Apache Flume 是一个分布式&#xff0c;高可用的数据收集系统。它可以从不同的数据源收集数据&#xff0c;经过聚合后发送到存储系统中&#xff0c;通常用于日志数据的收集。Flume 分为 NG 和 OG (1.0 之前) 两个版本&#xff0c;NG 在 OG 的基础上进行了完全的重构…...

行业追踪,2023-10-11

自动复盘 2023-10-11 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…...

Linux:进程控制

目录 一、进程创建 写时拷贝 二、进程终止 echo $? 如何终止进程 _exit与exit 三、进程等待 进程等待的必要性 进程等待的操作 wait waitpid status 异常退出情况 status相关宏 options 四、进程程序替换 1、关于进程程序替换 2、如何进行进程程序替换 程序…...

HTTP中的GET方法与POST方法

1、GET 和 POST方法之间的区别 根据 RFC 规范&#xff0c;GET 的语义是从服务器获取指定的资源&#xff0c;这个资源可以是静态的文本、页面、图片视频等。GET 请求的参数位置一般是写在 URL 中&#xff0c;URL 规定只能支持 ASCII&#xff0c;所以 GET 请求的参数只允许 ASCI…...

2023年10月16日-10月22日,(光追+ue+osg继续按部就班进行即可。)

根据月计划&#xff0c; 本周计划如下&#xff1a; 2023年10月16日-10月22日&#xff0c;光追10.7-10.13&#xff0c;ue rpg(p47-p53),ue5底层渲染01A19-01B4,osg29,osg30,filament文档每天看 落实到天就是 2023年10月16日光追10.7&#xff0c;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…...

查找算法:二分查找、插值查找、斐波那契查找

二分查找 查找的前提是数组有序 思路分析 代码实现 # 二分查找&#xff08;递归法实现&#xff09; # 找到一个相等的值就返回该值的下标 def binary_search(arr: list, find_val: int, left: int, right: int):mid (left right) // 2 # 寻找数组中间位置的下标if left &…...

python+django高校教室资源预约管理系统lqg8u

技术栈 后端&#xff1a;pythondjango 前端&#xff1a;vueCSSJavaScriptjQueryelementui 开发语言&#xff1a;Python 框架&#xff1a;django/flask Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyChar…...

Potato靶机

信息搜集 设备发现 扫描端口 综合扫描 开放了80端口的HTTP服务和7120端口的SSH服务 目录扫描 扫描目录 看看这个info.php&#xff0c;发现只有php的版本信息&#xff0c;没有可以利用的注入点 SSH突破 hydra 爆破 考虑到 7120 端口是 ssh 服务&#xff0c;尝试利用 hydra …...

【环境搭建】linux docker-compose安装gitlab和redis

gitlab需要redis&#xff0c;一起安装了 新建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

写在前 终于完成了&#xff01;&#xff01;&#xff01;&#xff01;内容不多就是本人太拖拉&#xff01; 这里主要介绍文件input&#xff0c;output操作。File类&#xff0c;流对象&#xff08;分为字节流、字符流&#xff09; 需要掌握每个流对象的使用方式&#xff1a;打…...

POI报表的高级应用

POI报表的高级应用 掌握基于模板打印的POI报表导出理解自定义工具类的执行流程 熟练使用SXSSFWorkbook完成百万数据报表打印理解基于事件驱动的POI报表导入 模板打印 概述 自定义生成Excel报表文件还是有很多不尽如意的地方&#xff0c;特别是针对复杂报表头&#xff0c;单…...

【计算机毕设选题推荐】超市管理系统SpringBoot+SSM+Vue

前言&#xff1a;我是IT源码社&#xff0c;从事计算机开发行业数年&#xff0c;专注Java领域&#xff0c;专业提供程序设计开发、源码分享、技术指导讲解、定制和毕业设计服务 项目名 基于SpringBoot的超市管理系统 技术栈 SpringBootVueMySQLMaven 文章目录 一、超市管理系统…...

【算法1-4】递推与递归-P1002 [NOIP2002 普及组] 过河卒

## 题目描述 棋盘上 A 点有一个过河卒&#xff0c;需要走到目标 B 点。卒行走的规则&#xff1a;可以向下、或者向右。同时在棋盘上 C 点有一个对方的马&#xff0c;该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。 棋盘用坐标表示&#…...

浅谈压力测试的作用是什么

随着现代应用程序变得越来越复杂&#xff0c;用户的期望也在不断提高&#xff0c;对性能和可靠性的要求变得更加苛刻。在应用程序开发和维护的过程中&#xff0c;压力测试是一项至关重要的活动&#xff0c;它可以帮助发现潜在的问题、评估系统的性能极限&#xff0c;以及确保在…...

互联网Java工程师面试题·Java 总结篇·第一弹

目录 1、面向对象的特征有哪些方面&#xff1f; 2、访问修饰符 public,private,protected,以及不写&#xff08;默认&#xff09;时的区别&#xff1f; 3、String 是最基本的数据类型吗&#xff1f; 4、float f3.4;是否正确&#xff1f; 5、short s1 1; s1 s1 1;有错吗…...

Anylogic 读取和写入Excel文件

1、选择面板-连接-Excel文件&#xff0c;拖入到视图中 然后在excel文件的属性中进行绑定外部excel文件。 绑定完之后&#xff0c;在你需要读取的地方进行写代码&#xff0c; //定义开始读取的行数 //这里设为2&#xff0c;是因为第一行是数据名称 int row12; //读取excel文件信…...

茶百道全链路可观测实战

作者&#xff1a;山猎 茶百道是四川成都的本土茶饮连锁品牌&#xff0c;创立于 2008 年 。经过 15 年的发展&#xff0c;茶百道已成为餐饮标杆品牌&#xff0c;全国门店超 7000 家&#xff0c;遍布全国 31 个省市&#xff0c;实现中国大陆所有省份及各线级城市的全覆盖。2021 …...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...

生信服务器 | 做生信为什么推荐使用Linux服务器?

原文链接&#xff1a;生信服务器 | 做生信为什么推荐使用Linux服务器&#xff1f; 一、 做生信为什么推荐使用服务器&#xff1f; 大家好&#xff0c;我是小杜。在做生信分析的同学&#xff0c;或是将接触学习生信分析的同学&#xff0c;<font style"color:rgb(53, 1…...

OCC笔记:TDF_Label中有多个相同类型属性

注&#xff1a;OCCT版本&#xff1a;7.9.1 TDF_Label中有多个相同类型的属性的方案 OCAF imposes the restriction that only one attribute type may be allocated to one label. It is necessary to take into account the design of the application data tree. For exampl…...

Linux--vsFTP配置篇

一、vsFTP 简介 vsftpd&#xff08;Very Secure FTP Daemon&#xff09;是 Linux 下常用的 FTP 服务程序&#xff0c;具有安全性高、效率高和稳定性好等特点。支持匿名访问、本地用户登录、虚拟用户等多种认证方式&#xff0c;并可灵活控制权限。 二、安装与启动 1. 检查是否已…...

鸿蒙APP测试实战:从HDC命令到专项测试

普通APP的测试与鸿蒙APP的测试有一些共同的特征&#xff0c;但是也有一些区别&#xff0c;其中共同特征是&#xff0c;它们都可以通过cmd的命令提示符工具来进行app的性能测试。 其中区别主要是&#xff0c;对于稳定性测试的命令的区别&#xff0c;性能指标获取方式的命令的区…...