VueRouter使用详解(5000字通关大全)
Vue Router是一个官方的路由管理器,它可以让我们在Vue应用中实现单页面应用(SPA)的效果,即通过改变URL而不刷新页面来显示不同的内容。Vue Router可以让我们定义多个路由,每个路由对应一个组件,当URL匹配到某个路由时,就会渲染对应的组件。Vue Router还提供了很多高级功能,如嵌套路由、动态路由、命名路由、导航守卫、路由元信息等,让我们可以更灵活地控制路由的行为和状态。
在本文中,我们将介绍Vue Router的基本使用方法,以及一些常用的API和技巧。我们假设你已经有了一些Vue的基础知识,如果不熟悉Vue,请先阅读官方文档。本文使用的Vue Router版本是4.x,这是目前最新的版本,它支持Vue 3.x,并且有一些重要的变化和改进。如果你还在使用旧版本,请参考旧版文档,做好兼容处理。
公众号:Code程序人生,个人网站:https://creatorblog.cn
安装和引入
要使用Vue Router,首先需要安装它。你可以通过npm或yarn来安装:
# npm
npm install vue-router# yarn
yarn add vue-router
然后,在你的入口文件(通常是main.js)中引入并创建一个路由实例:
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './App.vue'// 定义路由配置,每个路由映射一个组件
const routes = [{ path: '/', component: Home },{ path: '/about', component: About },// ...其他路由
]// 创建一个路由实例,使用history模式
const router = createRouter({history: createWebHistory(),routes, // 等价于routes: routes
})// 创建一个Vue应用实例,并挂载到#app元素上
const app = createApp(App)// 将路由实例注入到应用实例中
app.use(router)// 挂载应用
app.mount('#app')
这里有几点需要注意:
Vue Router 4.x使用了函数式的API来创建路由实例,而不是像3.x那样使用new VueRouter()构造函数。这样可以避免全局污染和依赖注入的问题。Vue Router 4.x支持三种模式:history、hash和memory。其中history模式是推荐的模式,它使用HTML5 History API来实现无刷新的URL切换。要使用history模式,需要调用createWebHistory()函数来创建一个history对象,并传递给createRouter()函数。如果你想使用hash模式或memory模式,请分别调用createWebHashHistory()或createWebMemoryHistory()函数。- 路由配置是一个数组,每个元素是一个对象,表示一个路由。每个路由对象至少需要有两个属性:
path和component。path是一个字符串,表示URL路径;component是一个组件,表示要渲染的内容。你可以在routes数组中定义任意多个路由对象。 - 要将路由实例注入到应用实例中,需要调用
app.use(router)方法。这样就可以在应用中使用路由相关的功能了。
使用router-link和router-view
有了路由实例和配置之后,我们就可以在应用中使用router-link和router-view两个组件了。router-link是一个特殊的组件,它会渲染成一个a标签,并且可以自动添加或移除active类名来表示当前激活的路由。router-link接受一个to属性,表示要跳转的目标路径。例如:
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
这会渲染成:
<a href="/" class="router-link-active">Home</a>
<a href="/about">About</a>
当URL变化时,router-link会自动更新active类名,以及对应的样式。你可以通过active-class属性来自定义active类名,或者通过exact属性来控制是否需要完全匹配路径。
router-view是另一个特殊的组件,它会根据当前匹配的路由来渲染对应的组件。你可以把它放在任何地方,通常是放在App组件的模板中,作为一个占位符。例如:
<template><div id="app"><h1>Vue Router Demo</h1><nav><router-link to="/">Home</router-link><router-link to="/about">About</router-link></nav><!-- 这里会渲染匹配到的组件 --><router-view></router-view></div>
</template>
当URL变化时,router-view会自动更新渲染的组件,以及对应的生命周期钩子。你可以通过name属性来给router-view命名,以便在嵌套路由中使用。
使用动态路由和命名路由
有时候,我们需要根据URL中的参数来渲染不同的组件,例如用户的个人主页或者文章的详情页。这时候,我们可以使用动态路由来实现。动态路由是指在path中使用冒号(:)来表示一个参数,例如:
const routes = [// ...其他路由// 动态路由,匹配/user/任意值{ path: '/user/:id', component: User },// 动态路由,匹配/post/任意值{ path: '/post/:slug', component: Post },
]
这样,当URL为/user/123或/post/hello-world时,就会匹配到对应的路由,并渲染User或Post组件。在组件中,我们可以通过$route.params对象来获取动态路由参数的值,例如:
<template><div class="user"><h2>User {{ $route.params.id }}</h2></div>
</template>
或者:
<template><div class="post"><h2>Post {{ $route.params.slug }}</h2></div>
</template>
当然,我们也可以给动态路由参数添加一些限制,例如正则表达式。这样可以避免匹配到不合法的值。例如:
const routes = [// ...其他路由// 动态路由,只匹配/user/数字{ path: '/user/:id(\\d+)', component: User },
]
这样,当URL为/user/abc时,就不会匹配到该路由了。
除了使用path来定义路由,我们还可以使用name来给路由命名。命名路由可以让我们在跳转或链接时更方便地引用路由,而不用担心path的变化。例如:
const routes = [// ...其他路由// 命名路由{ path: '/user/:id', name: 'user', component: User },
]
这样,在router-link中,我们就可以使用name属性来指定目标路由,并且通过params属性来传递动态路由参数。例如:
<router-link :to="{ name: 'user', params: { id: 123 }}">User 123</router-link>
这会渲染成:
<a href="/user/123">User 123</a>
同样,在编程式导航中,我们也可以使用name和params来跳转到目标路由。例如:
// 在组件中
this.$router.push({ name: ‘user’, params: { id: 456 }})// 这会跳转到 /user/456
使用命名路由的好处是,我们可以在任何地方修改路由的path,而不用担心影响到其他地方的引用。只要保持路由的name不变,就可以保证路由的正确性。
使用嵌套路由和命名视图
有时候,我们需要在一个页面中显示多个组件,或者在一个组件中嵌套另一个组件。这时候,我们可以使用嵌套路由和命名视图来实现。嵌套路由是指在一个路由对象中使用children属性来定义子路由,例如:
const routes = [// ...其他路由// 嵌套路由{path: '/user/:id',component: User,children: [// 当URL为/user/:id/profile时,渲染UserProfile组件{ path: 'profile', component: UserProfile },// 当URL为/user/:id/posts时,渲染UserPosts组件{ path: 'posts', component: UserPosts },]}
]
这样,当URL为/user/123/profile或/user/123/posts时,就会匹配到对应的子路由,并渲染User组件和UserProfile或UserPosts组件。注意,子路由的path不需要加斜杠(/),因为它是相对于父路由的path来解析的。
要在父组件中渲染子组件,我们需要在父组件的模板中使用router-view作为占位符。例如:
<template><div class="user"><h2>User {{ $route.params.id }}</h2><!-- 这里会渲染子组件 --><router-view></router-view></div>
</template>
如果我们想要同时显示多个组件,而不是嵌套显示,我们可以使用命名视图来实现。命名视图是指给router-view添加一个name属性来区分不同的视图,并且在路由配置中使用components属性来指定多个组件。例如:
const routes = [// ...其他路由// 命名视图{path: '/dashboard',components: {default: Dashboard,sidebar: Sidebar,header: Header,}}
]
这样,当URL为/dashboard时,就会匹配到该路由,并渲染Dashboard、Sidebar和Header三个组件。注意,components是一个对象,它的键是router-view的name属性,它的值是对应的组件。如果没有指定name属性,默认为default。
要在应用中使用命名视图,我们需要在模板中使用多个router-view并给它们添加name属性。例如:
<template><div id="app"><!-- 这里会渲染Header组件 --><router-view name="header"></router-view><div class="main"><!-- 这里会渲染Sidebar组件 --><router-view name="sidebar"></router-view><!-- 这里会渲染Dashboard组件 --><router-view></router-view></div></div>
</template>
当然,我们也可以将嵌套路由和命名视图结合起来使用,以实现更复杂的布局和导航。例如:
const routes = [// ...其他路由// 嵌套路由和命名视图{path: '/user/:id',component: User,children: [{path: 'profile',components: {default: UserProfile,sidebar: UserSidebar,}},{path: 'posts',components: {default: UserPosts,sidebar: UserSidebar,}},]}
]
这样,当URL为/user/123/profile或/user/123/posts时,就会匹配到对应的子路由,并渲染User、UserProfile或UserPosts和UserSidebar三个组件。注意,子路由的components也是一个对象,它的键是router-view的name属性,它的值是对应的组件。
要在父组件中使用命名视图,我们也需要在模板中使用多个router-view并给它们添加name属性。例如:
<template><div class="user"><h2>User {{ $route.params.id }}</h2><!-- 这里会渲染UserSidebar组件 --><router-view name="sidebar"></router-view><!-- 这里会渲染UserProfile或UserPosts组件 --><router-view></router-view></div>
</template>
使用导航守卫和路由元信息
有时候,我们需要在路由跳转时进行一些控制或处理,例如验证用户权限、显示加载提示、记录访问日志等。这时候,我们可以使用导航守卫来实现。导航守卫是一些函数,它们会在路由跳转前后被调用,让我们可以拦截或修改路由的行为。Vue Router提供了三种类型的导航守卫:全局守卫、路由独享守卫和组件内守卫。
全局守卫是指在路由实例上注册的守卫,它们会在任何路由跳转时被调用。全局守卫有三种:beforeEach、beforeResolve和afterEach。beforeEach守卫会在路由跳转前被调用,我们可以在这里进行一些权限验证或数据预处理。例如:
// 在创建路由实例之后
router.beforeEach((to, from, next) => {// to是目标路由对象,from是来源路由对象,next是一个函数// 检查目标路由是否需要登录if (to.meta.requiresAuth) {// 检查用户是否已经登录if (store.state.user) {// 已经登录,放行next()} else {// 没有登录,跳转到登录页next({ path: '/login' })}} else {// 不需要登录,放行next()}
})
这里,我们使用了to.meta属性来判断目标路由是否需要登录。meta属性是一个自定义的对象,我们可以在路由配置中给每个路由添加一些元信息,例如:
const routes = [// ...其他路由// 需要登录的路由{ path: '/profile', component: Profile, meta: { requiresAuth: true }},// 不需要登录的路由{ path: '/login', component: Login },
]
这样,在beforeEach守卫中,我们就可以根据meta属性来进行不同的处理。注意,在beforeEach守卫中,我们必须调用next函数来决定是否放行或重定向。next函数可以接受一个参数,表示要跳转的目标路径或路由对象。如果不传递参数,则表示放行当前的跳转。
beforeResolve守卫和beforeEach守卫类似,但是会在所有异步组件被解析后才被调用。我们可以在这里进行一些最后的检查或处理。例如:
// 在创建路由实例之后
router.beforeResolve((to, from, next) => {// to是目标路由对象,from是来源路由对象,next是一个函数// 显示加载提示store.commit('showLoading')// 放行next()
})
afterEach守卫会在路由跳转后被调用,我们可以在这里进行一些收尾工作或清理工作。例如:
// 在创建路由实例之后
router.afterEach((to, from) => {// to是目标路由对象,from是来源路由对象// 隐藏加载提示store.commit(‘hideLoading’);// 记录访问日志store.dispatch(‘logVisit’, { to, from }) });
路由独享守卫是指在路由配置中定义的守卫,它们只会在匹配到该路由时被调用。路由独享守卫有两种:beforeEnter和beforeLeave。beforeEnter守卫会在进入该路由前被调用,我们可以在这里进行一些特定的处理或拦截。例如:
const routes = [// ...其他路由// 路由独享守卫{path: '/admin',component: Admin,beforeEnter: (to, from, next) => {// to是目标路由对象,from是来源路由对象,next是一个函数// 检查用户是否是管理员if (store.state.user.role === 'admin') {// 是管理员,放行next()} else {// 不是管理员,跳转到首页next({ path: '/' })}}}
]
这里,我们使用了beforeEnter守卫来判断用户是否有权限访问/admin路由。注意,在beforeEnter守卫中,我们也必须调用next函数来决定是否放行或重定向。
beforeLeave守卫会在离开该路由前被调用,我们可以在这里进行一些确认或保存工作。例如:
const routes = [// ...其他路由// 路由独享守卫{path: '/edit/:id',component: Edit,beforeLeave: (to, from, next) => {// to是目标路由对象,from是来源路由对象,next是一个函数// 检查编辑内容是否已经保存if (this.$refs.editor.isSaved()) {// 已经保存,放行next()} else {// 没有保存,弹出确认框if (window.confirm('您的编辑内容尚未保存,确定要离开吗?')) {// 确定离开,放行next()} else {// 取消离开,中断跳转next(false)}}}}
]
这里,我们使用了beforeLeave守卫来提示用户是否要保存编辑内容。注意,在beforeLeave守卫中,我们也必须调用next函数来决定是否放行或中断。如果传递false作为参数,则表示中断当前的跳转。
组件内守卫是指在组件选项中定义的守卫,它们只会在该组件被渲染时被调用。组件内守卫有三种:beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave。beforeRouteEnter守卫会在渲染该组件前被调用,我们可以在这里进行一些数据获取或处理。例如:
<template><div class="post"><h2>{{ post.title }}</h2><p>{{ post.content }}</p></div>
</template><script>
export default {data() {return {post: null,}},beforeRouteEnter(to, from, next) {// to是目标路由对象,from是来源路由对象,next是一个函数// 获取文章数据fetch(`/api/posts/${to.params.id}`).then(res => res.json()).then(data => {// 将数据传递给组件实例next(vm => vm.post = data)})},
}
</script>
这里,我们使用了beforeRouteEnter守卫来获取文章数据,并将其传递给组件实例。注意,在beforeRouteEnter守卫中,我们无法访问this,因为组件实例还没有被创建。所以我们需要通过next函数的回调来访问组件实例。
beforeRouteUpdate守卫会在当前路由发生变化时被调用,但是该组件被复用时才会触发。我们可以在这里进行一些数据更新或处理。例如:
<template><div class="post"><h2>{{ post.title }}</h2><p>{{ post.content }}</p></div>
</template><script>
export default {data() {return {post: null,}},beforeRouteEnter(to, from, next) {// ...省略},beforeRouteUpdate(to, from, next) {// to是目标路由对象,from是来源路由对象,next是一个函数// 获取新的文章数据fetch(`/api/posts/${to.params.id}`).then(res => res.json()).then(data => {// 更新组件实例的数据this.post = data// 放行next()})},
}
</script>
这里,我们使用了beforeRouteUpdate守卫来获取新的文章数据,并更新组件实例的数据。注意,在beforeRouteUpdate守卫中,我们可以访问this,因为组件实例已经被创建并复用。同样,在beforeRouteUpdate守卫中,我们也必须调用next函数来决定是否放行或重定向。
beforeRouteLeave守卫会在离开该组件时被调用,我们可以在这里进行一些确认或保存工作。例如:
<template><div class="edit"><h2>编辑文章</h2><textarea ref="editor">{{ post.content }}</textarea><button @click="save">保存</button></div>
</template><script>
export default {data() {return {post: null,saved: false,}},beforeRouteEnter(to, from, next) {// ...省略},beforeRouteLeave(to, from, next) {// to是目标路由对象,from是来源路由对象,next是一个函数// 检查编辑内容是否已经保存if (this.saved) {// 已经保存,放行next()} else {// 没有保存,弹出确认框if (window.confirm('您的编辑内容尚未保存,确定要离开吗?')) {// 确定离开,放行next()} else {// 取消离开,中断跳转next(false)}}},methods: {save() {// ...省略this.saved = true}}
}
</script>
这里,我们使用了beforeRouteLeave守卫来提示用户是否要保存编辑内容。注意,在beforeRouteLeave守卫中,我们也必须调用next函数来决定是否放行或中断。
使用的注意事项
在使用Vue Router时,还有一些注意事项需要了解:
- 如果你想使用
HTML5 History模式,你需要配置你的服务器来支持该模式。具体来说,就是让服务器对于所有的请求都返回index.html文件,以便让Vue Router接管路由的处理。你可以参考官方文档中的相关说明来配置你的服务器。 - 如果你想使用
hash模式,你需要注意URL中的hash值可能会影响到锚点的功能。如果你想使用锚点来定位到页面中的某个元素,你需要在路由配置中使用scrollBehavior属性来自定义滚动行为。你可以参考官方文档中的相关示例来实现你的需求。 - 如果你想使用
memory模式,你需要注意该模式不会改变URL,也不会记录历史记录。这意味着用户无法通过浏览器的前进或后退按钮来导航路由,也无法通过刷新页面来保持当前状态。该模式适合一些不需要URL和历史记录的场景,例如移动端应用或小程序。 - 如果你想在组件中访问路由相关的信息或功能,你可以通过
this.$route和this.$router两个属性来实现。 this.$route是一个只读的对象,它包含了当前激活的路由的信息,例如path、params、query、meta等。你可以通过this.$route来获取或监视路由的变化,以便进行一些响应式的操作。
<template><div class="user"><h2>User {{ $route.params.id }}</h2><!-- 根据路由的query参数来显示不同的内容 --><div v-if="$route.query.active"><p>This user is active.</p></div><div v-else><p>This user is inactive.</p></div></div>
</template>
this.$router是一个可读写的对象,它是路由实例的引用,它包含了一些方法和属性,让我们可以在组件中控制路由的跳转或状态。
<template><div class="post"><h2>{{ post.title }}</h2><p>{{ post.content }}</p><!-- 使用router-link来跳转到上一篇或下一篇文章 --><nav><router-link :to="{ name: 'post', params: { id: prevId }}">Prev</router-link><router-link :to="{ name: 'post', params: { id: nextId }}">Next</router-link></nav><!-- 使用router.go来后退或前进 --><button @click="$router.go(-1)">Back</button><button @click="$router.go(1)">Forward</button></div>
</template><script>
export default {data() {return {post: null,prevId: null,nextId: null,}},beforeRouteEnter(to, from, next) {// ...省略},beforeRouteUpdate(to, from, next) {// ...省略},methods: {// 使用router.push来跳转到编辑页edit() {this.$router.push({ name: 'edit', params: { id: this.post.id }})}}
}
</script>
总结
以上就是Vue Router的基本使用方法,以及一些常用的API和技巧。Vue Router是一个非常强大和灵活的路由管理器,它可以让我们在Vue应用中实现各种复杂和高效的导航功能。
相关文章:
VueRouter使用详解(5000字通关大全)
Vue Router是一个官方的路由管理器,它可以让我们在Vue应用中实现单页面应用(SPA)的效果,即通过改变URL而不刷新页面来显示不同的内容。Vue Router可以让我们定义多个路由,每个路由对应一个组件,当URL匹配到…...
vue axios实现下载文件及responseType:blob注意事项
需要使用axios和js-file-download组件 npm install js-file-download --save npm install axios --save import fileDownload from fileDownload; // 引入fileDownload import axios from axios; // 引入axios axios({method: get,url: xxxxxxx,responseType: blob }).then(r…...
StringBuilder类分享(1)
一、StringBuilder说明 StringBuilder是一个可变的字符序列。这个类提供了一个与StringBuffer兼容的API,但不保证同步,即StringBuilder不是线程安全的,而StringBuffer是线程安全的。显然,StringBuilder要运行的更快一点。 这个类…...
Qt 打开文件列表选择文件,实现拖拽方式打开文件
1. 实现打开文件列表选择文件 1.1. 创建 Qt 工程,并添加几个简单控件 这里笔者选用的是 QMainWindow,创建好工程后在 ui 界面设计中添加 QLineEdit、QPushBtton至少这两个控件,如下图摆放。 1.2. 头文件中添加相关操作 在 mainwindow.h 中…...
[C/C++]天天酷跑游戏超详细教程-上篇
个人主页:北海 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏✨收录专栏:C/C🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!ǹ…...
5G NR:RACH流程 -- Msg1之选择正确的PRACH时频资源
PRACH的时域资源是如何确定的 PRACH的时域资源主要由参数“prach-ConfigurationIndex”决定。拿着这个参数的取值去协议38211查表6.3.3.2-2/3/4,需要注意根据实际情况在这三张表中进行选择: FR1 FDD/SULFR1 TDDFR2 TDD Random access preambles can onl…...
在vue3项目中编辑的时候,解决对话框里边的数据和列表中的数据联动了。深复制
//分析原因是从列表中拿到的数据直接复制去修改就涉及到堆里变的内容是一样的,直接复制其实只是把引用地址赋值给变量了,解决方法是 浅复制和深复制。<!-- 审批流程管理 --> <template><div style"float: left; width: 250px;backgr…...
循环结构(个人学习笔记黑马学习)
while循环语句 在屏幕中打印0~9这十个数字 #include <iostream> using namespace std;int main() {int i 0;while (i < 10) {cout << i << endl;i;}system("pause");return 0; } 练习案例: 猜数字 案例描述:系统随机生成一个1到100之间的数字&…...
ceph中PGLog处理流程
正文 struct pg_log_entry_t {ObjectModDesc mod_desc; //用于保存本地回滚的一些信息,用于EC模式下的回滚操作bufferlist snaps; //克隆操作,用于记录当前对象的snap列表hobject_t soid; …...
macOS使用命令行连接Oracle(SQL*Plus)
Author: histonevonzohomail.com Date: 2023/08/25 文章目录 SQL\*Plus安装下载环境配置 SQL\*Plus远程连接数据库参考文献 原文地址:https://histonevon.top/archives/oracle-mac-sqlplus数据库安装:Docker安装Oracle数据库 (histonevon.top) SQL*Plus…...
Mac下使用Homebrew安装MySQL5.7
Mac下使用Homebrew安装MySQL5.7 1. 安装Homebrew & Oh-My-Zsh2. 查询软件信息3. 执行安装命令4. 开机启动5. 服务状态查询6. 初始化配置7. 登录测试7.1 终端登录7.2 客户端登录 参考 1. 安装Homebrew & Oh-My-Zsh mac下如何安装homebrew MacOS安装Homebrew与Oh-My-Zsh…...
centos安装Nginx配置Nginx
1. 查看操作系统有没有安装Nginx which nginx 2. 使用epel的方式进行安装(方法二) 先安装epel sudo yum install yum-utils 安装完成后,查看安装的epel包即可 sudo yum install epel 3 开始安装nginx 上面的两个方法不管选择哪个&…...
Linux环境下搭建使用缓存中间件Redis
缓存中间件Redis搭建与使用 前言正文1 提供安装环境2 下载安装3 修改启动配置4 启动服务5 使用6 关闭服务7 卸载 前言 redis服务将在linux系统中部署,本文前提是已经搭建一个linux系统,并配置好网络等。使用vmware搭建一个linux系统,可以参考…...
Oracle 本地客户端连接远程 Oracle 服务端并使用 c# 连接测试
这里写自定义目录标题 前言Oracle 客户端安装先决条件下载 Oracle 客户端Oracle 客户端环境变量配置 PL/SQLPL/SQL 下载PL/SQL 配置 配置远程连接tnsnames.ora 文件配置 使用 PL/SQL 连接远程数据库使用 C# 远程访问 Oracle 数据库结语 前言 最近有一个需要使用本地的 Oracle …...
java中上传文件先下载到本地再上传还有就是直接通过文件流url地址进行上传优缺点?
在Java中上传文件到SFTP服务器时,有两种常见的方法:先下载到本地再上传和直接使用文件流URL地址进行上传。每种方法都有其优点和缺点,下面是对它们的简要比较: 先下载到本地再上传: 优点: 可以在本地对文件…...
华为复合vlan(mux vlan)
一、概念: Multiplex vlan:实现网络资源控制的的机制。 / Principle vlan:port 可以和mux vlan内所有接口进行通信,限制128个 < /Separate vlan:隔离型从vlan,只能和…...
第62步 深度学习图像识别:多分类建模(Pytorch)
基于WIN10的64位系统演示 一、写在前面 上期我们基于TensorFlow环境做了图像识别的多分类任务建模。 本期以健康组、肺结核组、COVID-19组、细菌性(病毒性)肺炎组为数据集,基于Pytorch环境,构建SqueezeNet多分类模型࿰…...
GPT带我学-设计模式-适配器模式
1 什么是适配器设计模式 适配器设计模式是一种结构性设计模式,用于在不兼容的接口之间进行转换。它允许将一个类的接口转换成客户端所期望的接口。 适配器模式包含以下几个角色: 目标接口(Target):定义客户端所期望…...
Pyecharts教程(七):使用pyecharts创建堆叠柱状图的示例
Pyecharts教程(七):使用pyecharts创建堆叠柱状图的示例 作者:安静到无声 个人主页 目录 Pyecharts教程(七):使用pyecharts创建堆叠柱状图的示例完整代码推荐专栏在数据可视化中,柱状图是一种常见的图表类型,它可以清晰地展示各类别之间的比较关系。然而,如果我们想要在同…...
C++中的强制转换的常用类型及应用场景详解
C中的强制转换的常用类型及应用场景详解 文章目录 C中的强制转换的常用类型及应用场景详解一、静态转换(static_cast)二、动态转换(dynamic_cast)三、常量转换(const_cast)四、重新解释转换(rei…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
