路由模式
History模式的时候 刷新页面会404
当我们进入到子路由时刷新页面,web容器没有相对应的页面此时会出现404
所以我们只需要配置将任意页面都重定向到 index.html,把路由交由前端处理就可以了。
解决方法
1 | location / { |
简单路由
基本配置
默认的路由配置是这样的
1 | import Vue from "vue"; |
Vue的路由有两种模式 hash
和 history
hash
模式对应的路由是类似于这个样子的 http://localhost:8080/#/about
也就是说对于搜索引擎来说所有的页面只有一个路径 就不利于搜索引擎索引
history模式
history
模式对应的路由是这个样子的http://localhost:8080/about
一般不建议使用history
模式,这种需要服务器需要配置一下。
在使用 Vue 的 history
模式时,由于前端路由是通过修改 URL 来实现的,所以在部署到服务器上时,需要进行一些特殊的配置才能确保正常访问。
以下是一个常见的配置流程:
Nginx添加配置:
在 Nginx 的配置文件中,添加一个用于处理前端路由的 location 配置,如下所示:
1 | location / { |
这个配置将会重定向所有请求到 index.html
,这样访问任何一个路由都会返回同一个首页。
然后 Vue Router 会根据 URL 来动态加载相应的组件。
保存并重新启动 Nginx 服务,使配置生效。
配置说明:
其中try_files $uri $uri/ /index.html;
是一个 Nginx 配置指令,用于处理前端路由的重定向。
下面是对每个参数的解释:
$uri
:尝试匹配当前请求的文件路径,如果找到该文件,则返回该文件。$uri/
:尝试匹配当前请求的目录路径,如果找到该目录下的索引文件(如index.html
),则返回该文件。这个参数主要用于处理目录路径的情况,例如
/about
这样的路由。/index.html
:如果上述两个尝试都失败,将请求重定向到index.html
,也就是前端路由的入口文件,但是URL不会变。
这个配置的目的是确保所有请求都重定向到前端的 index.html
文件。
由于前端路由是通过修改 URL 来实现的,所以服务器需要配置这样的规则来处理这些路由请求。
在重定向到 index.html
后,Vue Router 会根据 URL 来动态加载相应的组件。
这样的配置使得服务器在处理前端路由请求时不会报错,并且确保前端应用的正确渲染。
嵌套路由
Home.vue
1 | <div id="nav"> |
router.js
1 | { |
redirect 用来跳转到home路由时 自动加载子路由
路由懒加载
一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)
1 | const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue') |
路由跳转
标签形式
1 | <div id="nav"> |
JS形式
基本
1 | // 字符串 |
传参
query带参数
1 | // 带查询参数,变成 /register?userId=123 |
取值方式
1 | this.$route.query.userId; |
params带参数
1 | // 命名的路由 |
对应的取值方式
1 | this.$route.params.userId; |
注意:
下面的这种方式传参是错误的
1 | // 这里的 params 不生效 |
router带参数
1 | { |
然后带参数跳转
1 | this.$router.push({path:'/operate/${id}'}) |
获取参数
1 | this.$route.params.id |
简单的SEO配置
首先把路由模式设置为history,再添加meta信息 添加后的配置如下
1 | import Vue from "vue"; |
上面是在路由配置的JS中,当然也可以在在main.js
中添加
1 | router.beforeEach((to, from, next) => { |
注意上面的配置要放在创建Vue对象之前
1 | new Vue({ |
这样访问路由的时候 title
和 content
就会自动设置了。
Vue-meta的使用
安装
1 | npm install --save vue-meta |
router.js中添加
1 | import Router from 'vue-router' |
页面中
1 | <script> |
vue-meta 把引号做了转义处理,加入 __dangerouslyDisableSanitizers: ['script']
后,就不会再对这些字符做转义了,该字段使用需慎重!
当然我们也可以在这里引用JS和CSS(不建议这样处理)
1 | <script> |
路由的渲染
如果我们的页面有嵌套路由的时候 页面渲染的时候会先渲染子路由对应的页面 导致如果子路由获取外层的高度的时候获取的一直是0,因为外层还未渲染 解决的方法就是:在父页面渲染后通知子页面获取
比如我用vuex保存外层的高度
1 | export default new Vuex.Store({ |
添加公共的事件监听
1 | var vue_event = new Vue(); |
父页面
1 | this.page_height = window.document.body.offsetHeight - this.$refs.header.offsetHeight - parseInt(getComputedStyle(this.$refs.main).marginBottom) - 2 + "px"; |
子页面接收
1 | mounted() { |
路由守卫
判断登录状态路由跳转
1 | router.beforeEach((to, from, next) => { |
路由面包屑
1 | <el-breadcrumb separator="/" style="margin-left: 10px"> |
vuex
1 | import Vue from "vue"; |
router
1 | router.afterEach((to) => { |
排除根层级
1 | router.afterEach((to) => { |
后记
现在有这个一个需求,我们像让面包屑中出现类似的结构 首页
=>用户列表
=>用户详情
,但是用户详情
不是用户列表
的子路由,所以用to.matched
是无法匹配到的,所以只能我们自己来处理路由的数组。
路由的代码改成如下即可:
1 | let routers_all = []; |
Menu回显
1 | <Menu |
监听
1 | export default{ |
路由重置
1 | const createRouter = () => |
动态添加路由
1 | let routes = [ |
注意
默认添加路由后,在vue-devtools中并不能看到新路由。
要添加
1 | router.options.routes = router.getRoutes() |
常见问题
push相同路由报错
push相同路由报错的解决方式
1 | //获取原型对象上的push函数 |
replace相同路由报错
替换原函数
1 | //获取原型对象上的replace函数 |
添加判断
1 | if (this.$route.path !== "/home/index") { |
添加参数
1 | this.$router.replace({ |
使用location.href
1 | location.href = "/#/home/index"; |
路由相同参数不同
路由相同参数不同 无法触发路由。
推荐方式2和方式3。
解决方法:
方式1
给 router-view 设置 key 属性为路由的完整路径
1 | <keep-alive> |
这种方法我觉得应该是一劳永逸的方法,可能对性能造成一定损耗。
不适用于一个tab切换路由并加载列表的组件,会造成页面白屏。
方式2
官方给出的方法是通过 watch 监听路由变化,做判断路由路径然后调用响应的方法
页面初始化处理放在pageLoad
,不要放在mounted
中。
监听路由
1 | watch: { |
方式3
监听参数
页面初始化处理放在pageLoad
,不要放在mounted
中。
1 | watch: { |