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…...
 
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
 
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
 
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
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&…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
 
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
