Vue高级特性实战:自定义指令、插槽与路由全解析
一、自定义指令
1.如何自定义指令
⑴.全局注册语法
通过 Vue.directive
方法注册,语法格式为:
Vue.directive('指令名', {// 钩子函数,元素插入父节点时触发(仅保证父节点存在,不一定已插入文档)inserted(el) { // el 表示绑定指令的 DOM 元素,可在此进行 DOM 操作el.focus(); // 示例:让元素获取焦点}// 其他钩子函数(如 bind、update 等,可选)
})
- 参数说明:
'指令名'
:指令的名称,使用时以v-
前缀调用(如v-focus
)。inserted
:钩子函数,当元素插入父节点时触发(仅保证父节点存在,不一定已插入文档),常用于初始化 DOM 操作。el
:绑定指令的 DOM 元素,可直接操作该元素。
示例:
// 全局注册一个自动获取焦点的指令 v-focus
Vue.directive('focus', {inserted(el) {el.focus(); // 元素插入时获取焦点}
})// 使用方式:<input v-focus type="text">
main.js
import { createApp } from 'vue';
import App from './App.vue';// 创建 Vue 应用实例
const app = createApp(App);// 全局注册自定义指令 v-focus
app.directive('focus', {inserted(el) {el.focus();}
});// 挂载应用
app.mount('#app');
App.vue
<template><div><h1>自定义指令</h1><input v-focus ref="inp" type="text"></div>
</template><script>
export default {// 移除局部注册的指令
}
</script><style></style>
⑵.局部注册语法
在组件内部通过 directives
选项注册,仅在当前组件内生效,语法格式为:
export default {directives: {// 指令名(无需 v- 前缀,注册名与使用名一致)指令名: { inserted(el) {// 操作 DOMel.focus(); // 示例:让元素获取焦点}}}
}
- 参数说明:
directives
:组件选项,用于声明局部自定义指令。指令名
:注册的指令名称,使用时以v-
前缀调用(如v-focus
)。inserted
钩子及el
参数含义与全局注册一致。
示例:
<template><input v-focus type="text"> <!-- 使用指令 -->
</template><script>
export default {directives: {// 局部注册 v-focus 指令focus: { inserted(el) {el.focus(); // 元素插入时获取焦点}}}
}
</script>
App.vue
<template><div><h1>自定义指令</h1><input v-focus ref="inp" type="text"></div>
</template><script>
export default {// 局部注册指令directives: {// 指令名:指令的配置项focus: {inserted (el) {// 当元素插入到 DOM 中时,让元素获取焦点el.focus()}}}
}
</script><style></style>
两种注册方式的区别
- 全局注册:通过
Vue.directive
注册后,所有组件均可使用该指令,适用于通用功能(如全局的焦点控制、权限校验等)。 - 局部注册:通过组件内的
directives
选项注册,仅当前组件可用,适用于特定组件的特殊 DOM 操作,避免污染全局作用域。
通过自定义指令,可封装重复的 DOM 操作逻辑,提升代码复用性与简洁性。
2.自定义指令 - 指令的值
<template><div><h1 v-color="color1">指令的值1测试</h1><h1 v-color="color2">指令的值2测试</h1></div>
</template><script>
export default {data () {return {color1: 'red',color2: 'orange'}},directives: {color: {// 1. inserted 提供的是元素被添加到页面中时的逻辑inserted (el, binding) {console.log(el, binding.value);// binding.value 就是指令的值el.style.color = binding.value},// 2. update 指令的值修改的时候触发,提供值变化后,dom更新的逻辑update (el, binding) {console.log('指令的值修改了');el.style.color = binding.value}}}
}
</script><style></style>
3.自定义指令 - v-loading 指令封装
App.vue
<template><div class="main"><div class="box" v-loading="isLoading"><ul><li v-for="item in list" :key="item.id" class="news"><div class="left"><div class="title">{{ item.title }}</div><div class="info"><span>{{ item.source }}</span><span>{{ item.time }}</span></div></div><div class="right"><img :src="item.img" alt=""></div></li></ul></div><div class="box2" v-loading="isLoading2"></div></div>
</template><script>
// 安装axios => yarn add axios
import axios from 'axios'// 接口地址:http://hmajax.itheima.net/api/news
// 请求方式:get
export default {data () {return {list: [],isLoading: true,isLoading2: true}},async created () {// 1. 发送请求获取数据const res = await axios.get('http://hmajax.itheima.net/api/news')setTimeout(() => {// 2. 更新到 list 中,用于页面渲染 v-forthis.list = res.data.datathis.isLoading = false}, 2000)},directives: {loading: {inserted (el, binding) {binding.value ? el.classList.add('loading') : el.classList.remove('loading')},update (el, binding) {binding.value ? el.classList.add('loading') : el.classList.remove('loading')}}}
}
</script><style>
.loading:before {content: '';position: absolute;left: 0;top: 0;width: 100%;height: 100%;background: #fff url('./loading.gif') no-repeat center;
}.box2 {width: 400px;height: 400px;border: 2px solid #000;position: relative;
}.box {width: 800px;min-height: 500px;border: 3px solid orange;border-radius: 5px;position: relative;
}
.news {display: flex;height: 120px;width: 600px;margin: 0 auto;padding: 20px 0;cursor: pointer;
}
.news .left {flex: 1;display: flex;flex-direction: column;justify-content: space-between;padding-right: 10px;
}
.news .left .title {font-size: 20px;
}
.news .left .info {color: #999999;
}
.news .left .info span {margin-right: 20px;
}
.news .right {width: 160px;height: 120px;
}
.news .right img {width: 100%;height: 100%;object-fit: cover;
}
</style>
二、插槽
1.插槽 - 默认插槽
插槽(Slots)是 Vue 实现组件内容分发的机制,允许我们在组件模板中预留一个或多个区域,将不同的内容插入到这些区域中。它就像是组件模板中的 “占位符”,可以让父组件决定子组件的部分内容如何展示。这大大增强了组件的复用性和灵活性,使得同一个组件可以根据不同的使用场景展示不同的内容。
MyDialog.vue
<template><div class="dialog"><div class="dialog-header"><h3>友情提示</h3><span class="close">✖️</span></div><div class="dialog-content"><!-- 1. 在需要定制的位置,使用slot占位 --><slot></slot></div><div class="dialog-footer"><button>取消</button><button>确认</button></div></div>
</template><script>
export default {data () {return {}}
}
</script><style scoped>
* {margin: 0;padding: 0;
}
.dialog {width: 470px;height: 230px;padding: 0 25px;background-color: #ffffff;margin: 40px auto;border-radius: 5px;
}
.dialog-header {height: 70px;line-height: 70px;font-size: 20px;border-bottom: 1px solid #ccc;position: relative;
}
.dialog-header .close {position: absolute;right: 0px;top: 0px;cursor: pointer;
}
.dialog-content {height: 80px;font-size: 18px;padding: 15px 0;
}
.dialog-footer {display: flex;justify-content: flex-end;
}
.dialog-footer button {width: 65px;height: 35px;background-color: #ffffff;border: 1px solid #e1e3e9;cursor: pointer;outline: none;margin-left: 10px;border-radius: 3px;
}
.dialog-footer button:last-child {background-color: #007acc;color: #fff;
}
</style>
App.vue
<template><div><!-- 2. 在使用组件时,组件标签内填入内容 --><MyDialog><div>你确认要删除么</div></MyDialog><MyDialog><p>你确认要退出么</p><p>你确认要退出么</p><p>你确认要退出么</p></MyDialog></div>
</template><script>
import MyDialog from './components/MyDialog.vue'
export default {data () {return {}},components: {MyDialog}
}
</script><style>
body {background-color: #b3b3b3;
}
</style>
2.插槽 - 后备内容(默认值)
MyDialog.vue
<template><div class="dialog"><div class="dialog-header"><h3>友情提示</h3><span class="close">✖️</span></div><div class="dialog-content"><!-- 往slot标签内部,编写内容,可以作为后备内容(默认值) --><slot>我是默认的文本内容</slot></div><div class="dialog-footer"><button>取消</button><button>确认</button></div></div>
</template><script>
export default {data () {return {}}
}
</script><style scoped>
* {margin: 0;padding: 0;
}
.dialog {width: 470px;height: 230px;padding: 0 25px;background-color: #ffffff;margin: 40px auto;border-radius: 5px;
}
.dialog-header {height: 70px;line-height: 70px;font-size: 20px;border-bottom: 1px solid #ccc;position: relative;
}
.dialog-header .close {position: absolute;right: 0px;top: 0px;cursor: pointer;
}
.dialog-content {height: 80px;font-size: 18px;padding: 15px 0;
}
.dialog-footer {display: flex;justify-content: flex-end;
}
.dialog-footer button {width: 65px;height: 35px;background-color: #ffffff;border: 1px solid #e1e3e9;cursor: pointer;outline: none;margin-left: 10px;border-radius: 3px;
}
.dialog-footer button:last-child {background-color: #007acc;color: #fff;
}
</style>
App.vue
<template><div><MyDialog></MyDialog><MyDialog>你确认要退出么</MyDialog></div>
</template><script>
import MyDialog from './components/MyDialog.vue'
export default {data () {return {}},components: {MyDialog}
}
</script><style>
body {background-color: #b3b3b3;
}
</style>
3.插槽 - 具名插槽
MyDialog.vue
<template><div class="dialog"><div class="dialog-header"><!-- 一旦插槽起了名字,就是具名插槽,只支持定向分发 --><slot name="head"></slot></div><div class="dialog-content"><slot name="content"></slot></div><div class="dialog-footer"><slot name="footer"></slot></div></div>
</template><script>
export default {data () {return {}}
}
</script><style scoped>
* {margin: 0;padding: 0;
}
.dialog {width: 470px;height: 230px;padding: 0 25px;background-color: #ffffff;margin: 40px auto;border-radius: 5px;
}
.dialog-header {height: 70px;line-height: 70px;font-size: 20px;border-bottom: 1px solid #ccc;position: relative;
}
.dialog-header .close {position: absolute;right: 0px;top: 0px;cursor: pointer;
}
.dialog-content {height: 80px;font-size: 18px;padding: 15px 0;
}
.dialog-footer {display: flex;justify-content: flex-end;
}
.dialog-footer button {width: 65px;height: 35px;background-color: #ffffff;border: 1px solid #e1e3e9;cursor: pointer;outline: none;margin-left: 10px;border-radius: 3px;
}
.dialog-footer button:last-child {background-color: #007acc;color: #fff;
}
</style>
App.vue
<template><div><MyDialog><!-- 需要通过template标签包裹需要分发的结构,包成一个整体 --><template v-slot:head><div>我是大标题</div></template><template v-slot:content><div>我是内容</div></template><template #footer><button>取消</button><button>确认</button></template></MyDialog></div>
</template><script>
import MyDialog from './components/MyDialog.vue'
export default {data () {return {}},components: {MyDialog}
}
</script><style>
body {background-color: #b3b3b3;
}
</style>
4.插槽 - 作用域插槽
App.vue
<template><div><MyTable :data="list"><!-- 3. 通过template #插槽名="变量名" 接收 --><template #default="obj"><button @click="del(obj.row.id)">删除</button></template></MyTable><MyTable :data="list2"><template #default="{ row }"><button @click="show(row)">查看</button></template></MyTable></div>
</template><script>
import MyTable from './components/MyTable.vue'
export default {data () {return {list: [{ id: 1, name: '张小花', age: 18 },{ id: 2, name: '孙大明', age: 19 },{ id: 3, name: '刘德忠', age: 17 },],list2: [{ id: 1, name: '赵小云', age: 18 },{ id: 2, name: '刘蓓蓓', age: 19 },{ id: 3, name: '姜肖泰', age: 17 },]}},methods: {del (id) {this.list = this.list.filter(item => item.id !== id)},show (row) {// console.log(row);alert(`姓名:${row.name}; 年纪:${row.age}`)}},components: {MyTable}
}
</script>
MyTable.vue
<template><table class="my-table"><thead><tr><th>序号</th><th>姓名</th><th>年纪</th><th>操作</th></tr></thead><tbody><tr v-for="(item, index) in data" :key="item.id"><td>{{ index + 1 }}</td><td>{{ item.name }}</td><td>{{ item.age }}</td><td><!-- 1. 给slot标签,添加属性的方式传值 --><slot :row="item" msg="测试文本"></slot><!-- 2. 将所有的属性,添加到一个对象中 --><!-- {row: { id: 2, name: '孙大明', age: 19 },msg: '测试文本'}--></td></tr></tbody></table>
</template><script>
export default {props: {data: Array}
}
</script><style scoped>
.my-table {width: 450px;text-align: center;border: 1px solid #ccc;font-size: 24px;margin: 30px auto;
}
.my-table thead {background-color: #1f74ff;color: #fff;
}
.my-table thead th {font-weight: normal;
}
.my-table thead tr {line-height: 40px;
}
.my-table th,
.my-table td {border-bottom: 1px solid #ccc;border-right: 1px solid #ccc;
}
.my-table td:last-child {border-right: none;
}
.my-table tr:last-child td {border-bottom: none;
}
.my-table button {width: 65px;height: 35px;font-size: 18px;border: 1px solid #ccc;outline: none;border-radius: 3px;cursor: pointer;background-color: #ffffff;margin-left: 5px;
}
</style>
运行结果:
:data="list"
和 :data="list2"
的作用
MyTable
组件:MyTable
组件有一个名为data
的props
,其类型为数组,用于接收外部传入的数据。
export default {props: {data: Array}
}
- 父组件的数据:父组件里定义了两个数组
list
和list2
,它们各自包含了不同的数据项。
data () {return {list: [{ id: 1, name: '张小花', age: 18 },{ id: 2, name: '孙大明', age: 19 },{ id: 3, name: '刘德忠', age: 17 },],list2: [{ id: 1, name: '赵小云', age: 18 },{ id: 2, name: '刘蓓蓓', age: 19 },{ id: 3, name: '姜肖泰', age: 17 },]}
}
- 属性绑定:
:data="list"
:把父组件的list
数组传递给MyTable
组件的data
属性。这样,MyTable
组件就能使用list
数组里的数据进行渲染。:data="list2"
:把父组件的list2
数组传递给另一个MyTable
组件的data
属性。这个MyTable
组件会使用list2
数组里的数据进行渲染。
在 Vue 组件中,<slot :row="item" msg="测试文本"></slot>
涉及 插槽传值,用于向父组件使用插槽的区域传递数据,具体解释如下:
1. :row="item"
(动态属性绑定传值)
- 作用:通过动态绑定(
v-bind:
缩写:
),将子组件当前循环的item
数据(如{ id: 1, name: '张小花', age: 18 }
)作为名为row
的属性传递给父组件的插槽。 - 父组件接收:父组件通过
template #default="obj"
(或简化为template #default="{ row }"
)接收,obj
或row
即可获取子组件传递的item
数据。例如:<template #default="obj">
中,obj.row
即子组件传递的item
。<template #default="{ row }">
是解构赋值,直接通过row
访问item
。
2. msg="测试文本"
(普通属性传值)
- 作用:通过普通属性,将字符串
测试文本
作为名为msg
的属性传递给父组件的插槽。 - 父组件接收:父组件在插槽作用域内可通过
obj.msg
(若按template #default="obj"
接收)获取该值。例如:
<template #default="obj"><span>{{ obj.msg }}</span> <!-- 显示 "测试文本" -->
</template>
三、综合案例:商品列表
MyTable.vue
<template><table class="my-table"><thead><tr><slot name="head"></slot></tr></thead><tbody><tr v-for="(item, index) in data" :key="item.id"><slot name="body" :item="item" :index="index" ></slot></tr></tbody></table>
</template><script>
export default {props: {data: {type: Array,required: true}}
};
</script><style lang="less" scoped>.my-table {width: 100%;border-spacing: 0;img {width: 100px;height: 100px;object-fit: contain;vertical-align: middle;}th {background: #f5f5f5;border-bottom: 2px solid #069;}td {border-bottom: 1px dashed #ccc;}td,th {text-align: center;padding: 10px;transition: all .5s;&.red {color: red;}}.none {height: 100px;line-height: 100px;color: #999;}
}</style>
MyTag.vue
<template><div class="my-tag"><inputv-if="isEdit"v-focusref="inp"class="input"type="text"placeholder="输入标签":value="value"@blur="isEdit = false"@keyup.enter="handleEnter"/><div v-else@dblclick="handleClick"class="text">{{ value }}</div></div>
</template><script>
export default {props: {value: String},data () {return {isEdit: false}},methods: {handleClick () {// 双击后,切换到显示状态 (Vue是异步dom更新)this.isEdit = true// // 等dom更新完了,再获取焦点// this.$nextTick(() => {// // 立刻获取焦点// this.$refs.inp.focus()// })},handleEnter (e) {// 非空处理if (e.target.value.trim() === '') return alert('标签内容不能为空')// 子传父,将回车时,[输入框的内容] 提交给父组件更新// 由于父组件是v-model,触发事件,需要触发 input 事件this.$emit('input', e.target.value)// 提交完成,关闭输入状态this.isEdit = false}}
}
</script><style lang="less" scoped>
.my-tag {cursor: pointer;.input {appearance: none;outline: none;border: 1px solid #ccc;width: 100px;height: 40px;box-sizing: border-box;padding: 10px;color: #666;&::placeholder {color: #666;}}
}
</style>
App.vue
<template><div class="table-case"><MyTable :data="goods"><template #head><th>编号</th><th>名称</th><th>图片</th><th width="100px">标签</th></template><template #body="{ item, index }"><td>{{ index + 1 }}</td><td>{{ item.name }}</td><td><img:src="item.picture"/></td><td><MyTag v-model="item.tag"></MyTag></td></template></MyTable></div>
</template><script>
// my-tag 标签组件的封装
// 1. 创建组件 - 初始化
// 2. 实现功能
// (1) 双击显示,并且自动聚焦
// v-if v-else @dbclick 操作 isEdit
// 自动聚焦:
// 1. $nextTick => $refs 获取到dom,进行focus获取焦点
// 2. 封装v-focus指令// (2) 失去焦点,隐藏输入框
// @blur 操作 isEdit 即可// (3) 回显标签信息
// 回显的标签信息是父组件传递过来的
// v-model实现功能 (简化代码) v-model => :value 和 @input
// 组件内部通过props接收, :value设置给输入框// (4) 内容修改了,回车 => 修改标签信息
// @keyup.enter, 触发事件 $emit('input', e.target.value)// ---------------------------------------------------------------------// my-table 表格组件的封装
// 1. 数据不能写死,动态传递表格渲染的数据 props
// 2. 结构不能写死 - 多处结构自定义 【具名插槽】
// (1) 表头支持自定义
// (2) 主体支持自定义import MyTag from './components/MyTag.vue'
import MyTable from './components/MyTable.vue'
export default {name: 'TableCase',components: {MyTag,MyTable},data () {return {// 测试组件功能的临时数据tempText: '水杯',tempText2: '钢笔',goods: [{ id: 101, picture: 'https://yanxuan-item.nosdn.127.net/f8c37ffa41ab1eb84bff499e1f6acfc7.jpg', name: '梨皮朱泥三绝清代小品壶经典款紫砂壶', tag: '茶具' },{ id: 102, picture: 'https://yanxuan-item.nosdn.127.net/221317c85274a188174352474b859d7b.jpg', name: '全防水HABU旋钮牛皮户外徒步鞋山宁泰抗菌', tag: '男鞋' },{ id: 103, picture: 'https://yanxuan-item.nosdn.127.net/cd4b840751ef4f7505c85004f0bebcb5.png', name: '毛茸茸小熊出没,儿童羊羔绒背心73-90cm', tag: '儿童服饰' },{ id: 104, picture: 'https://yanxuan-item.nosdn.127.net/56eb25a38d7a630e76a608a9360eec6b.jpg', name: '基础百搭,儿童套头针织毛衣1-9岁', tag: '儿童服饰' },]}}
}
</script><style lang="less" scoped>
.table-case {width: 1000px;margin: 50px auto;img {width: 100px;height: 100px;object-fit: contain;vertical-align: middle;}
}</style>
main.js
import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = false// 封装全局指令 focus
Vue.directive('focus', {// 指令所在的dom元素,被插入到页面中时触发inserted(el) {el.focus()}
})new Vue({render: h => h(App),
}).$mount('#app')
四、路由入门
1.单页应用程序: SPA - Single Page Application
2.路由的介绍
3.VueRouter 的 介绍
4.VueRouter 的 使用 (5 + 2)
安装 vue-router
:在项目目录下运行以下命令安装 vue-router
:
npm install vue-router
或者使用 yarn
:
yarn add vue-router
main.js
import Vue from 'vue'
import App from './App.vue'// 路由的使用步骤 5 + 2
// 5个基础步骤
// 1. 下载 v3.6.5
// 2. 引入
// 3. 安装注册 Vue.use(Vue插件)
// 4. 创建路由对象
// 5. 注入到new Vue中,建立关联// 2个核心步骤
// 1. 建组件(views目录),配规则
// 2. 准备导航链接,配置路由出口(匹配的组件展示的位置)
import Find from './views/Find'
import My from './views/My'
import Friend from './views/Friend'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化const router = new VueRouter({// routes 路由规则们// route 一条路由规则 { path: 路径, component: 组件 }routes: [{ path: '/find', component: Find },{ path: '/my', component: My },{ path: '/friend', component: Friend },]
})Vue.config.productionTip = falsenew Vue({render: h => h(App),router
}).$mount('#app')
App.vue
<template><div><div class="footer_wrap"><a href="#/find">发现音乐</a><a href="#/my">我的音乐</a><a href="#/friend">朋友</a></div><div class="top"><!-- 路由出口 → 匹配的组件所展示的位置 --><router-view></router-view></div></div>
</template><script>
export default {};
</script><style>
body {margin: 0;padding: 0;
}.footer_wrap {position: relative;left: 0;top: 0;display: flex;width: 100%;text-align: center;background-color: #333;color: #ccc;
}.footer_wrap a {flex: 1;text-decoration: none;padding: 20px 0;line-height: 20px;background-color: #333;color: #ccc;border: 1px solid black;
}.footer_wrap a:hover {background-color: #555;
}
</style>
Find.vue
<template><div><p>发现音乐</p><p>发现音乐</p><p>发现音乐</p><p>发现音乐</p></div>
</template><script>
export default {name: 'FindMusic'
}
</script><style></style>
Friend.vue
<template><div><p>我的朋友</p><p>我的朋友</p><p>我的朋友</p><p>我的朋友</p></div>
</template><script>
export default {name: 'MyFriend'
}
</script><style></style>
My.vue
<template><div><p>我的音乐</p><p>我的音乐</p><p>我的音乐</p><p>我的音乐</p></div>
</template><script>
export default {name: 'MyMusic'
}
</script><style></style>
5.组件存放目录问题
组件存放目录问题 (组件分类)
相关文章:
Vue高级特性实战:自定义指令、插槽与路由全解析
一、自定义指令 1.如何自定义指令 ⑴.全局注册语法 通过 Vue.directive 方法注册,语法格式为: Vue.directive(指令名, {// 钩子函数,元素插入父节点时触发(仅保证父节点存在,不一定已插入文档)inserted(…...
Python入门:流程控制练习
本文将介绍Python中流程控制的基础知识,包括条件判断和循环结构,并提供多个实用示例帮助初学者快速掌握这些概念。所有代码都使用基础语法,非常适合Python新手学习。 1. 简单条件判断: 编写一个程序,要求用户输入一个…...
Unity PBR基础知识
PBR原理 基于物理的渲染(Physically Based Rendering,PBR)是指使用基于物理原理和微平面理论建模的着色/光照模型,以及使用从现实中测量的表面参数来准确表示真实世界材质的渲染理念。 PBR基础理念 微平面理论(Micr…...
智慧交警系统架构设计方案
一、引言:智慧交警为何成为城市治理的刚需? 当前,中国城市化进程加速,汽车保有量激增,交通拥堵、事故频发、执法效率不足等问题日益突出。传统交通管理依赖人力巡查与分散系统,已难以应对复杂需求。智慧交…...
NOC科普一
拓扑结构 NoC里Router之间的link链路连接可以定义成不同的结构以改变通信测量和简化片上通信结构。 (a)Ring:环形,每个router都有2个相邻节点,虽然部署和故障排除相对容易,但主要缺点是其通信的距离也即环…...
Linux CentOS 7 安装Apache 部署html页面
*、使用yum包管理器安装Apache。运行以下命令: sudo yum install httpd *、启动Apache服务 sudo systemctl start httpd *、设置Apache服务开机自启 sudo systemctl enable httpd *、验证Apache是否运行 sudo systemctl status httpd 或者,通过浏…...
人工智能在医疗行业的应用和发展前景
人工智能在医疗行业的应用和发展前景 引言 在科技日新月异的今天,人工智能(Artificial Intelligence,AI)已然成为全球最具潜力与影响力的技术之一。医疗行业,作为关乎人类健康与生命的关键领域,正迅速成为人工智能应用的热门阵地。人工智能在医疗领域的应用,不仅为解决…...
vue3+Nest.js项目 部署阿里云
可以先参考之前的vue3express部署的文章 vue3viteexpressmongoDB上线(新手向)_vue3 vite express-CSDN博客 区别在于express和数据库 前端前往上面文章查看 1.nest.js部署 首先,把nest.js中相关的文件打包 除去依赖(node_modules)上传到服…...
phpstudy修改Apache端口号
1. 修改Listen.conf文件 本地phpstudy安装目录: 2.其他问题 ① 修改httpd.conf不起作用 ② 直接通过控制面板配置好像有延迟缓存...
JSON-RPC 2.0 规范中文版——无状态轻量级远程过程调用协议
前言 JSON-RPC是一种简单、轻量且无状态的远程过程调用(RPC)协议,它允许不同系统通过标准化的数据格式进行通信。自2010年由JSON-RPC工作组发布以来,已成为众多应用中实现远程交互的基础协议之一。本规范主要表达了JSON-RPC 2.0版…...
DeepSeek+Dify之七借助API和Trae完成demo
DeepSeek+Dify之六通过API调用工作流 文章目录 背景准备资料1、借助Trae来创建demo2、前后端主要代码3、测试demo4、完整项目背景 在软件开发与项目实践领域,常常需要借助各种工具与技术来快速搭建可运行的示例项目,以验证思路、展示功能或进行技术探索。本文聚焦于借助 Tra…...
C++ 红黑树
上一节我介绍了二叉搜索树家族的AVL树,这里我们来介绍二叉搜索树家族的另一个成员,也是使用最广泛的成员。 1.AVL树与红黑树的区别 平衡性质 AVL 树:是严格的平衡二叉树,要求任意节点的左右子树高度差的绝对值不超过 1ÿ…...
学习海康VisionMaster之线圆测量
一:进一步学习了 今天学习下VisionMaster中的线圆测量:核心就是坐标点到直线的距离量测 1:什么是线圆测量? 工业自动化中很常见的应用尺寸测量,需要量测一个零件的外形尺寸,其中一项如果是需要测量圆心到直…...
Uniapp:置顶
目录 一、出现场景二、效果展示三、具体使用一、出现场景 在项目的开发过程中,我们经常会用到置顶的功能,比如说从页面的最下方滑动到最上面太慢了,这个时候我们就可以使用置顶功能。 二、效果展示 三、具体使用 参数名类型必填说明scrollTopNumber否滚动到页面的目标位置…...
UDP数据报和TCP流套接字编程
文章目录 UDP数据报套接字编程1.DatagramSocket类2.DatagramPacket类3. InetSocketAddress类构建服务端和客户端 TCP流套接字编程1. ServerSocket类2.Socket类构建服务端和客户端 扩展对话形式简易的字典多线程实现线程池实现 UDP数据报套接字编程 1.DatagramSocket类 Datagr…...
某建筑石料用灰岩矿自动化监测
1. 项目简介 某建材有限公司成立于2012年,是一家集矿山开采、石料生产及销售为一体的建筑材料生产企业,拥有两条年产500万吨的环保型精品骨料生产线,各类工程机械 30 多台套,运输车辆50多辆。公司坚持生态优先,以高质…...
C++11 的编译器支持
C11 主要功能特性一览 特性描述提案GCCClangMSVCApple ClangEDG eccpIntel CNvidia HPC C (ex PGI)*Nvidia nvccCrayEmbarcadero C BuilderIBM Open XL C for AIXIBM Open XL C for z/OSIBM XL CSun/Oracle CHP aCCDigital Mars C核心功能右值引用 (T&&)支持移动语义和…...
20250429 垂直地表发射激光测量偏转可以验证相对性原理吗
垂直地表发射激光测量偏转可以验证相对性原理吗 垂直地表发射激光测量偏转可以在一定条件下用于检验广义相对论中的等效原理和引力对光传播的影响,但要说直接验证整个相对性原理(狭义广义)是不准确的。我们可以逐步分析这个问题:…...
Makefile 在 ARM MCU 开发中的编译与链接参数详解与实践
内容大纲 引言 一、预处理与宏定义 头文件搜索路径:-I 宏定义:-D 二、编译器选项(CFLAGS) 架构与指令集:-mcpu、-mthumb 优化与调试:-Os、-O2、-g 警告与错误:-Wall、-Werror 代码剥离:-ffunction-sections、-fdata-sections 其他常用选项 三、链接器选项(LDFLAGS) 链…...
AimRT 从零到一:官方示例精讲 —— 四、logger示例.md
logger示例 官方仓库:logger 配置文件(configuration_logger.yaml) 依据官方示例项目结构自行编写YAML配置文件: # 基础信息 base_info:project_name: Logger # 项目名称build_mode_tags: ["EXAMPLE", "SIMULATION", "TE…...
mybatis传递多个不同类型的参数到mapper xml文件
在业务中查询某张表时需要设置多个查询条件,并且还要根据id列表进行权限过滤,这时推荐采用Map<String, Object>作为参数进行查询,因为:Object可以设置成不同的类型,比如:List<Integer> ids&…...
信创开发中的数据库详解:国产替代背景下的技术生态与实践指南
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开…...
【Linux】第十三章 访问Linux文件系统
目录 1. 存储设备是什么?怎么理解分区和格式化? 2. 文件系统是什么? 3. 挂载是什么?挂载点是什么? 4. 怎么理解块设备? 5. 在SATA附加存储中,第一磁盘上的第一个分区和第二磁盘的第二个分区…...
多态与虚函数
在 C 中,virtual 关键字用于实现多态性(Polymorphism),这是面向对象编程(OOPP)的核心特性之一。多态性允许你编写通用的代码,该代码可以操作不同类型的对象,而这些对象可以有不同的内…...
Spring Boot - 配置管理与自动化配置进阶
Spring Boot 的配置管理和自动化配置是其核心特性之一,能够显著提升开发效率和应用灵活性。本文将深入探讨以下内容: 1、配置管理:多环境配置与优先级解析。 2、自动化配置:自定义 Spring Boot Starter 与 spring.factories 扩展…...
第六章 QT基础:7、Qt中多线程的使用
在进行桌面应用程序开发时,假设应用程序需要处理比较复杂的逻辑,如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。 这种情况下,需要使用多线程: 主线程处理窗口事件和控件更新子线程进…...
前端Vue3 + 后端Spring Boot,前端取消请求后端处理逻辑分析
在 Vue3 Spring Boot 的技术栈下,前端取消请求后,后端是否继续执行业务逻辑的答案仍然是 取决于请求处理的阶段 和 Spring Boot 的实现方式。以下是结合具体技术的详细分析: 1. 请求未到达 Spring Boot 场景:前端通过 AbortContr…...
ShaderToy学习笔记 05.3D旋转
1. 3D旋转 1.1. 汇制立方体 由于立方体没有旋转,所以正对着看过去时,看起来是正方形的,所以需要旋转一下,才能看到立方体的样子。 常见几何体的SDF BOX 的SDF为 float sdBox( vec3 p, vec3 b ) {vec3 q abs(p) - b;return len…...
编程日志4.24
栈的链表基础表示结构 #include<iostream> #include<stdexcept> using namespace std; //模板声明,表明Stack类是一个通用的模板,可以用于存储任何类型的元素T template<typename T> //栈的声明 //Stack类的声明,表示一…...
通信设备制造数字化转型中的创新模式与实践探索
在数字化浪潮下,通信设备制造企业积极探索创新模式,推动数字化转型,以提升竞争力和适应市场变化。 在生产模式创新方面,企业引入工业互联网平台,实现设备互联互通与生产过程智能化监控。通过在生产设备上安装传感器&a…...
同一个路由器接口eth0和ppp0什么不同?
答案摘自 百度知道, eth0是以太网接口,是表示以太网连接的物理接口,路由器可能会有不止一个以太网接口,因此可能会eth0,eht1之类的。 ppp0是经以太网接口PPP拨号时创建的链路接口,用以建PPP拨号连接的&am…...
零训练成本优化LLM: 11种LLM权重合并策略原理与MergeKit实战配置
随着大语言模型的快速发展,如何在不消耗大量计算资源的情况下优化模型性能成为业界关注焦点。模型权重合并技术提供了一种零训练成本的高效解决方案,能够智能整合多个专业微调模型的优势,无需额外训练即可显著提升性能表现。本文系统剖析11种…...
基于tabula对pdf中多个excel进行识别并转换成word中的优化(五)
优化地方:处理合并的单元格内容。 1、修改为stream"complex" 2、增加换行符f"{table_data[i - 1][j]}\n{table_data[i][j]}".strip() 一、pdf中excel样例 二、完整代码 import tabula import numpy as np from docx import Document from docx…...
QT中的网络编程
Qt中的网络编程是通过封装操作系统的API进行实现的 C标准库中,并没有提供网络编程的封装接口 进行网络编程时本质是在编写应用层代码,需要传输层提供支持 传输层最核心的协议为UDP/TCP 使用Qt网络编程的API时,需要在.pro文件中添加network模块…...
0.5 像素边框实现
0.5 像素边框怎么实现 文章目录 0.5 像素边框怎么实现方法 1:使用 transform: scale() 缩放(推荐)方法 2:直接使用 0.5px 边框(部分浏览器支持)方法 3:使用 box-shadow 模拟边框方法 4ÿ…...
【Vagrant+VirtualBox创建自动化虚拟环境】Ansible测试Playbook
文章目录 Vagrant安装vagrant安装 VirtualBox如何使用 Ansible安装AnsiblePlaybook测试创建hosts文件创建setup.yml文件 Vagrant Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境。它使用Oracle的开源VirtualBox虚拟化系统,使用 Chef创建自动…...
“连接世界的桥梁:深入理解计算机网络应用层”
一、引言 当你浏览网页、发送邮件、聊天或观看视频时,这一切都离不开计算机网络中的应用层(Application Layer)。 应用层是网络协议栈的最顶层,直接为用户的各种应用程序提供服务。它为用户进程之间建立通信桥梁,屏蔽了…...
Vulkan与OpenGL的对比
传统图形API与现代图形API 传统图形API指的是OpenGL/DirectX11这类简单易用、驱动托管严重的图形接口;而现代图形API则指的是Vulkan/Metal/DirectX12这类使用复杂、暴露更多底层硬件功能来显式控制的弱驱动设计的图形接口。 现代图形API与传统图形API相比ÿ…...
海外社交App的Web3革命:去中心化社交与Token经济实战指南
一、Web3社交的核心组件:从身份到经济的重构 去中心化身份(DID)技术栈:Ceramic IDX协议构建链上身份图谱代码示例:javascript// 创建DID const ceramic new CeramicClient() const did new DID({ provider: cerami…...
凯撒密码算法的实现
在密码学里,凯撒密码(也叫恺撒密码、移位密码、恺撒代码或者恺撒移位)是一种简单且广为人知的加密技术。它属于替换密码的一种,在这种加密方式中,明文中的每个字母都会被替换成字母表中往后移动固定位数的字母。例如&a…...
Chrome的插件扩展程序安装目录是什么?在哪个文件夹?
目录 前提 直接复制到浏览器中打开 Mac下Chrome extension 安装路径 最近换了mac pro用起来虽然方便,但是对常用的一些使用方法还是不熟悉。这不为了找到mac上chrome插件的安装路径在哪里,花费了不少时间。我想应用有不少像小编一样刚刚使用mac的小白…...
C++23中的std::forward_like:完美转发的增强
文章目录 一、背景与动机(一)完美转发的局限性(二)std::forward_like的提出 二、std::forward_like的设计与实现(一)基本语法(二)实现原理(三)与std::forward…...
AI与软件测试的未来:如何利用智能自动化改变测试流程
用工作流生成测试用例和自动化测试脚本! 随着人工智能(AI)技术的迅猛发展,软件测试作为软件开发生命周期中的关键环节,正在经历一场前所未有的变革。传统的测试方法已经无法满足现代快速迭代和持续交付的需求ÿ…...
React Native 动态切换主题
React Native 动态切换主题 创建主题配置和上下文创建主题化高阶组件主应用组件主屏幕组件(类组件形式) 创建主题配置和上下文 // ThemeContext.jsimport React, { Component, createContext } from react;import { Appearance, AsyncStorage } from rea…...
得物 小程序 6宫格 分析
声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 逆向过程 部分python代码 if result …...
PocketFlow一个最小的Agent框架
1、背景 PocketFlow 2、使用 python 的版本需要python3.10 在cookbook中有如何使用的说明,如图所示 在tuils.py中修改代码 def call_llm(messages):# client OpenAI(api_keyos.environ.get("OPENAI_API_KEY", "your-api-key"))client Op…...
Objective-C Block 底层原理深度解析
Objective-C Block 底层原理深度解析 1. Block 是什么? 1.1 Block 的本质 Block 是 Objective-C 中的特殊对象,实现了匿名函数的功能 通过 isa 指针继承自 NSObject,可以响应(如 copy、retain、release)等内存管理方…...
AlDente Pro for Mac电脑 充电限制保护工具 安装教程【简单,轻松上手】
AlDente Pro for Mac电脑 充电限制保护工具 安装教程【简单,轻松上手】 AlDente Pro for Mac,是一款充电限制保护工具,是可以限制最大充电百分比来保护电池的工具。锂离子和聚合物电池(如 MacBook 中的电池)在40&…...
Linux systemd 从理论到实践:现代系统管理的核心工具
文章目录 引言:为什么需要 systemd?第一部分:systemd 核心理论1.1 systemd 的设计哲学1.2 核心组件1.3 单元文件(Unit File)结构 第二部分:实战操作指南2.1 基础命令2.2 服务管理高级操作2.3 日志管理&…...
分享一个移动端项目模板:React-Umi4-mobile
分享一个移动端项目模板:React-Umi4-mobile 大家好,今天想和大家分享一个我最近做的移动端项目模板 React-Umi4-mobile。 模板的主要内容 这个模板主要包括: 基于 Umi 4 框架使用了 antd-mobile 组件库配置了 px 自动转 vw(基…...