VUE笔记(六)vue路由
一、路由的简介
1、实现生活中的路由
路由:路由其实就是一个key-value对应关系
路由器:用于管理多个路由关系的设备被称为路由器
2、前端的路由
目前使用的前端项目都是单页面的应用(SPA),一个项目中只有一个html页面,这种项目是由很多个组件组成,组件之间如果要跳转要依靠路由来完成,路由是由key和value组成一个对应关系,前端路由的key就是url地址,路由的value就是组件本身
key | value |
---|---|
http://localhost:8080/login | Login.vue |
http://localhost:8080/register | Register.vue |
总之:路由是实现多个组件之间进行跳转一种方式,使用路由将各组件之间联系起来
由于vue是一个渐进式的前端框架,vue的核心语法中不包括路由,路由以插件的形式存在,如果要去使用路由就要去将路由集成到vue项目中
二、路由的基本配置
1、路由的配置
由于路由不是vue的核心功能,大家如果要使用就需要去单独集成它,在vue中使用路由最多一个路由产品vue-router
vue-router的官网:Vue Router
注意:vue2的项目,匹配的路由版本是vue-router@3
配置的具体步骤如下
-
安装vue-router的依赖包
npm install vue-router@3.5.1
-
在src目录创建router的文件夹,在router文件夹下创建index.js文件,具体代码如下
//导入Vue包
import Vue from 'vue'
//导入VueRouter包
import VueRouter from 'vue-router'
//将VueRouter作为插件设置到Vue中
Vue.use(VueRouter)
//创建路由器对象
const router=new VueRouter()
//将这个路由器对象导出
export default router
-
将路由挂载到vue实例上,在main.js文件中
import Vue from 'vue'
import App from './App.vue'
import router from '@/router'
Vue.config.productionTip = false
new Vue({render: h => h(App),router
}).$mount('#app')
2、一级路由的配置
路由是一个key-value的对应关系
-
创建组件
在src/views目录下分别创建Login.vue、Register.vue、Home.vue
-
路由配置
在src/router/index.js进行如下配置
//导入Vue包
import Vue from 'vue'
//导入VueRouter包
import VueRouter from 'vue-router'
//导入组件
import Login from '@/views/Login'
import Register from '@/views/Register'
import Home from '@/views/Home'
//将VueRouter作为插件设置到Vue中
Vue.use(VueRouter)
//创建routes数组
const routes=[{path:'/login',component:Login},{path:'/register',component:Register},{path:'/home',component:Home}
]
/*创建路由器对象const router=new VueRouter(config)config:路由的配置对象routes:路由配置的数组
*/
const router=new VueRouter({routes
})
//将这个路由器对象导出
export default router
3、路由的出口设置
如上已经将路由的规则配置成功了,如果要显示在页面上,就需要配置路由出口
在App.vue根组件中配置路由出口
<template><router-view></router-view>
</template>
4、路由的跳转
使用vue-router进行路由跳转有两种方式
-
标签式跳转方式:使用
<router-link>
这个标签进行跳转,一般使用在<template></template>
模板之中,最终会编译成<a>
标签 -
编程式跳转方式:使用
this.$router
对象的push
或者replace
方法进行跳转的,这种跳转方式一般使用在组件的js代码部分
4.1、标签式路由跳转的案例
已有账号?<router-link to="/login">前往登录</router-link>
4.2、编程式路由跳转
-
下载axios
npm i axios
-
配置package.json
"scripts": {"serve": "vue-cli-service serve","serve:production": "set NODE_ENV=production&vue-cli-service serve","build": "vue-cli-service build"}
-
封装auth.js方法,完成token获取和设置的封装
位置:src/utils/auth.js
const tokenkey="admin-token"
// 保存token到localStorage中的方法
export const setToken=tokenval=>localStorage.setItem(tokenkey,tokenval)
// 从localStorage中获取token
export const getToken=()=>localStorage.getToken(tokenkey)
-
封装axios
位置:src/api/request.js
import axios from 'axios'
import {getToken} from '@/utils/auth'/* 基础路由的配置
*/
switch(process.env.NODE_ENV){case 'production':axios.defaults.baseURL="http://47.98.128.191:3000/"break;default:axios.defaults.baseURL="http://www.zhaijizhe.cn:3005"break
}
/* 设置请求拦截器
*/
axios.interceptors.request.use(config=>{//获取token的信息,然后将token信息携带到请求头信息中if(getToken){config.headers.Authorization=getToken()}return config
})
/* 设置响应拦截器
*/
axios.interceptors.response.use(response=>{return response.data
},err=>{if(err.response){switch(err.response.status){case 401:breakcase 404:breakcase 500:break}}
})export default axios
-
编写登录api方法
位置:src/api/modules/users.js
import request from '@/api/request'
export default{login:(data)=>request.post('/users/login',data)
}
-
汇总模块
位置:src/api/api.js
import users from "./modules/users";
export default{users
}
-
挂载api到Vue原型上
位置:src/main.js
import api from '@/api/api'
Vue.prototype.$api=api
-
组件中完成登录
位置:src/views/Login.vue
<template><div><h1>登录</h1><div>没有账号?<router-link to="/register">前往注册</router-link></div><div><div><label for="username">姓名:</label><input id="username" type="text" placeholder="请输入登录账户" v-model="user.username"></div><div><label for="password">密码:</label><input id="password" type="text" placeholder="请输入登录账户" v-model="user.password"></div><div><button @click="login">登录</button></div></div></div>
</template><script>
import {setToken} from '@/utils/auth'
export default {data(){return{user:{username:'admin',password:'123'}}},methods:{async login(){let {code,message,token}=await this.$api.users.login(this.user)/* 登录成功后,要完成的事项有两个1、保存token到localStorage中2、使用路由进行跳转*/setToken(token)if(code){alert(message)//跳转到后台,使用编程式路由跳转this.$router.replace('/home')}}}
}
</script><style></style>
5、路由的嵌套
-
如果要配置二级路由,需要在相应的一级路由对象上添加children属性,然后进行配置
位置:src/router/index.js
{path:'/home',component:Home,children:[{path:'workplace',//二级路由的path的前不要带/component:workplace},{path:'analysis',component:analysis},{path:'studentList',component:studentList}]}
-
静态菜单
位置:src/views/Home.vue
<template><div class="container"><div class="header"><div class="logo">学苑BOSS系统</div></div><div class="main"><div class="silder"><ul><li><span>控制面板</span><ul class="sul"><li><router-link to="/home/workplace">工作台</router-link></li><li><router-link to="/home/analysis">统计报表</router-link></li></ul></li><li><span>学员管理</span><ul class="sul"><li><router-link to="/home/studentList">学生列表</router-link></li></ul></li><li><span>系统管理</span><ul class="sul"><li>班主任管理</li><li>教师管理</li><li>专业管理</li><li>班级管理</li></ul></li></ul></div><div class="content"><!-- 设置二级路由的出口 --><router-view></router-view></div></div></div>
</template><script>
export default {}
</script>
三、路由的其他配置
1、路由的重定向
所谓的路由重定向就是指当你输入一个路由的路径时候,它会自动重新跳转到另外一个路由上这种行为称为路由重定向
{path:'/',redirect:'/home'},
2、路由懒加载
为了提高首屏加载速度,可以采用路由懒加载的方式,提升加载性能,避免白屏现象出现
//导入Vue包
import Vue from 'vue'
//导入VueRouter包
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//创建routes数组
const routes=[{path:'/login',component:()=>import('@/views/Login')},{path:'/register',component:()=>import('@/views/Register')},{path:'/',redirect:'/home'},{path:'/home',component:()=>import('@/views/Home'),children:[{path:'workplace',//二级路由的path的前不要带/component:()=>import('@/views/dashboard/workplace.vue')},{path:'analysis',component:()=>import('@/views/dashboard/analysis.vue')},{path:'studentList',component:()=>import('@/views/students/studentList.vue')}]}
]
const router=new VueRouter({routes
})
//将这个路由器对象导出
export default router
3、缓存路由
-
为需要设计缓存组件取一个名称
export default {name:'analysis'
}
-
在路由的出口的地方设置keep-alive
<keep-alive exclude="analysis"><router-view></router-view></keep-alive>
-
exclude
:该组件不被缓存 -
include
:该组件会被缓存
4、路由的元信息
路由对象有很多属性,核心有两个,一个就是path,表示的路由的路径,component表示的是路由的对应的组件,除此之外还有其他的属性,比如meta属性,可以设置路由的额外信息,这里以两个例子给大家讲解
4.1、面包屑的功能
-
需要在路由定义的时候在相应的路由配置对象中添加meta属性,配置面包屑的具体配置
{path:'workplace',//二级路由的path的前不要带/component:()=>import('@/views/dashboard/workplace.vue'),meta:{firstTitle:'控制面板',secondTitle:'工作台'}
},
-
自定义面包屑组件
在src/components目录下创建BreadCrumb组件
<template><div><span>{{$route.meta.firstTitle}}</span>><span>{{$route.meta.secondTitle}}</span></div>
</template>
-
在需要的组件中引入面包屑组件
<template><div><bread-crumb></bread-crumb><h1>学生列表</h1></div>
</template>
4.2、路由缓存状态设置
-
在路由配置中为meta属性设置isKeepAlive属性
{path:'workplace',//二级路由的path的前不要带/component:()=>import('@/views/dashboard/workplace.vue'),meta:{firstTitle:'控制面板',secondTitle:'工作台',iskeepAlive:true}},
-
在路由出口的地方通过v-if指令来完成设置
<keep-alive><router-view v-if="$route.meta.iskeepAlive"></router-view></keep-alive><router-view v-if="!$route.meta.iskeepAlive"></router-view>
说明:这种设置方式较之前使用include或者exclude方式的更加合理。
四、路由传参
1、学生列表
-
编写获取学生的api方法
import request from '@/api/request'
export default{getStudents:params=>request.get('/students/getStudents',{params})
}
-
汇总api
import users from "./modules/users";
import students from "./modules/students";
export default{users,students
}
2、query传参
vue-router这个路由操作中,要进行传参有多种方式,比较常用的方式有两种
-
query传参方式
-
params传参方式
query传参的步骤
第1步:创建页面组件,配置路由
{path:'studentDetail',component:()=>import('@/views/students/studentDetail.vue'),meta:{firstTitle:'学生管理',secondTitle:'学生详情'}}
第2步:进行传参
-
标签跳转的方式
<router-link :to="`/home/studentDetail?_id=${item._id}`"><button class="btn detal">查看</button></router-link>
<router-link :to="'/home/studentDetail?_id='+item._id"><button class="btn detal">查看</button></router-link>
<router-link :to="{path:'/home/studentDetail',query:{_id:item._id}}"><button class="btn detal">查看</button></router-link>
//命名路由
<router-link :to="{name:'xsxq',query:{_id:item._id}}"><button class="btn detal">查看</button></router-link>
最后一种写法是使用了命名路由的写法,命名路由的好处就是使用name来指定要跳转位置
-
编程方式进行跳转
goStudentDetail(_id){this.$router.push(`/home/studentDetail?_id=${_id}`)
}
goStudentDetail(_id){this.$router.push('/home/studentDetail?_id='+_id)
}
goStudentDetail(_id){this.$router.push({path:'/home/studentDetail',query:{_id}})}goStudentDetail(_id){this.$router.push({name:'xsxq',query:{_id}})}
第3步:接收路由参数
使用this.$route.query方式获取参数
export default {components:{BreadCrumb},created(){console.log(this.$route.query._id);}
}
$router和$route
面试题(简单的面试题)
-
router:它是一个VueRouter类型的一个对象,通过new VueRouter构造函数方式将其创建出来,它是一个全局对象
-
设置路由模式
-
实现路由跳转:通过该对象中push或者replace方法来实现跳转的
-
-
route:路由信息对象,它属于一个局部对象,该对象主要用来描述路由信息的
-
获取该路由path路径
-
获取该路由的传递的参数(query参数,params参数)
-
获取该路由的meta信息(用户自定义的信息)
-
4、params传参
动态路由概念:所谓的动态路由是指路由地址的一部分是变化的,像这种我们将其称为动态路由
http://localhost:8080/#/home/studentUpadate/10001
http://localhost:8080/#/home/studentUpadate/10002
http://localhost:8080/#/home/studentUpadate/10003
如上操作,如果有多条信息,就需要在router/index.js中配置多个路由信息对象,这种做法不可取,原因有两个
-
配置信息量特别大
-
这种配置不灵活
为了解决这个问题,我们可以动态路由的方式进行配置,具体配置步骤如下
第1步:在路由配置文件中配置如下
{path:'studentUpdate/:id',component:()=>import('@/views/students/studentUpdate.vue'),meta:{firstTitle:'学生管理',secondTitle:'修改学生'}}
第2步:路由跳转传参
根据跳转方式的不同
-
标签方式跳转
<router-link :to="`/home/studentUpdate/${item._id}`"><button class="btn detal">修改</button></router-link><router-link :to="'/home/studentUpdate/'+item._id"><button class="btn detal">修改</button></router-link>
-
编程方式跳转
this.$router.push('/home/studentUpdate/'+_id)this.$router.push(`/home/studentUpdate/${_id}`)goStudentUpdate(_id){this.$router.push({name:'xsxg',params:{id:_id}})}
注意:如果要使用push方法的参数是配置对象形式参数,这种params只能和命名路由结合使用,不能和path一起使用
第3步:接收params参数
接收params参数有两个方法
-
使用this.$route.params.参数名
console.log(this.$route.params.id);
-
使用props方式传参
配置步骤
首先:在路由对象设置可以使用props方式接收
{name:'xsxg',path:'studentUpdate/:id',component:()=>import('@/views/students/studentUpdate.vue'),meta:{firstTitle:'学生管理',secondTitle:'修改学生'},props:true
}
其次:在接收参数的组件中设置props选项
export default {props:['id'],
}
最后,在组件中使用
export default {props:['id'],components:{BreadCrumb},created(){// console.log(this.$route.params.id);console.log('id:',this.id);}
}
5、修改学生
-
页面返回和页面刷新
<button @click="$router.go(-1)">返回</button>
<button @click="$router.go(0)" >刷新</button>
五、路由模式【面试题】
由于Vue项目为单页面应用,所以整个项目在开发和构建过程中,仅存在一个HTML物理文件,通过路由系统可以实现将项目的组件与可访问的URL路径进行绑定。由于Vue项目只有一个HTML物理文件,切换页面时既需要让访问的URL路径发生变化,又不能触发HTML物理文件的重新加载,这就使得VueRouter的跳转模式不能使用普通的超链接方式。
VueRouter为了支持单页面应用的页面管理和页面跳转,提供了两种页面跳转和加载模式:
-
hash:在浏览器 URL 路径中会有一个'#'
-
history:在浏览器 URL 路径中没有'#'
1、hash模式
hash模式使用了锚点技术重写URL访问路径,会在原有的URL路径后拼接/#/xx,这种方式可以在不重新加载原有HTML文件的基础上,实现切换URL路径的目的,hash模式的原理案例,代码如下
<a href="#/index">首页</a><a href="#/about">关于我们</a><div class="page index">我是首页</div><div class="page about">我是关于页面</div><script>window.onhashchange=function(event){var newURL=event.newURL.split("#/")[1]var oldURL=event.oldURL.split("#/")[1]var newPage=document.querySelector('.'+newURL)var oldPage=document.querySelector('.'+oldURL)newPage.style.display="block"oldPage.style.display="none"}</script>
hash模式利用了纯静态技术,解决了单页面应用的页面划分,它可以在不触发网页重新加载的情况下切换URL路径,配合onhashchange可以实现,一旦URL中的hash部分发生变化,就触发函数通知,通过javascript编程便可以很快速的实现DOM对象的切换显示。
hash模式同时也存在着不足之处,如在分布式微前端项目中,嵌套的子应用和主应用都使用hash模式时,由于hash模式的URL路径只能存在一个#,会导致子应用和主应用在定义URL路径上存在着困难,hash模式的URL路径中包含#,也会在视觉上导致URL路径不美观
2、history模式
histroy模式是VueRouter中常用的一种路由模式,它与hash模式不同,不需要借助锚点技术重写URL路径,所以history模式使用的URL路径中不存在#,在视觉上更加美观,histroy模式采用histroy对象中的pushState()函数重写函数URL路径,可在触发重新加载的情况下变更URL路径,history的原理,代码如下
<a href="javascript:jump('/index')">跳转到首页</a><a href="javascript:jump('/about')">跳转到about页</a><div class="page index">我是首页</div><div class="page about">我是关于页面</div><script>function jump(path){history.pushState(null,'page',path)var pages=document.querySelectorAll('.page')var newPage=document.querySelector(path.replace("/","."))pages.forEach(item=>item.style.display='none')newPage.style.display='block'}</script>
history模式重写URL路径的解决方案与hash模式现象类似,但本质不同,虽然histroy模式可以重写URL路径,但是重写后的新路径中并不包含原有HTML物理文件的访问路径,所以history模式在重写URL路径后,一旦刷新网页会造成404无法访问的效果,VueCli在开发环境中解决了history模式的刷新问题,不过项目发布到生产环境时,由于histroy模式的URL路径问题,还需要配合生产服务器的转发规则重写,用以支持history模式的路由加载。
可以在路由的配置文件中更改路由模式:
const router = new VueRouter({routes: routes,mode: 'history'
})
不设置 mode 属性,则默认为 hash 模式。
六、路由守卫
1、什么是路由守卫
当路由发生变化的时候,会触发的一些函数,我们这些函数中编写一定业务逻辑,这种函数称为路由守卫函数,也有人称为导航守卫
按照类型将导航守卫分为三大类
-
全局前置守卫:当所有路由被触发的时候,在进入指定组件之前所触发的守卫函数
-
路由独享守卫:触发指定路由的路由的时候触发
-
组件内守卫:当离开组件的时候,或者进入组件的时候触发的守卫函数
2、全局前置守卫
2.1、语法
router.beforeEach((to,from,next)=>{})
参数说明:
-
to:即将要进入目标路由对象
-
from:当前导航正要离开的路由
-
next:是一个函数,该函数的作用是进入到目标路由所指定的组件,或者按照要求进入到指定的组件
案例:防止没有token直接进入后台
第1步:在router/index.js中编写路由全局前置守卫函数,完成token验证
router.beforeEach(async(to,from,next)=>{console.log('********进入路由全局前置守卫************');if(to.path=="/login"||to.path=="/register"){console.log('即将要进入的是登录或者注册组件');//放行进入next()}else{//获取tokenlet token=getToken()if(token){let result=await api.users.getUserInfo()if(result.code){next()//放行进入}}else{alert('您还没有登录,请先登录')next('/login')}}
})
第2步:在二次封装axios的文件中request.js中补全401状态时的执行业务逻辑
axios.interceptors.response.use(response=>{return response.data
},err=>{if(err.response){switch(err.response.status){case 401:console.log('进入到拦截器的401处理中');//弹框提示alert('您的token已失效,请重新登录') //进行路由跳转router.push('/login')breakcase 404:breakcase 500:break}}
})
3、路由独享守卫
这种守卫函数,只针对于进入该路由所触发
{path:'/home',component:()=>import('@/views/Home'),children:[],//如果进入该路由或者该路由下的子路由都会进入到这个守卫函数beforeEnter:async function(to,from,next){let token=getToken()if(token){let {code}=await Vue.prototype.$api.users.getUserInfo()if(code){next()}}else{alert('您还没有登录,请登录')next('/login')}}}
4、组件内守卫
写在组件中
beforeRouteEnter:async function(to,from,next){console.log('------进入该组件---------');let result=await Vue.prototype.$api.users.getUserInfo()if(result.data.auth==1){console.log('------我是超级管理员-----------');next()}else if(result.data.auth==2){console.log('-------我是普通管理员----------------------');alert('您没有权限进入,请联系系统管理,为您开设权限')}// let result=await this.$api.users.getUserInfo()// console.log('result',result);},beforeRouteLeave(to,from,next){console.log('------离开该组件----------');if(this.name==''||this.fcz==''||this.startTime==''){if(window.confirm('您还没有输入完所有的信息,您确认你要离开吗?')){next()}}}
相关文章:

VUE笔记(六)vue路由
一、路由的简介 1、实现生活中的路由 路由:路由其实就是一个key-value对应关系 路由器:用于管理多个路由关系的设备被称为路由器 2、前端的路由 目前使用的前端项目都是单页面的应用(SPA),一个项目中只有一个html页…...

nginx反向代理 负载均衡
目录 1.反向代理介绍: 2.七层代理和四层代理: 2.1 七层代理: 2.2 四层代理: 3.反向代理web服务器: 3.1 代理服务器配置: 3.2 服务器配置 : 3.3 客户端访问: 3.4 代理不同端口&am…...
hugging face inference API返回内容太短的问题
hugging face的inference api返回的内容默认很短,可以通过参数max_new_tokens进行设置: Detailed parameters When sending your request, you should send a JSON encoded payload. Here are all the options All parametersinputs (required):a str…...
react中redux的详细使用以及持久化处理
一.redux使用 1.安装 npm i redux 例一: 2.创建redux文件夹,store.js文件 store.js文件 import {legacy_createStore as createStore,combineReducers}from "redux" // 每一块状态内容对应一个reducer文件 import {CollApsedReducer} fro…...
论文笔记: 循环神经网络进行速度模型反演 (未完)
摘要: 分享对论文的理解, 原文见 Gabriel Fabien-Ouellet and Rahul Sarkar, Seismic velocity estimation: A deep recurrent neural-network approach. Geophysics (2020) U21–U29. 作者应该是领域专家, 对地球科学的理解胜于深度学习. 为方便讨论, 等式编号保持与原文一致.…...

多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比
多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比 目录 多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预测对比预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | Matlab实现BiLSTM-Adaboost和BiLSTM多变量时间序列预…...

excel绘制直方图
Excel 2016直方图使用指南 excel绘制各种曲线十分方便,可以通过代码将计算的数据输出到excel里面,然后通过excel的插入标签,绘制各种需要的曲线。 对于直方图,横坐标是分布区间,纵坐标是这个区间内数值的频数&#x…...
react-grid-layout 实现原理介绍
简介 React-grid-layout 是一个基于 React 的网格布局库,它可以帮助我们轻松地在网格中管理和排列组件。它提供了一个直观的 API,可以通过配置网格的大小、列数和组件的位置来实现复杂的布局,还支持对网格中组件的拖拽和重新排列。 实现 诉…...

集合框架-(Collection/Map)
1.单列集合 1.1基础概要 集合中存储的是对象的地址信息,想要输出对象的信息,需要在具体的类中重写toString()方法 Collection代表单列集合,每个元素数据只包含一个值 List集合:添加的元素可以是有序、可…...
什么是单文件组件?
单文件组件形式 非单文件组件 可以理解为是通过 html 文件来使用 Vue。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><…...
国际站阿里云服务器多久会重启一次系统??
阿里云服务器是一种高性能、高可靠的云计算服务,但在长时间运行过程中,系统可能会出现一些问题,需要重启来恢复正常运行。那么,阿里云服务器多久重启一次系统呢?本文将对这个问题进行解答。 阿里云服务器重启频率 阿里…...

低成本32位单片机电动工具无感方波控制方案
RAMSUN介绍基于灵动32位微处理器MM32SPIN0230的BLDC电动工具无感方波控制方案,包括MM32SPIN0230芯片资源。 以下是电动工具无感方波控制方案的简述: MM32SPIN0230电动工具专用板 芯片介绍 MM32SPIN0230系列是灵动微MindSPIN旗下高性能的单电机控制产品…...

安防视频监控/视频集中存储/云存储平台EasyCVR平台无法播放HLS协议该如何解决?
视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、…...
MySQL如何查找某个字段值相同的数据
当我们想要查找MySQL中某个字段值相同的数据,但我们又不知道这个数据的值是什么的时候该如何操作呢? 在我的数据表中有单词表以及对应的详细信息表,如果两张表是以单词作为逻辑上的外键时,查询单词详细信息操作就可以根据word值进…...

8.react18并发模式与startTransition(搜索高亮思路)
React 18 之前,渲染是一个单一的,不间断的,同步的事务,一旦渲染开始,就不能被中断 React 18引入并发模式,它允许你将标记更新作为一个transitions,这会告诉React他们可以被中断执行.这样可以将紧急任务先更新,不紧急任务后更新. 将任务给紧急任务先执行, 优先级低的任务后执行…...

前端Vue自定义得分构成水平柱形图组件 可用于系统专业门类得分评估分析
引入Vue自定义得分构成水平柱形图组件:cc-horBarChart 随着技术的发展,传统的开发方式使得系统的复杂度越来越高,一个小小的改动或小功能的增加可能会导致整体逻辑的修改,造成牵一发而动全身的情况。为了解决这个问题,…...
Linux获取纳秒级别时间
在 Linux 系统中可以使用 gettimeofday 函数来获取时间,这个函数能够以毫秒的精度来获取时间 struct timeval tv;gettimeofday(&tv, NULL);time_t cur_time tv.tv_sec;long cur_time_ms tv.tv_usec/1000;printf(“cur_time %d \n”, cur_time);printf(“cur…...

CSS中你不得不知道的盒子模型
目录 1、CSS的盒子模型1.1 css盒子模型有哪些:1.2 css盒子模型的区别1.3 通过css如何转换css盒子模型 1、CSS的盒子模型 1.1 css盒子模型有哪些: 标准盒子模型、怪异盒子模型(IE盒子模型) 1.2 css盒子模型的区别 标准盒子模型&a…...

知识储备--基础算法篇-数组
1.学习 2.数组 2.1第53题-最大子数组和 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 心得:一直在纠结这个连续的事情&…...

zookeeper 理论合集
目录 系统背景 集群结构 多个节点之间的角色 节点的状态 为什么引入 Observer 存储结构 ZNode 节点结构 ZNode 创建类型 内存数据存储 数据持久化 zookeeper 的容量大小 数据同步 消息广播 崩溃恢复 如何保证顺序一致性 核心流程 Leader 选举流程 脑裂问题 …...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

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进…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...