Vue-Router详解
1、前端路由的发展历程
1.1、认识前端路由
路由其实是网络工程中的一个术语:
- 在架构一个网络时,非常重要的两个设备就是路由器和交换机。
- 当然,目前在我们生活中路由器也是越来越被大家所熟知,因为我们生活中都会用到路由器:
- 事实上,路由器主要维护的是一个映射表;
- 映射表会决定数据的流向;
路由的概念在软件工程中出现,最早是在后端路由中实现的,原因是web的发展主要经历了这样一些阶段:
- 后端路由阶段;
- 前后端分离阶段;
- 单页面富应用(SPA);
1.2、后端路由阶段
早期的网站开发整个HTML页面是由服务器来渲染的.
- 服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示.
但是, 一个网站, 这么多页面服务器如何处理呢?
- 一个页面有自己对应的网址, 也就是URL;
- URL会发送到服务器, 服务器会通过正则对该URL进行匹配, 并且最后交给一个Controller进行处理;
- Controller进行各种处理, 最终生成HTML或者数据, 返回给前端.
上面的这种操作, 就是后端路由:
- 当我们页面中需要请求不同的路径内容时, 交给服务器来进行处理, 服务器渲染好整个页面, 并且将页面返回给客户端.
- 这种情况下渲染好的页面, 不需要单独加载任何的js和css, 可以直接交给浏览器展示, 这样也有利于SEO的优化.
后端路由的缺点:
- 一种情况是整个页面的模块由后端人员来编写和维护的;
- 另一种情况是前端开发人员如果要开发页面, 需要通过PHP和Java等语言来编写页面代码;
- 而且通常情况下HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情;
1.3、前后端分离阶段
前端渲染的理解:
- 每次请求涉及到的静态资源都会从静态资源服务器获取,这些资源包括HTML+CSS+JS,然后在前端对这些请求回来的资源进行渲染;
- 需要注意的是,客户端的每一次请求,都会从静态资源服务器请求文件;
- 同时可以看到,和之前的后端路由不同,这时后端只是负责提供API了;
前后端分离阶段:
- 随着Ajax的出现, 有了前后端分离的开发模式;
- 后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JavaScript将数据渲染到页面中;
- 这样做最大的优点就是前后端责任的清晰,后端专注于数据上,前端专注于交互和可视化上;
- 并且当移动端(iOS/Android)出现后,后端不需要进行任何处理,依然使用之前的一套API即可;
- 目前比较少的网站采用这种模式开发;
单页面富应用阶段:
- 其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由.
- 也就是前端来维护一套路由规则.
前端路由的核心是什么呢?改变URL,但是页面不进行整体的刷新。
2、改变URL, 页面不刷新的两种模式
2.1、URL的hash
- 前端路由是如何做到URL和内容进行映射呢?监听URL的改变。
- URL的hash
- URL的hash也就是锚点(#), 本质上是改变window.location的href属性;
- 我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新;
- hash的优势就是兼容性更好,在老版IE中都可以运行,但是缺陷是有一个#,显得不像一个真实的路径。
2.2、HTML5的History
history接口是HTML5新增的, 它有六种模式改变URL而不刷新页面:
- replaceState:替换原来的路径;
- pushState:使用新的路径;
- popState:路径的回退;
- go:向前或向后改变路径;
- forward:向前改变路径;
- back:向后改变路径;
3、Vue-Router基本使用
3.1、认识vue-router
目前前端流行的三大框架, 都有自己的路由实现:
- Angular的ngRouter
- React的ReactRouter
- Vue的vue-router
Vue Router 是 Vue.js 的官方路由:
- 它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用(SPA)变得非常容易;
- 目前Vue路由最新的版本是4.x版本,我们上课会基于最新的版本讲解;
vue-router是基于路由和组件的
- 路由用于设定访问路径, 将路径和组件映射起来;
- 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换;
安装Vue Router:
npm install vue-router
3.2、路由的使用步骤
使用vue-router的步骤:
- 第一步:创建路由需要映射的组件(打算显示的页面);
- 第二步:通过createRouter创建路由对象,并且传入routes和history模式;
- 配置路由映射: 组件和路径映射关系的routes数组;
- 创建基于hash或者history的模式;
- 第三步:使用app注册路由对象(use方法);
- 第四步:路由使用: 通过<router-link>和<router-view>;
3.3、路由的基本使用流程
3.4、路由的默认路径
我们这里还有一个不太好的实现:
- 默认情况下, 进入网站的首页, 我们希望<router-view>渲染首页的内容;
- 但是我们的实现中, 默认没有显示首页组件, 必须让用户点击才可以;
如何可以让路径默认跳到到首页, 并且<router-view>渲染首页组件呢?
我们在routes中又配置了一个映射:
- path配置的是根路径: /
- redirect是重定向, 也就是我们将根路径重定向到/home的路径下, 这样就可以得到我们想要的结果了。
3.5、history模式
另外一种选择的模式是history模式:
3.6、router-link
router-link事实上有很多属性可以配置:
to属性:
- 是一个字符串,或者是一个对象
replace属性:
- 设置 replace 属性的话,当点击时,会调用 router.replace(),而不是 router.push();
active-class属性:
- 设置激活a元素后应用的class,默认是router-link-active
exact-active-class属性:
- 链接精准激活时,应用于渲染的 <a> 的 class,默认是router-link-exact-active;
4、路由懒加载分包处理
4.1、路由懒加载
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载:
- 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效;
- 也可以提高首屏的渲染效率;
其实这里还是我们前面讲到过的webpack的分包知识,而Vue Router默认就支持动态来导入组件:
- 这是因为component可以传入一个组件,也可以接收一个函数,该函数需要放回一个Promise;
- 而import函数就是返回一个Promise
4.2、打包效果分析
- 我们看一下打包后的效果:
- 我们会发现分包是没有一个很明确的名称的,其实webpack从3.x开始支持对分包进行命名(chunk name):
5、动态路由和路由嵌套
5.1、路由的其他属性
- name属性:路由记录独一无二的名称;
- meta属性:自定义的数据
5.2、动态路由基本匹配
很多时候我们需要将给定匹配模式的路由映射到同一个组件:
- 例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但是用户的ID是不同的;
- 在Vue Router中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数;
在router-link中进行如下跳转:
5.3、获取动态路由的值
那么在User中如何获取到对应的值呢?
- 在template中,直接通过 $route.params 获取值;
- 在created中,通过 this.$route.params 获取值;
- 在setup中,我们要使用 vue-router库给我们提供的一个hook useRoute;
- 该Hook会返回一个Route对象,对象中保存着当前路由相关的值;
5.4、NotFound
对于哪些没有匹配到的路由,我们通常会匹配到固定的某个页面
- 比如NotFound的错误页面中,这个时候我们可编写一个动态路由用于匹配所有的页面;
我们可以通过 $route.params.pathMatch获取到传入的参数:
5.5、匹配规则加*
这里还有另外一种写法:
- 注意:我在/:pathMatch(.*)后面又加了一个 *;
- 它们的区别在于解析的时候,是否解析 /:
5.6、路由的嵌套
什么是路由的嵌套呢?
- 目前我们匹配的Home、About、User等都属于第一层路由,我们在它们之间可以来回进行切换;
但是呢,我们Home页面本身,也可能会在多个组件之间来回切换:
- 比如Home中包括Product、Message,它们可以在Home内部来回切换;
- 这个时候我们就需要使用嵌套路由,在Home中也使用 router-view 来占位之后需要渲染的组件;
路由的嵌套配置:在一层路由中添加 children属性
6、路由的编程式导航
6.1、代码的页面跳转
有时候我们希望通过代码来完成页面的跳转,比如点击的是一个按钮:
当然,我们也可以传入一个对象:
如果是在setup中编写的代码,那么我们可以通过 useRouter 来获取:
6.2、query方式的参数
我们也可以通过query的方式来传递参数:
在界面中通过 $route.query 来获取参数:
6.3、替换当前的位置
使用push的特点是压入一个新的页面,那么在用户点击返回时,上一个页面还可以回退,但是如果我们希望当前页面是一个替换操作,那么可以使用replace:
6.4、页面的前进后退
router的go方法:
router也有back:通过调用 history.back() 回溯历史。相当于 router.go(-1);
router也有forward:通过调用 history.forward() 在历史中前进。相当于 router.go(1);
7、动态管理路由对象
7.1、动态添加路由
某些情况下我们可能需要动态的来添加路由:
- 比如根据用户不同的权限,注册不同的路由;
- 这个时候我们可以使用一个方法 addRoute;
如果我们是为route添加一个children路由,那么可以传入对应的name:
7.2、动态管理路由的其他方法
删除路由有以下三种方式:
- 方式一:添加一个name相同的路由;
- 方式二:通过removeRoute方法,传入路由的名称;
- 方式三:通过addRoute方法的返回值回调;
路由的其他方法补充:
- router.hasRoute():检查路由是否存在。
- router.getRoutes():获取一个包含所有路由记录的数组
8、路由导航守卫钩子
8.1、路由导航守卫
- vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
- 全局的前置守卫beforeEach是在导航触发时会被回调的:
- 它有两个参数:
- to:即将进入的路由Route对象;
- from:即将离开的路由Route对象;
- 它有返回值:
- false:取消当前导航;
- 不返回或者undefined:进行默认导航;
- 返回一个路由地址:
- 可以是一个string类型的路径;
- 可以是一个对象,对象中包含path、query、params等信息;
- 可选的第三个参数:next(不推荐使用)
- 在Vue2中我们是通过next函数来决定如何进行跳转的;
- 但是在Vue3中我们是通过返回值来控制的,不再推荐使用next函数,这是因为开发中很容易调用多次next;
8.2、登录守卫功能
比如我们完成一个功能,只有登录后才能看到其他页面:
8.3、其他导航守卫
Vue-Router还提供了很多的其他守卫函数,目的都是在某一个时刻给予我们回调,让我们可以更好的控制程序的流程或者功能:导航守卫 | Vue Router
我们一起来看一下完整的导航解析流程:
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫(2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫(2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
9、示例代码
9.1、代码结构
9.2、index.js
import {createRouter, createWebHashHistory, createWebHistory} from 'vue-router'// import Home from '../Views/Home.vue'
// import About from '../Views/About.vue'// 路由的懒加载
// const Home = () => import(/* webpackChunkName: 'home' */"../Views/Home.vue")
// const About = () => import(/* webpackChunkName: 'about' */"../Views/About.vue")// 创建一个路由: 映射关系
const router = createRouter({// 指定采用的模式: hashhistory: createWebHashHistory(),// history: createWebHistory(),// 映射关系routes: [{path: "/",redirect: "/home" // 跳转页面},{name: "home",path: "/home",component: () => import("../Views/Home.vue"),meta: {name: "why",age: 18},children: [{path: "/home",redirect: "/home/recommend"},{path: "recommend", // /home/recommendcomponent: () => import("../Views/HomeRecommend.vue")},{path: "ranking", // /home/rankingcomponent: () => import("../Views/HomeRanking.vue")}]},{name: "about",path: "/about",component: () => import("../Views/About.vue")},{path: "/user/:id",component: () => import("../Views/User.vue")},{path: "/order",component: () => import("../Views/Order.vue")},{path: "/login",component: () => import("../Views/Login.vue")},{// 上面路径匹配不成功后,使用这个匹配任意路径// path: "/:pathMatch(.*)", // 后面不加上 * 对路径不进行解析path: "/:pathMatch(.*)*",component: () => import("../Views/NotFound.vue")}]
})// 1.动态管理路由
let isAdmin = true
if (isAdmin) {// 一级路由router.addRoute({path: "/admin",component: () => import("../Views/Admin.vue")})// 添加vip页面router.addRoute("home", {path: "vip",component: () => import("../Views/HomeVip.vue")})
}// 获取router中所有的映射路由对象
console.log(router.getRoutes())// 2.路由导航守卫
// 进行任何的路由跳转之前, 传入的beforeEach中的函数都会被回调
// 需求: 进入到订单(order)页面时, 判断用户是否登录(isLogin -> localStorage保存token)
// 情况一: 用户没有登录, 那么跳转到登录页面, 进行登录的操作
// 情况二: 用户已经登录, 那么直接进入到订单页面
router.beforeEach((to, from) => {// 1.进入到任何别的页面时, 都跳转到login页面// if (to.path !== "/login") {// return "/login"// }// 2.进入到订单页面时, 判断用户是否登录const token = localStorage.getItem("token")if (to.path === "/order" && !token) {return "/login"}
})export default router
9.3、 About.vue
<template><div class="about"><h2>About: {{ $route.query }}</h2><button @click="backBtnClick">返回</button></div>
</template><script setup>import { useRouter } from 'vue-router'const router = useRouter()function backBtnClick() {// router.back()// router.forward()// go(delta)// go(1) -> forward()// go(-1) -> back()router.go(-1)}</script><style scoped>
</style>
9.4、Admin.vue
<template><div><h2>Admin</h2><p>哈哈哈哈哈哈哈</p><p>哈哈哈哈哈哈哈</p><p>哈哈哈哈哈哈哈</p><p>哈哈哈哈哈哈哈</p><p>哈哈哈哈哈哈哈</p><p>哈哈哈哈哈哈哈</p></div>
</template><script setup></script><style scoped>
</style>
9.5、Home.vue
<template><div class="home"><h2>Home</h2><div class="home-nav"><router-link to="/home/recommend">推荐</router-link><router-link to="/home/ranking">排行</router-link></div><button @click="logoutClick">退出登录</button><!-- 占位组件 --><router-view></router-view></div>
</template><script setup>function logoutClick() {localStorage.removeItem("token")}</script><style scoped>
</style>
9.6、HomeRanking.vue
<template><div class="home-ranking"><h2>各种榜单</h2><ul><li>热歌榜</li><li>新歌榜</li><li>原创榜</li><li>歌手榜单</li></ul></div>
</template><script>export default {}
</script><style scoped>
</style>
9.7、HomeRecommend.vue
<template><div class="home-recommend"><h2>HomeRecommend</h2><ul><li>推荐歌单1</li><li>推荐歌单2</li><li>推荐歌单3</li><li>推荐歌单4</li></ul></div>
</template><script>export default {}
</script><style scoped>
</style>
9.8、HomeVip.vue
<template><div><h2>HomeVip</h2><h2></h2></div>
</template><script>export default {}
</script><style scoped>
</style>
9.9、Login.vue
<template><div class="login"><h2>登录页面</h2><button @click="loginClick">登录</button></div>
</template><script setup>import { useRouter } from 'vue-router'const router = useRouter()function loginClick() {// 向服务器发送请求, 服务器会返回tokenlocalStorage.setItem("token", "coderwhy")// 跳转到order页面router.push("/order")}</script><style scoped>
</style>
9.10、NotFound.vue
<template><div class="not-found"><h2>NotFound: 您当前的路径{{ $route.params.pathMatch }}不正确, 请输入正确的路径!</h2></div>
</template><script setup>
</script><style scoped>.not-found {color: red;}</style>
9.11、Order.vue
<template><div class="order"><h2>订单页面</h2><ul><li>订单1</li><li>订单2</li><li>订单3</li><li>订单4</li><li>订单5</li></ul></div>
</template><script>export default {}
</script><style scoped>
</style>
9.12、User.vue
<template><div class="user"><!-- 在模板中获取到id --><h2>User: {{ $route.params.id }}</h2></div></template><script setup>import { useRoute, onBeforeRouteUpdate } from 'vue-router'const route = useRoute()console.log(route.params.id)// 获取route跳转idonBeforeRouteUpdate((to, from) => {console.log("from:", from.params.id)console.log("to:", to.params.id)})</script><style scoped>
</style>
9.13、App.vue
<template><div class="app"><h2>App Content</h2><div class="nav"><router-link to="/home" replace>首页</router-link><!-- <router-link :to="{ path: '/home' }" replace>首页</router-link> --><router-link to="/about" replace active-class="active">关于</router-link><router-link to="/user/123">用户123</router-link><router-link to="/user/321">用户321</router-link><router-link to="/order">订单</router-link><!-- 其他元素跳转 --><span @click="homeSpanClick">首页</span><button @click="aboutBtnClick">关于</button></div><!--组件占位(确定渲染位置)--><router-view></router-view></div>
</template><script setup>import { useRouter } from 'vue-router'const router = useRouter()// 监听元素的点击function homeSpanClick() {// 跳转到首页// router.push("/home")router.push({// name: "home"path: "/home"})}function aboutBtnClick() {// 跳转到关于router.push({path: "/about",query: {name: "why",age: 18}})}</script><style>.router-link-active {color: red;font-size: 20px;}.active {color: red;font-size: 20px;}</style>
9.14、main.js
import { createApp } from 'vue'
import router from './router'
import App from './App.vue'// localStorage.setItem("token", "coderwhy")const app = createApp(App)
app.use(router)
app.mount('#app')
相关文章:
【Django学习笔记(十)】Django的创建与运行
Django的创建与运行 前言正文1、安装Django2、创建项目2.1 基于终端创建项目2.2 基于Pycharm创建项目2.3 两种方式对比 3、默认项目文件介绍4、APP5、启动运行Django5.1 激活App5.2 编写URL和视图函数对应关系5.3 启动Django项目5.3.1 命令行启动5.3.2 Pycharm启动5.3.3 views.…...
自动虫情测报灯
TH-CQ6随着农业科技的不断进步,智能化、自动化的设备正逐步渗透到农业生产的各个环节中。其中,自动虫情测报灯作为一种新兴的农业科技产品,正以其独特的功能和优势,成为农田病虫害防治的重要工具。 一、自动虫情测报灯的工作原理…...
k8s——核心概念篇
服务的分类 有状态代表应用nginx apache优点对客户端透明,无依赖关系,可以高效实现扩容,迁移缺点不能存储数据,需要额外的数据服务支撑无状态代表应用MYSQL Redis优点可以独立存储数据,实现数据管理缺点集群环境下需要实现主从,数据同步,备份,水平扩容负载。资源和对象…...
【前端学习——正则】
https://www.bilibili.com/video/BV1da4y1p7iZ/?spm_id_from333.337.search-card.all.click&vd_source5cef5968d539682b683e7d01b00ad01b 学习网站 https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md...
LeetCode:盛最多水的容器
文章收录于LeetCode专栏 盛最多水的容器 给你n个非负整数a1,a2,…,an,每个数代表坐标中的一个点(i, ai) 。在坐标内画 n 条垂直线,垂直线i的两个端点分别为(i, ai) 和 (i, 0)。找出其中的两条线,使得它们与…...
windows系统远程执行脚本部署项目操作手册
windows系统远程执行脚本部署项目操作手册 windows系统远程执行脚本部署项目 如果频繁的需要部署项目到远程的服务器上,每次要手动上传项目,然后停止项目,启动项目,很麻烦,像Linux天生支持远程执行脚本 Windows借助工具也可以做到. 安装WinSCP软件 自行下载软件或关注我的公…...
Vue-Router详解
1、前端路由的发展历程 1.1、认识前端路由 路由其实是网络工程中的一个术语: 在架构一个网络时,非常重要的两个设备就是路由器和交换机。当然,目前在我们生活中路由器也是越来越被大家所熟知,因为我们生活中都会用到路由器&…...
Eclipse中的Build Path
Eclipse中的Build Path简介如果修改了Build Path中的中的JRE版本,记得还需要同步修改Java编译器的版本,如下图红框所示简介 Build Path是Java工程包含的资源属性合集,用来管理和配置此Java工程中【除当前工程自身代码以外的其他资源】的引用…...
Python与Matlab混合编程案例
前言因为项目需要,需要批处理很多Matlab的.m文件,从每个文件中提取结果合并到一个文件中。 很明显,如果手工统计,几百个文件会累死的。 因此立即想到了Python在批处理方面的优势,因此就在网上找了相关资料,…...
stack、queue、priority_queue
容器适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。 其中stack和queue都是容器适配器,其中stack可以封装vector、list以及我们…...
高通平台开发系列讲解(GPS篇)gpsONE 系统架构
文章目录 一、系统架构图二、gpsONE系统组成三、gpsONE交互流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢高通的定位系统模块,名称叫gpsONE。 一、系统架构图 二、gpsONE系统组成 GPS系统架构可以分为六个部分: APP层Framework Client端(LocationManager API…...
zkMove——针对Move合约生态的zkVM
1. 引言 Move为不同于Solidity的,开源的安全的智能合约开发语言,最早由Facebook为Diem链创造开发。不过,Move本身设计为与平台无关的语言,具有通用的库、工具,并使得采用完全不同数据模型和执行模型的链的开发者社区都…...
贪心算法的题目
每一步都做出一个局部最优的选择,最终的结果就是全局最优 只有一部分问题才能用贪心算法(严格来讲,一个问题能不能用贪心算法需要证明的) 2022.8.30 蔚来笔试题: 有a个y,b个o,c个u,用这些字母拼成一个字符串…...
线程控制--Linux
文章目录线程理解线程的优点与缺点进程的多个线程共享线程控制线程创建线程终止线程等待线程分离总结线程理解 谈及线程,就不得不谈起进程与线程的关系了。学习完前面有关进程的知识,之前我们对进程的定义是:内核数据结构代码和数据。但是今…...
17 | 如何做好面试复盘?将经验提升为能力
前言 前言:面试是最好的查漏补缺机会,做好面试复盘又是十分的重要。 文章目录前言一. 关于复盘1. 什么是复盘(What)2. 复盘的目的(Why)3. 什么时候需要复盘(When)4. 怎么进行复盘&am…...
数据结构-树
1. 二叉树遍历 #include <stdbool.h> #include "stdio.h" #include "stdlib.h"typedef struct TNode *Position; typedef Position BinTree; // 二叉树类型 typedef char ElementType;// 树结点定义 struct TNode {ElementType Data; // 结点数据Bin…...
Python3 循环语句
本章节将为大家介绍 Python 循环语句的使用。 Python 中的循环语句有 for 和 while。 Python 循环语句的控制结构图如下所示: while 循环 Python 中 while 语句的一般形式: while 判断条件(condition):执行语句(statements)…… 执行流程…...
时序数据处理中的拟合问题
对于深度学习或机器学习模型而言,我们不仅要求它对训练数据集有很好的拟合(训练误差),同时也希望它可以对未知数据集(测试集)有很好的拟合结果(泛化能力),所产生的测试误差被称为泛化误差。度量泛化能力的好坏,最直观的表现就是模型的过拟合(overfitting)和欠拟合(…...
[数据结构基础]排序算法第一弹 -- 直接插入排序和希尔排序
目录 一. 排序的概念及分类 1.1 排序的概念 1.2 常见的排序算法 二. 直接插入排序 2.1 直接插入排序的实现逻辑 2.2 直接插入排序的实现代码 2.3 直接插入排序的时间复杂度分析 三. 希尔排序 3.1 希尔排序的实现逻辑 3.2 希尔排序实现代码 3.3 希尔排序的效率测试 …...
厚积薄发打卡Day115:Debug设计模式<简单工厂、工厂方法、抽象工厂>
厚积薄发打卡Day115:Debug设计模式<简单工厂、工厂方法、抽象工厂> 简单工厂 定义 由一个工厂对象决定创建出哪一种产品类的实例(严格意义并不是设计模式,更是一种风格) 类型:创建型,但不属于GOF…...
python元组
python元组 文章目录python元组一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.创建元组2.访问元组3.修改元组4.删除元组5.索引及截取6.元组运算符7.内置函数总结一、实验目的 掌握元组的用法 二、实验原理 Python 的元组与列表类似,不同之处在…...
gcc中预定义的宏__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
今天在看Linux系统编程这本书的代码的时候看到了__GNUC__,不太清楚这个宏所以去查了一下,以此记录。GNU C预定义了一系列的宏,这些宏都是以双下划线开始的,这里只讲一下__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__,完…...
AxMath使用教程(持续更新中)
前言 这两天学了学Latex,主要是为了以后写毕业论文做铺垫,而且Latex在数学公式这一方面,要比Word方便许多,于是我就下载了一款国产的公式编辑器——AxMath。永久会员不贵,只要36元,而且软件很好用…...
day11 栈和队列 | 20、有效的括号 1047、删除字符串中的所有相邻重复项 150、逆波兰表达式求值
题目 20、有效的括号 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序…...
【前端面试】http面试整理
"一问一答"模型的协议 客户端通过http请求;服务器端根据请求返回客户想要的资源;客户端接收到资源;http是什么 HTTP是超文本传输协议,是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约…...
倒霉倒霉倒霉(传送门 bfs 三维数组 递归 综合运用
题目描述“啊!倒霉倒霉倒霉~”龙叔被困在一座大厦里了,可恶的瓦龙把这座大厦点燃了,他借机消灭龙叔。这座大厦有L层,每一层都有R*C个房间。熊熊火焰蔓延十分快,有的房间已经着火了,龙叔没办法通过。这时老爹…...
C++函数定义和调用介绍
C函数定义和调用介绍 函数的意义:利用率高,可读性强,利于移植。 一个C程序中主函数有且只有一个,是程序的入口,而函数(或称子函数)可以有很多。 每个 C 程序都至少有一个函数,即主…...
手把手带初学者快速入门 JAVA Web SSM 框架
博主也是刚开始学习SSM,为了帮大家节省时间,写下SSM快速入门博客 有什么不对的地方还请 私信 或者 评论区 指出 只是一个简单的整合项目,让初学者了解一下SSM的大致结构 项目先把框架写好,之后在填写内容 项目压缩包 完整的蓝奏…...
RocketMQ源码本地搭建调试
1 GitHub源码 git clone https://github.com/apache/rocketmq.git导入IDEA,可在命令行执行mvn compile一下,保证源码能够正确编译。本次我使用的master分支的版本-4.8.0。下面我们开始准备启动Namesrv。 2 启动Namesrv 到namesrv模块找到NamesrvStart…...
Axios 二次封装并使用
index.js import axios from "axios";let token localStorage.getItem("token"); // let token "123213"; class Request {// 自定义变量instance;constructor(config) {// console.log(config)// 创建axios 实例,变量接收this.in…...
【SpringCloud】Nacos集群搭建
集群结构图官方给出的Nacos集群图如下:其中包含3个nacos节点,然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx。我们接下来要尝试 Nacos集群搭建,效果图如下所示:三个nacos节点的地址:节点ipportnacos1l…...
【CSDN的2022与2023】普普通通的三年,从懵懂、焦虑到坚定、奋进,破除焦虑努力成为更好的自己
大家好,我是黄小黄!一名普通的软件工程在读学生。最近终于闲下来了一丢丢!借着休息之余,来写一篇年度总结散散心~与其说是年度总结,不如说是给大学生活与莽莽撞撞的自己一个交代叭! 这些都是小标题~碎碎念1…...
k8s单机版使用本地存储local-path-provisioner
在k8s单机环境中,我们经常使用本机路径作为持久化存储。在k8s官方文档中有两种方式使用本机存储,一种是hostPath,另一种是local volume,这两种都不支持动态扩容,并且程序移植改动比较大,而local-path-provi…...
MySQL优化(1)执行计划explain中type属性详解
系列文章目录1.初始化测试数据1.初始化表格(user表)2.初始化表格(product表)3.初始化表格(user表数据初始化)4.初始化表格(product表函数)5.初始化表格(product表数据初始…...
servlet过滤器Filter简要回顾-过滤请求字符编码,/和/*和/**的区别
servlet过滤器Filter简要回顾-过滤请求字符编码,/和/*和/**的区别servlet过滤器1.filter过滤器的含义2.filter过滤器的使用3.测试-过滤字符编码正确响应中文编码3.1 创建servlet用于显示中文字符3.2 自定义过滤器3.3 配置web.xml中的servlet映射以及过滤器请求拦截3.4 运行输出…...
Java链表OJ题
目录1. 删除链表中等于给定值val的所有结点2. 逆置单链表3. 链表的中间结点4. 链表中倒数第k个结点5. 将两个有序链表合并为一个新的有序链表6. 以给定值x为基准将链表分割成两部分7. 判断是否为回文链表8. 两个链表的第一个公共结点9. 判断链表中是否有环10. 链表开始入环的第…...
0、Spring工程构建Spring快速入门Spring配置文件详解注入Sprint相关API
1、Spring工程构建 创建工程项目目录文件夹 IDEA选择项目new一个module 配置案例 aop创建 创建并下载完毕后,点击file选择projert 选择按照的jdk版本 output选择当前目录, 点击右下方apply 选择facets,点击""号选择web 选择当前…...
网络原理之HTTP/HTTPS、TCP、IP四层协议栈
文章目录一、应用层(一)xml协议(二)json协议(三)protobuffer协议(四)HTTP协议1. 抓包工具,fiddler2. HTTP报文格式3. HTTP请求(Request)(1)URL基本…...
CS61B 2021spring HW0
HW 0: A Java Crash Course 文章目录HW 0: A Java Crash CourseA Basic ProgramCreative Exercise 1a: Drawing a TriangleCreative Exercise 1b: DrawTriangleExercise 2、3Optional: Exercise 4Java可视化orz表达积累参考资料这个hw是optional,然后主要是给至少学…...
自动驾驶环境感知——视觉传感器技术
文章目录1. 摄像头的成像原理1.1 单目视觉传感器的硬件结构1.2 单目视觉的成像原理 –小孔成像模型1.3 单目视觉的成像原理 – 像素坐标系1.4 单目视觉三维坐标系转换 – 外参1.5 单目视觉的坐标系转换 – 从世界坐标点到像素坐标1.6 单目视觉的特性2. 视觉传感器的标定2.1 视觉…...
分享148个ASP源码,总有一款适合您
ASP源码 分享148个ASP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 148个ASP源码下载链接:https://pan.baidu.com/s/1e2PvBmXxZA8C3IelkP8ZtQ?pwdj7lp 提取码&#x…...
Java线程的生命周期的五种状态
前面在《有关Java多线程的几个概念》(https://blog.csdn.net/helloworldchina/article/details/128753898)讲述了Java线程的生命周期的五种状态。在这里再详述一下线程的5种状态。 在java中,任何对象都要有生命周期,线程也一样&a…...
springboot自定义拦截器的简单使用和一个小例子
springboot自定义拦截器的使用1. 自定义拦截器2. 拦截器登录验证的小demo2.1 配置pom.xml2.2 创建User的bean组件2.3 创建需要的表单页面以及登录成功的页面2.4 编写controller映射关系2.5 自定义拦截器类,实现intercepetor接口2.6注册添加拦截器,自定义…...
APT之木马静态免杀
前言 这篇文章主要是记录手动编写代码进行木马免杀,使用工具也可以免杀,只不过太脚本小子了,而且工具的特征也容易被杀软抓到,指不定哪天就用不了了,所以要学一下手动去免杀木马,也方便以后开发一个只属于…...
设计模式 - 创建型模式_抽象工厂模式
文章目录创建型模式概述Case场景模拟工程模拟早期单机Redis的使用Bad ImplBetter Impl (抽象⼯⼚模式重构代码)定义适配接⼝实现集群适配器接口代理方式的抽象工厂类单元测试小结创建型模式 创建型模式提供创建对象的机制, 能够提升已有代码…...
9、断点调试
文章目录9、断点调试9.1 为什么需要Debug9.2 Debug的步骤1 添加断点2 启动调试3 单步调试工具介绍9.3 多种Debug情况介绍1 行断点2 方法断点3 字段断点4 条件断点5 异常断点6 线程断点7 强制结束9.4 自定义调试数据视图9.5 常见问题【尚硅谷】idea实战教程-讲师:宋红…...
yolo结构介绍
更新中 yolo结构: 这个是针对最早的v5版本1.0进行讲解,现在2022最新版本是V6.2。有一些细节的差别比如Backbone部分Focus倍替换成6*6的Conv,bottleneckCSP替换为C3,Neck部分SPP被替换成SPPF等 Release v1.0 ultralytics/yolov5 (github.com) # parameters nc: 80 # n…...
大数据技术架构(组件)7——Hive:Filter PushDown Cases And Outer Join Behavior
1.2、Filter PushDown Cases And Outer Join Behavior前提:关闭优化器set hive.auto.convertjoinfalse; set hive.cbo.enablefalse;Inner Join:1、Join On中的谓词: 左表下推、右表下推2、Where谓词:左表下推、右表下推-- 第一种情况: join on 谓词 selectt1.user_id,t2.user_i…...
【MySQL】第十二部分 子查询
【MySQL】第十二部分 子查询 文章目录【MySQL】第十二部分 子查询12. 子查询12.1 单行子查询12.2 多行子查询12.3 非相关子查询和相关子查询12.4 EXISTS 与 NOT EXISTS关键字总结12. 子查询 子查询 说白了就是嵌套查询,在一个查询语句中嵌套另外一个查询语句进行内部查询. 子…...
Day08 C++STL入门基础知识五——vector容器(下) 插入删除-数据存取-交换容器-预留空间【全面深度剖析+例题代码展示】
More haste, less speed. 欲速则不达 文章目录1. 承接上文2. 插入操作2.1 函数原型(总括)2.2 尾插尾删2.2.1 操作2.2.2 代码展示2.2.3 测试结果2.3 迭代器插入2.3.1 操作2.3.2 代码展示2.3.3 测试结果2.4 think小思考2.4.1 小疑问2.4.2 思路2.4.3 代码展示2.4.4 测试结果3. 删除…...
打工人必知必会(二)——劳动合同解除
目录 1、劳动合同的解除种类 2、协商解除劳动合同 3、用人单位解除劳动合同 1)过错性解除劳动合同 2)非过错性解除劳动合同 4、经济性裁员解除劳动合同 5、违法解除劳动合同 6、 劳动者解除劳动合同 提前30日以书面形式通知用人单位 员工即时解…...
量化选股——基于多因子模型的量化策略(第1部分—因子测算策略构建)
文章目录1.多因子模型概述2.因子挖掘3.多因子策略4.多因子策略构建基于多因子的策略通用流程Fama-French三因子因子效果测算方法因子测算结论&量化策略构建东西有点多,拆开成多个文章,边写边整合~,应该会分成2部分: 第1部分—…...
(Java高级教程)第四章必备前端基础知识-第三节1:JavaScript简介和基础语法
文章目录一:JavaScript简介(1)JavaScript概述(2)JavaScript特点(3)JavaScript运行过程(4)JavaScript组成(5)JavaScript的引入方式和基本使用&…...
好的质量+数量 = 健康的创作者生态
缘起 CSDN 每天都有近万名创作者发表各种内容, 其中博客就有一万篇左右。 这个数量是非常可喜的,这也是 CSDN 的产品、研发运营小伙伴、和各位博主持续工作的结果。 衡量一个 IT 内容平台,除了数量之外,还有另外一些因素…...
利用Golang可选参数实现可选模式
本文讨论Golang函数可选参数及函数类型,以及如何利用可选函数类型实现可选模式。同时通过构造函数作为示例,实现强大带可选参数的构造函数,让代码更直观、灵活、支持扩展。 从需求开始 可选参数给函数传递额外参数扩展或修改其行为…...
【Git】Git 的基本使用
Git的简介 Git是一个版本管理控制系统(缩写VCS),是一个工具,github或者gitee是git命令行工具的网站化。它可以在任何时间点,将文档的状态作为更新记录保存起来,也可以在任何时间点,将更新记录恢复回来。 git的诞生历…...
Linux系统(项目管理和LINUX)
目录 一、VMWare安装和使用 1.安装VMware 2.使用VMware 二、常用命令 三、常用配置 环境变量配置: 系统文件配置: 软件包配置: 安全配置: 其他配置: 四、Xshell的使用 安装 Xshell: 启动 Xshe…...
在 PHP中使用 Redis 缓存的方法有哪些
在 PHP 中使用 Redis 作为缓存的方法非常多样化,因为 Redis 提供了丰富的数据结构和命令集。以下是一些常见的 PHP 中使用 Redis 缓存的方法: 字符串缓存 Redis 最基本的数据结构是字符串(string),你可以用它来缓存简…...
【DeepLearning.AI】吴恩达系列课程——使用ChatGPT API构建系统(持续更新中——)
目录 前言一、Language Models, the Chat Format and Tokens(LLM,交互形式)1-1、加载api-key1-2、使用辅助函数(即指令调整LLM)1-2、使用辅助函数(聊天格式)1-3、辅助函数修改(输出字…...
企业防泄露如何做到安全有效
随着信息时代的急速演进,企业的重要商业机密越来越多地以电子文档的形式存在。常见的CAD图纸、Office文档承载着公司的核心价值和竞争优势,同时也面临着前所未有的数据安全威胁。确保这些重要信息的文档安全已经成为每个企业必须直面的挑战。在这样的背景…...
stable diffusion最推荐安装的几个模型,大佬们都在用!
stable diffusion(稳定扩散)(简称SD)正在席卷世界,让任何人都可以使用各种风格的人工智能技术生成图像。只需点击几个按钮,您就可以生成一个人的照片级真实感图像,或一幅高精度的风景数字插图。通过使用精心制作的提示…...
模糊的图片文字,OCR能否正确识别?
拍照手抖、光线不足等复杂的环境下形成的图片都有可能会造成文字模糊,那这些图片文字对于OCR软件来说,是否能否准确识别呢? 这其中的奥秘,与文字的模糊程度紧密相连。想象一下,如果那些文字对于我们的双眼来说&#x…...
SQL 基础 | JOIN 操作介绍
在SQL中,JOIN是一种强大的功能,用于将两个或多个表中的行结合起来,基于相关的列之间的关系。 JOIN操作通常用在SELECT语句中,以便从多个表中检索数据。 以下是几种基本的JOIN类型以及它们的用法: INNER JOIN࿱…...
【快捷部署】022_ZooKeeper(3.5.8)
📣【快捷部署系列】022期信息 编号选型版本操作系统部署形式部署模式复检时间022ZooKeeper3.5.8Ubuntu 20.04tar包单机2024-05-07 一、快捷部署 #!/bin/bash ################################################################################# # 作者ÿ…...
C语言 自定义类型——联合体
目录: 一、联合体是?声明计算内存大小 二、联合体的特点例如 三、联合体大小的计算规则: 四、应用习1习2 一、联合体是? 联合体和结构体差不多,但是其最大的区别在于联合体所有的成员共用一块内存空间。所以联合体也叫共用体。联…...
基于FPGA的累加器及数码管显示VHDL代码Quartus仿真
名称:基于FPGA的累加器及数码管显示VHDL代码Quartus仿真(文末获取) 软件:Quartus 语言:VHDL 代码功能: 累加器及数码管显示 1、可以通过按键输入1~9 2、数字输入后进行累加,将累加结果显示…...
[COCI2022-2023#1] Berilij 题解
推荐在 cnblogs 上阅读。 Solution P9030 [COCI2022-2023#1] Berilij 本题解转载翻译自官方题解:COCI 2022/2023 CONTEST 1 Part 1 让我们定义图形 G G G,顶点代表飞船,边代表两艘飞船外部接触的情况。此外,让边的边权成为它…...
c++扩展C++对C的扩展
C对C的扩展 ::作用域运算符 通常情况下,如果有两个同名变量,一个是全局变量,另一个是局部变量,那么局部变量在其作用域内具有较高的优先权,它将屏蔽全局变量。 //全局变量 int a 10; void test() {/* 变量a是test函…...