Vue Router 学习
前言
随着ajax兴起,页面请求越来越多,是用来处理单页应用 SPA(single page web application)的不二之选
SPA应用特点体现在如下:
- 页面交互是无刷新
- 页面的跳转也是无刷新的
原理是 匹配不同的 url 路径,进行解析,然后动态的渲染出区域 html 内容
每当切换路由的时候,在DOM中删除上一个路由节点(from
),渲染一个新的节点(to
)-- 可使用缓存路由
keep-alive
,从而不使用
这种销毁再创建的模式
可是url 每次变化的时候,都会造成页面的刷新,
那么解决办法就是在改变 url 的情况下,保证页面的不刷新
2014年以前前端路由是通过hash模式进行
通过类似这样 http://www.xxx.com/#login
这种 #的后面部分 ,后面的 hash 值会发生变化
并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。
另外每次 hash 值的变化,还会触发
hashchange
事件, 从而我们可知hash 发生了哪些变化*** window.onhashchange***
然后我们可以监听
hashchange
来实现页面的更新
14年后HTML5 标准发布多了两个API `pushState· `replaceState`
至此url路径变得美观。(如果你愿意使用 vue-router 的同时开启 history
模式的话)
mode:'history'
Vue Router 在模块化编程中的用法
现在来配置一个简单路由
加入路由跳转页面的组件都创建在 src 目录下的 view下比较好
view 下为页面级组件,一般不复用,一般引用 components下面的小组件
components 下为小组件,常用组件,一般会复用
router
名词,路由器(发出动作者)
route
名词,路由(所走的路径)
routes
名词(复数)(代表一组路由路径)
src 目录下创建一个文件夹为
router
在router 文件夹下 创建
index.js
文件-
main.js
中导入 且声明使用import router from './router' // 省略了 /index.js 这是因为webpack默认 index true
new Vue({ router, //实例中使用 store, render: h => h(App) }).$mount('#app')
-
编写
index.js
文件import VueRouter from 'vue-router' //导入前 记得导入前置 vue
Vue.use(VueRouter) // 使用
-
产生一个对象并向外暴露
export default new VueRouter({ })
-
在
routes
中配置n
个路由export default new VueRouter({ mode:'history', routes: [ //多条对象,理因是一个数组 { // 第1条路由 path: '/', component: xxx // 对应映射的组件名 请在使用之前先导入组件 }, { // 第2条路由 path: '/xxx', } ] })
在
App
组件中的模板中 在需要点击跳转路由的地方指定router-link
<router-link to="/xxx">这里配置要显示的文本,相当于 a 连接</router-link>
to 里面的参数一定要写
routers
中的path
对应一致
- 在指定变化的部分中加入
router-view
<templete>
<div id='app'>
<nav>
<router-link to="">Home</router-link>
<router-link to="">About</router-link>
</nav>
<div class="main-body">
<router-view></router-view> <!--这里是需要变化的部分-->
</div>
</div>
</templete>
现在来配置一个嵌套路由
配置嵌套路由的时候,会出现如下情况:
下面这些问题,好像是我当初
router-link
里面的to
与index.js
里面的路由映射对应>不上所以才产生的问题, 请仔细检查自己有没有配错!
指定的 层级嵌套路由路径不正确 (时刻注意
path
中最左边的/
代表根路径,请写全,/father/child
,或者 直接省略为xxx
)
- 在加入子路由嵌套的时候使用简写
path
会发生问题,点击子组件后不显示,(这个问题发生在 父组件的path
为/
的时候),将/
更改为具体的名称(或者老老实实写全路径)const routes = [ { path: '/', name: 'home', component: Home, children: [ { path: '/home/news', // 靠近path 最左侧的那个 / 代表根路径 name: 'news', component: News }, { path: 'message', // 这个时候简写会出现问题,点击会渲染不出,必须写全/home/message name: 'message', component: Message } ] }, { path: '/about', name: 'about', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ]
将
/
修改为具体路径可解决{ path: '/home', //修改在这里 name: 'home', component: Home, children: [ { path: '/home/news', name: 'news', component: News }, { path: 'message', // 简写没问题了 name: 'message', component: Message } ] },
在写path的时候,如果在 router-link 中用到了该 path,请一定对照写一致,
在写name的时候,必须写引入的组件中 组件的名字,如:
export default { name: 'Login', //假设这是 登陆组件 }
在路由中配置:
{ path:'/login', //随意指定 name:'Login', //不能随意指定,必须大小写一致,写成login就不行,vue默认按照组件名称渲染路由 component:Login }
缓存路由组件
用来保持组件的状态,在
tab
选项卡中跳转有时候需要查看下上一个tab
的信息,但是之前的数据是从后台获取来的,这个时候不需要再次请求数据(实时性要求比较低的),减小服务器压力,来使用
keep-alive
保持,缓存这个组件对象
<keep-alive>
<router-view></router-view>
</keep-alive>
使用编程式路由
意思就是不使用
<router-link> xxx </router-link>
,这样的点击跳转,在代码执行的时候决定跳转路由
this.$router.push('/toPath')
使用 watch
来监视路由的最新变化
vue中,获取实时最新的状态的方法就是 watch
如果有以下需求:
左边的树结构是 发起ajax 请求成功后渲染出来的,
左边的每一个树节点node 都有唯一的一个 Key标识
当点击某一个node的时候,进行路由跳转,需要传递对应的 Key标识改变路由跳转
结构和需求看起来像下面这样:
路由跳转时携带参数 params
(此处没用 query
来携带参数)
params
与 query
的区别请点击
this.$router.push({name:'ModuleConfig',params:{index:n}})
// 得到 n 的值不在这里提出
右边的router-view
区域中 使用watch
data(){
return{
index: this.$route.params.index
}
}
好像有说法:
router
只负责写(传)
route
只负责读(取)
'$route'(to,from){
this.index = to.params.index //获取实时最新的 后缀 index,然后index 变化时,整个表单变化
}
// 左值 index 定义在 data 中(普通属性)
// 右值 在路由跳转的携带参数中取出
router
中的 index.js
修改配置
const routes = [
{
path:'/ModuleConfig/:index', //要对应
name:'ModuleConfig',
component:ModuleConfig,
}
]
这里还可以将
index
定义成computed
属性
computed:{
index(){
return this.$route.params.index
}
}
如果你需要分别拿到
oldvalue
,newvalue
,那显然watch
更合适
watch
更像是为属性改变的前后定义的一个钩子函数,可以点击此处 参考查看我的另一篇文章中写到的区别
以后再慢慢更新,最后说下:
任何时候都参照下 Vue 风格指南都是好的。比如
static
与assets
文件夹的区别,又比如view
与components
文件夹的区别,说不定每次 vue-cli 的更新都会带来vue ui
构建项目后的文件夹不一致呢? GO to Vue 风格指南