VUE笔记(六)vue路由

一、路由的简介

1、实现生活中的路由

路由:路由其实就是一个key-value对应关系

路由器:用于管理多个路由关系的设备被称为路由器

2、前端的路由

目前使用的前端项目都是单页面的应用(SPA),一个项目中只有一个html页面,这种项目是由很多个组件组成,组件之间如果要跳转要依靠路由来完成,路由是由key和value组成一个对应关系,前端路由的key就是url地址,路由的value就是组件本身

keyvalue
http://localhost:8080/loginLogin.vue
http://localhost:8080/registerRegister.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>&gt;<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()}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/106566.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Open3D 点云中值滤波

目录 一、算法原理1、中值滤波2、参考文献二、代码实现三、结果展示四、参考链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、中值滤波 中值滤波的方法是,对待处理的当前采样点,选择一个模板,该模…

牛客练习赛 114

C.Kevin的七彩旗 思路&#xff1a;贪心和dp均可以解决。 贪心&#xff1a;我们可以发现&#xff0c;最终想要获得合法的序列&#xff0c;我们必须是通过把几段连续的序列拼凑起来&#xff0c;但序列之间可能有重合&#xff0c;因此我们就转化为了&#xff0c;记录每一段最大的…

如何评估分类模型的好坏

如何评估分类模型的好坏 评估分类预测模型的质量&#xff0c;常用一个矩阵、三条曲线和六个指标。 一个矩阵&#xff1a;混淆矩阵&#xff1b;三条曲线&#xff1a;ROC曲线、PR曲线、KS曲线&#xff1b;六个指标&#xff1a;正确率Acc、查全率R、查准率P、F值、AUC、BEP值、KS…

Wireshark数据抓包分析之UDP协议

一、实验目的&#xff1a; 通过使用wireshark对UDP数据包的抓取分析UDP协议的内容 二、预备知识&#xff1a; UDP协议的概念&#xff1a;UDP使用底层的互联网协议来传送报文&#xff0c;同IP一样提供不可靠的无连接传输服务。它也不提供报文到达确认、排序及流量控制等功能。 …

【C++心愿便利店】No.3---内联函数、auto、范围for、nullptr

文章目录 前言&#x1f31f;一、内联函数&#x1f30f;1.1.面试题&#x1f30f;1.2.内联函数概念&#x1f30f;1.3.内联函数特性 &#x1f31f;二、auto关键字&#x1f30f;2.1.类型别名思考&#x1f30f;2.2.auto简介&#x1f30f;2.3.auto的使用细节&#x1f30f;2.4.auto不能…

stm32之8.中断

&#xff08;Exceptions&#xff09;异常是导致程序流更改的事件&#xff0c;发生这种情况&#xff0c;处理器将挂起当前执行的任务&#xff0c;并执行程序的一部分&#xff0c;称之为异常处理函数。在完成异常处理程序的执行之后&#xff0c;处理器将恢复正常的程序执行&#…

家长如何将ChatGPT成为家庭日常活动的得力助手

人工智能已经在许多领域发挥作用&#xff0c;如播放音乐、关闭灯光和帮助我们更安全地驾驶。那么&#xff0c;在养育孩子方面呢&#xff1f; 使用像ChatGPT这样的应用&#xff0c;家长们可以更好地完成任务&#xff0c;但同时也要了解其中存在的风险。 许多家长表示&#xff…

TCP拥塞控制详解 | 7. 超越TCP

网络传输问题本质上是对网络资源的共享和复用问题&#xff0c;因此拥塞控制是网络工程领域的核心问题之一&#xff0c;并且随着互联网和数据中心流量的爆炸式增长&#xff0c;相关算法和机制出现了很多创新&#xff0c;本系列是免费电子书《TCP Congestion Control: A Systems …

uniapp 微信小程序:RecorderManager 录音DEMO

uniapp 微信小程序&#xff1a;RecorderManager 录音DEMO 简介index.vue参考资料 简介 使用 RecorderManager 实现录音。及相关的基本操作。&#xff08;获取文件信息&#xff0c;上传文件&#xff09; 此图包含Demo中用于上传测试的服务端程序upload.exe&#xff0c;下载后用…

sql server 快速安装

目录标题 一、下载二、直接选择基本安装二、下载ssms&#xff08;数据库图形化操作页面&#xff09;三、开启sa账号认证&#xff08;一&#xff09;第一步&#xff1a;更改身份验证模式&#xff08;二&#xff09;第二步&#xff1a;启用 sa 登录四、开启tcp/ip 一、下载 下载…

Leetcode80. 删除有序数组中的重复项 II

给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 class Solu…

Linux内核学习(九)—— 虚拟文件系统(基于Linux 2.6内核)

虚拟文件系统&#xff08;VFS&#xff09;作为内核子系统&#xff0c;为用户空间程序提供了文件和文件系统相关的接口。通过虚拟文件系统&#xff0c;程序可以利用标准的 Unix 系统调用对不同的文件系统&#xff08;甚至不同介质上的文件系统&#xff09;进行读写操作。 一、通…

❤ 给自己的mac系统上安装java环境

❤ 给自己的mac系统上安装java环境 &#x1f353; 作为前端工程师如何给自己的mac系统上安装java环境 &#x1f34e; 最近因为自己的一些项目需求&#xff0c;mac电脑上需要安装一些后台的java环境&#xff0c;用来跑后台的java程序&#xff0c;于是从一个前端工程师的角度安…

C++:命名空间,缺省参数,函数重载,引用,内联函数

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》 文章目录 前言一、命名空间命名空间的定义命名空间的使用 二、缺省参数缺省参数概念缺省参数分类 三、函数重载函数重载的概念 四、引用引用的概念引用特性引用的使用场景引用与指针的区别 …

游戏中的图片打包流程,免费的png打包plist工具,一款把若干资源图片拼接为一张大图的免费工具

手机游戏开发中&#xff0c;为了提高图片渲染性能&#xff0c;经常需要将小图片合并成一张大图进行渲染。如果手工来做的话就非常耗时。TexturePacker就是一款非常不错方便的处理工具。TexturePacker虽然非常优秀&#xff0c;但不是免费的。 对于打包流程&#xff0c;做游戏的…

python print ljust 文本对齐打印 对齐打印名册

背景 在python部分场景下&#xff0c;我们需要打印输出一些文本消息&#xff0c;但我们又无法预测可能的打印内容是什么。这种情况下&#xff0c;我们要对齐打印这些文本&#xff0c;是比较比较难以处理的。 例如下面是一列姓名&#xff0c;和对应的一列手机/电话号&#xff0…

响应式布局bootstrap使用

响应式布局 学习目标 能够说出响应式原理 能够使媒体查询完成响应式导航 能够使用Bootstrap的栅格系统 能够使用bootstrap的响应式工具 1.响应式原理 1.1响应式开发原理 就是使用媒体查询针对不同宽度的设备进行布局和样式的设置,从而适配不同设备的目的 1.2响应式布局容器…

成功解决修改已经push到远程git仓库的commit message

1.使用 Git 命令行进入要修改的项目目录。 2.运行 git log 命令查看提交历史&#xff0c;找到要修改的提交的哈希值&#xff08;commit hash&#xff09;。 3.运行 git rebase -i <commit hash> 命令&#xff0c;将 <commit hash> 替换为要修改的提交的哈希值。这将…

第61步 深度学习图像识别:多分类建模(TensorFlow)

基于WIN10的64位系统演示 一、写在前面 截至上期&#xff0c;我们一直都在做二分类的任务&#xff0c;无论是之前的机器学习任务&#xff0c;还是最近更新的图像分类任务。然而&#xff0c;在实际工作中&#xff0c;我们大概率需要进行多分类任务。例如肺部胸片可不仅仅能诊断…

keepalived+haproxy 搭建高可用高负载高性能rabbitmq集群

一、环境准备 1. 我这里准备了三台centos7 虚拟机 主机名主机地址软件node-01192.168.157.133rabbitmq、erlang、haproxy、keepalivednode-02192.168.157.134rabbitmq、erlang、haproxy、keepalivednode-03192.168.157.135rabbitmq、erlang 2. 关闭三台机器的防火墙 # 关闭…