FE - 走向Node与Webpack 之路 - 必须知道的 Vue Router !
推荐资料vue-router 2 资料中个别东西不理解的,本文可以找到。(真没有,就评论或私信)1. 安装与配置安装:npm install vue-router -D (-save-dev)配置:为了使用方便,新建 router.js 进行注册和配置VueRouter , 比如:router.js/*** Created by yuan on 2/24/2017.*/import Vue
推荐资料
资料中个别东西不理解的,本文可以找到。(真没有,就评论或私信)
1. 安装与配置
安装:
npm install vue-router -D (-save-dev)
配置:
为了使用方便,新建 router.js
进行注册和配置VueRouter
, 比如:
router.js
/**
* Created by yuan on 2/24/2017.
*/
import Vue from "vue";
import VueRouter from "vue-router";
//全局注册
Vue.use(VueRouter);
const router = new VueRouter({
routes:[
]
});
export default router; //提供接口
配置 在 vue 实例中: (main.js)
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
new Vue({
el: '#app',
router,//配置
render: h => h(App)
})
Router 配置
declare type RouteConfig = {
path: string;
component?: Component;
name?: string; // for named routes (命名路由)
components?: { [name: string]: Component }; // for named views (命名视图组件)
redirect?: string | Location | Function;
alias?: string | Array<string>;
children?: Array<RouteConfig>; // for nested routes
beforeEnter?: (to: Route, from: Route, next: Function) => void;
meta?: any;
}
这在上面的文档里摘的,具体内容可以看看里面的。
举个例子:
const router = new VueRouter({
mode: 'history',
routes: [
//动态路径参数,以冒号开头
{
path: "/user/:id",
component: User,
name: "u",
},
{
path: "/demo",
components: {//多个组件
demo: Demo,
demo1:Demo1,
}
},
]
});
- mode
三个值 : hash” | “history” | “abstract”
- hash : 默认值,地址栏 会多个
#
号:http://localhost:8080/#/
- history : 指定的时候,就正常了,没有
#
号 - abstract : 不知道!!
- hash : 默认值,地址栏 会多个
- routes
指定地址 和 组件等 ,路由匹配后面说!
2.路由匹配
路由地址匹配,常见的类型有 :
localhost/user/{id}
localhost/user?id=12
(1)动态路由匹配
// 动态路径参数 以冒号开头,后面是组件名称(单个组件)
{ path: '/user/:id', component: User }
使用的时候,可以直接使用router-link (路径前面有“/” 表示根路径):
<router-link to="/user/12">动态匹配:/user/12</router-link><br><br>
User组件中就可以获取到12,通过 route对象获取:
<template>
<div>
<h1>User : params </h1>
<h3>{{this.$route.params.id}}</h3>
</div>
</template>
(2)编程式导航
简言 :就是通过 router 对象进行操作(非route对象);
比如:
routers 一个对象
{
path: "/user/:id",
component: User,
name: "user", //命名路由
}
编程式 操作
// 对象 : VueRouter 下 routes 下的 path 路径
router.push({ path: '/user/12' })
// 命名的路由 : VueRouter 下 routes 下的 name 路径
router.push({ name: 'user', params: { id: 12 }})
// 带查询参数,变成 /user?id=12
router.push({ path: 'user', query: { id: 12 }})
在 Component 中使用的时候,使用 this.$router 获取 router对象并进行操作。
router-link
// router.push(对象) 该对象均可以在router-link 传入
<router-link :to="对象">
(3)重定向 与 别名
VueRouter 下 router对象配置
重定向到 b
{ path: '/a', redirect: '/b' }
重定向到路由名称为foo的路径
{ path: '/a', redirect: { name: 'foo' }}
重定向指定函数
{ path: '/a', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}
别名 :访问 b 时 ,地址为 b , 内容为 a .
{ path: '/a', component: A, alias: '/b' }
3.命名视图
router-view
组件是一个 functional
组件,渲染路由路径匹配到的视图组件;
单组件:
{
path: "/home",
component: Home, // 单组件
name: "h",
}
入口组件下实现 : 自动将 Home
组件 渲染到 router-view
下
// 在 App.vue template 下
<router-view></router-view>
多组件 : 属性 name
{
path: "/demo",
components: { // 多组件 指定 components , 渲染不同router-view
demo: Demo,
demo1:Demo1,
}
}
入口文件下实现: 将不同组件名的 渲染到 相同name
的 router-view
上。
<div >
<router-view name="demo"></router-view>
<router-view name="demo1"></router-view>
</div>
行为表现 :
通过路由将组件渲染到 router-view
中,它也是组件,可以配合 过渡效果<transition>
和 组件缓存 <keep-alive>
使用。如果同时使用的话 <keep-alive>
保证在内层使用。
<transition>
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
4.数据加载
(1)vue 生命周期
vue的生命周期也对应component的生命周期,可以在component中使用生命周期的钩子已达到自己的目的。
比如:
可以在 created 钩子(回调)中执行加载数据操作
通过上图所示,可以看见生命周期的钩子(回调):
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestory
示例:
在 mounted中加载数据
export default {
name: "user",
data(){
return {
post: null,
}
},
mounted(){
let id = this.$route.params.id
this.$http.getUserInfo(id,response(data){
})
}
}
(2)数据获取
路由数据获取也有钩子(回调),两种方式:
这里面刚开始看的时候,有些懵,导航?什么鬼。其实就是地址栏URL
, 下面我简言说明
先加载数据,后跳转URL
未完成前,触发某个路由时,在路由的 beforeRouteEnter
钩子中获取数据,在数据获取成功后执行跳转。
比如:
export default {
name: "user",
data(){
return {
post: null,
}
},
watch: {
//监听route 数据变化,route数据是只读的!
'$route': 'changData'
},
methods: {
changData: function () {
let id = this.$route.params.id;
console.log("changData : " +id);
this.post = "changData change post !"+id;
},
test: function () {
this.$router.push({path: "/user/188"});
}
},
beforeRouteEnter(to, from, next){
//先完成数据加载,再完成导航,后渲染组件
let id = to.params.id;
console.log("beforeRouteEnter : " + id);
//获取数据成功
// next(true);
//获取数据失败 : 拦截不跳转
// next(false);
//对data数据赋值
next(vm => vm.post = ('beforeRouteEnter load'+id));
},
}
beforeRouteEnter 钩子: 内置 next 方法 当next(true)时,执行跳转,否则拦截跳转
先跳转URL,后加载数据
先完成跳转,然后在接下来的组件生命周期钩子中获取数据。比如 created 和 mounted中执行 加载
export default {
name: "user",
data(){
return {
post: null,
}
},
mounted(){
// mounted中
let id = this.$route.params.id
this.$http.getUserInfo(id,response(data){
})
},
created(){
// created 中
let id = this.$route.params.id
this.$http.getUserInfo(id,response(data){
})
}
(3)懒加载
当打包应用时候,js 包会变得十分的大,影响页面加载。把 不同路由对应的组件分割成不同的代码块,当访问这个路由的时候,再去加载对应组件,就快速了。
定义异步组件 : 将现有的组件,定义为 异步组件,后配置路由,即可实现懒加载
定义Foo组件为异步组件!
const Foo = resolve => {
// require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
require.ensure(['./Foo.vue'], () => {
resolve(require('./Foo.vue'))
})
}
这样也可以定义
const Foo = resolve => require(['./Foo.vue'], resolve)
使用异步组件 : 使用异步组件和直接使用组件一模一样
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo
}
]
})
5.进阶
(1)路由钩子(回调)
上面的数据加载中已经使用 beforeRouteEnter
钩子数据回调;
路由对象钩子
- beforeEach : 路由触发时,执行前执行的回调钩子
全局
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// to : 进入目标的route路由信息对象
// from: 离开的 route路由信息对象
// next : function , next(true) 执行跳转,next(false) 拦截跳转
})
局部
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
- afterEach :路由触发时,执行后回调的钩子
// 也可以全局和局部设置 ,但没有next 方法,只有route对象
router.afterEach(route => {
// ...
})
组件内钩子:
- beforeRouteEnter
- beforeRouteUpdate (2.2 新增)
- beforeRouteLeave
比如:
export default {
name: "user",
data(){
return {
post: null,
}
},
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当钩子执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是改组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
注意 beforeRouteEnter
方法 ,无法通过this
获取vue
实例,因为该方法执行时,vue
还未加载,可以通过下面next
方法获取vue
实例。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
(2)过渡效果
因为 <router-view>
也是组件,所有可以添加过渡效果,比如
<transition>
<router-view></router-view>
</transition>
(3)HTML5 History mode
如果是混合开发的话,使用默认的hash
就可以,这时候URL
后面有个#
符号:
http://yoursite.com/index.html/#/home
如果是单个服务器跑SPA应用的话,可以配置为 history,这样看起来更正式点;
http://yoursite.com/user/id
mode属性
mode
类型: string
默认值: "hash" (浏览器环境) | "abstract" (Node.js 环境)
可选值: "hash" | "history" | "abstract"
6.router与route 对组件注入
router :
当前router实例,常用方法:
- router.beforeEach(guard)
- router.afterEach(hook)
- router.push(location)
- router.go(n)
- router.replace(location
- router.currentRoute : 获取当前 route 路由信息对象
route :
路由信息对象,当前路由状态信息,常用属性
$route.params
$route.query
$route.path
$route.name
组件内使用
- 在Component中使用 router 对象 ,使用 this.$router调用 。
this.$router.push({path: "/user/188"});
- 在Component中获取route 路由信息对象,使用 this.$route调用。
this.$route.params.id
下篇: 单页面应用 与 传统web应用
完
更多推荐
所有评论(0)