1. SPA(Single Page Application)
- 比后端渲染有更好的性能
- Ajax前端渲染,不支持浏览器的前进、后退操作
- SPA单页面应用程序:整个系统只有一个页面,内容的变化是通过Ajax异步请求实现的局部刷新,同时支持浏览器地址栏的前进、后退操作
- 基于URL的hash,是SPA的实现原理
- 前端路由是也SPA实现的基础
2. Vue-Router的基本使用
代码实例
<!--1-1. 先引入 vue.js 文件-->
<script src="js/vue.js"></script>
<!--1-2. 再引入 vue-router.js 文件-->
<script src="js/vue-router.js"></script>
<div id="app">
<!--2. 添加路由链接-->
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
<!--3. 添加路由填充占位符-->
<router-view></router-view>
</div>
<script>
// 4-1. 定义路由组件--User组件
const User = {
template: '<h1>User 组件</h1>'
}
// 4-2. 定义路由组件--Register组件
const Register = {
template: '<h1>Register 组件</h1>'
}
// 5.创建Vue-Router组件对象并配置路由规则
const pathRouter = new VueRouter({
routes: [
{path: '/user', component: User},
{path: '/register', component: Register}
]
});
const vm = new Vue({
el: '#app',
data: {
},
// 6. 将VueRouter实例对象挂载到Vue实例对象上
router: pathRouter
});
</script>
2-1.Vue-Router使用步骤:
- 引入
vue.js
和vue-router.js
文件,<script src="js/vue.js"></script>
要先于<script src="js/vue-router.js"></script>
引入,因为Vue-Router依赖Vue - 使用
<router-link>
标签,添加路由连接,<router-link to="/user">User</router-link>
,Vue默认情况下会把<router-link>
替换成<a>
,并且把to="/user"
替换成href="#/user"
- 使用
<router-view>
,Vue会把<router-link>
的to
属性值对应的内容显示在<>router-view>
所在的位置处 - 根据Vue组件的声明语法,定义路由组件
- 创建VueRouter路由实例对象,并把第4步定义的路由组件配置到路由实例对象中
- 将VueRouter实例对象挂载到Vue实例对象上
2-2.Vue-Router路由重定向功能
通过重定向功能,我们可以配置页面在首次打开时需要展示的内容,是在2-1.Vue-Router使用步骤中第4步的定义路由组件中进行配置。如下添加:
// 创建Vue-Router组件对象
const pathRouter = new VueRouter({
routes: [
{path: '/', redirect: '/user'}, // 路由重定向配置 将访问路径'/'的请求重定向到路径/user'上
{path: '/user', component: User},
{path: '/register', component: Register}
]
});
3.Vue-Router 路由嵌套
路由嵌套是指在一个路由组件渲染的页面中还有路由组件,实现代码示例
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<div id="app">
<router-link to="/userLogin">User Login</router-link>
<router-link to="/register">User Register</router-link>
<router-view></router-view>
</div>
<script>
const userLogin = {
template: '<h1>用户登录</h1>'
}
const userRegister = {
template: `
<div>
<h1>用户注册</h1>
<hr/>
<router-link to="/register/link1">Link1</router-link>
<router-link to="/register/link2">Link2</router-link>
<router-view />
</div>
`
}
const link1 = {
template: '<h3>link1</h3>'
}
const link2 = {
template: '<h3>link2</h3>'
}
const pathRouter = new VueRouter({
routes: [
{path: '/user', component: userLogin},
{path: '/register', component: userRegister, children: [
{path: '/register/link1', component: link1},
{path: '/register/link2', component: link2}
]}
]
});
var vm = new Vue({
el: '#app',
data: {
},
router: pathRouter
});
</script>
在路由定义规则中使用children
来指定子路由的路由规则
{path: '/register', component: userRegister,
children: [
{path: '/link1', component: link1},
{path: '/link2', component: link2}
]
}
3-1.多级路由嵌套
如果有多级嵌套,可以继续嵌套,三级嵌套代码如下:
<script>
const userLogin = {
template: '<h1>用户登录</h1>'
}
const userRegister = {
template: `
<div>
<h1>用户注册</h1>
<hr/>
<router-link to="/register/link1">Link1</router-link>
<router-link to="/register/link2">Link2</router-link>
<router-view />
</div>
`
}
const link1 = {
template: `
<div>
<h3>link1</h3>
<hr/>
<router-link to="/register/link1/link1-1">Link1-1</router-link>
<router-link to="/register/link1/link1-2">Link1-2</router-link>
<router-view />
</div>`
}
const link2 = {
template: '<h3>link2</h3>'
}
const link1_1 = {
template: '<h5>link1-1</h5>'
}
const link1_2 = {
template: '<h5>link1-2</h5>'
}
const pathRouter = new VueRouter({
routes: [
{path: '/user', component: userLogin},
{path: '/register', component: userRegister, children: [
{path: '/register/link1', component: link1, children: [
{path: '/register/link1/link1-1', component: link1_1},
{path: '/register/link1/link1-2', component: link1_2}
]},
{path: '/register/link2', component: link2}
]}
]
});
</script>
在路由规则定义的代码出我们看到三级路由嵌套的代码:
routes: [
{path: '/user', component: userLogin},
{path: '/register', component: userRegister,
children: [
{path: '/register/link1', component: link1,
children: [
{path: '/register/link1/link1-1', component: link1_1},
{path: '/register/link1/link1-2', component: link1_2}
]
},
{path: '/register/link2', component: link2}
]
}
]
4.Vue-Router 动态路由匹配
有多个路径对应同一个路径组件的情况,Vue提供了动态路由的功能,实现多个路径与一个路由组件的对应关系,代码如下:
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
<div id="app">
<router-link to="/page/1">Page1</router-link>
<router-link to="/page/2">Page2</router-link>
<router-link to="/page/3">Page3</router-link>
<router-link to="/query">Query</router-link>
<router-view></router-view>
</div>
<script>
var pageCom = {
template: `
<h1>Page {{ $route.params.pid }}</h1>
`
}
var queryCom = {
template: `
<div>
<h1>Query Page</h1>
<hr/>
<router-link to="/query/1">Query 1</router-link>
<router-link to="/query/2">Query 2</router-link>
<router-view></router-view>
</div>
`
}
var queryPage = {
template: '<h3>Query Page{{ $route.params.qid }}</h3>'
}
var router = new VueRouter({
routes: [
{path: '/page/:pid', component: pageCom},
{path: '/query', component: queryCom,
children: [
{path: '/query/:qid', component: queryPage}
]
}
]
});
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
对于路径<router-link to="/page/1">Page1</router-link>
、<router-link to="/page/2">Page2</router-link>
和<router-link to="/page/3">Page3</router-link>
对应的路由组件是:
var pageCom = {
template: `
<h1>Page {{ $route.params.pid }}</h1>
`
}
因此可以在VueRouter实例的路由规则中进行动态路由配置:
routes: [
{path: '/page/:pid', component: pageCom},
...
}
在路由规则中的:pid
是动态参数,根据路径不同,参数的取值也有所不同。对应的路由组件中 {{$route.params.pid}}
,其中$route.params
是从Vue-Router获取参数的固定内容,.pid
要与路由规则中的动态参数名保持一致。
5. Vue-Router参数传递
动态路由是有多个路径对应同一个路由组件,也就是对于路由组件来说,路径中有可变参数,而在路由组件中获取到路径中的可变参数是需要{{route.params.[参数名]}}
来获取的。除了通过动态路由传递参数,Vue-Router还提供了以下几种方式进行参数传递:
5-1. props属性值为布尔类型
代码示例
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
<div id="app">
<router-link to="/item/1">商品1</router-link>
<router-link to="/item/2">商品2</router-link>
<router-link to="/item/3">商品3</router-link>
<router-link to="/query">商品查询</router-link>
<router-view></router-view>
</div>
<script>
var itemCom = {
props: ['id'],
template: `
<div>
<h1>商品{{id}}</h1>
</div>
`
}
var queryCom = {
template: '<h1>商品查询</h1>'
}
var router = new VueRouter({
routes: [
{path: '/item/:id', component: itemCom, props: true},
{path: '/query/', component: queryCom}
]
});
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
上述代码中实现参数传递的主要配置是在路由规则里添加props: true
,同时需要在组件声明中添加props: ['id']
`
5-2. props属性值为对象类型
代码示例
<div id="app">
<router-link to="/item/1">测试商品1</router-link>
<router-link to="/item/2">测试商品2</router-link>
<router-link to="/item/3">测试商品3</router-link>
<router-view></router-view>
</div>
<script>
const itemCom = {
props: ['id', 'name', 'price'],
template: `
<div>
商品页面 <br>
商品ID:{{id}} -- 商品名称:{{name}} -- 商品价格:{{price}} 元
</div>
`
}
const router = new VueRouter({
routes: [
{path: '/item/:id', component: itemCom, props: {name: '测试商品1', price: 20}}
]
});
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
通过布尔类型的props配置,可以把动态路由的参数传递到组件中。如果要传递其他参数,就需要将props指定为对象类型,即: {path: '/item/:id', component: itemCom, props: {name: '测试商品1', price: 20}}
,同时也需要在路由组件声明中添加props: ['id', 'name', 'price']
。在这里共有两种类型阐参数,一个:id
表示的动态路径传递参数,另一个是name price
表示通过props属性传递的参数。对应id只能通过{{$route.params.id}}
方式获取
5-3. props属性值为函数类型
代码实例
<div id="app">
<router-link to="/item/1">商品1</router-link>
<router-link to="/item/2">商品2</router-link>
<router-link to="/item/3">商品3</router-link>
<router-view></router-view>
</div>
<script>
const itemCom = {
props: ['id', 'name', 'price'],
template: `
<div>
<h3>商品详情</h3>
商品ID:{{id}}--商品名称:{{name}}--商品价格:{{price}}
</div>
`
}
const router = new VueRouter({
routes: [
{path: '/item/:id', component: itemCom, props: route => ({id: route.params.id, name:'测试商品', price: 30})}
]
});
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
为了实现在路由组件中获取参数形式的一致,我们使用props属性的函数类型,通过在路由规则中配置props: route => ({id: route.params.id, name:'测试商品', price: 30})}
,就可以在路由组件中以{{id}}
、{{name}}
、{{price}}
一致的形式获取到可变路径参数和路由规则配置参数。
6. Vue-Router命名路由
路由规则的定义配置中提供了name
属性,用来给路由规则命名
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
<div id="app">
<router-link :to='{name: "item", params:{id: 1, name: "商品1", price: 30}}'>商品1</router-link>
<router-link :to='{name: "item", params:{id: 2, name: "商品2", price: 40}}'>商品2</router-link>
<router-link :to='{name: "item", params:{id: 3, name: "商品3", price: 10}}'>商品3</router-link>
<router-view></router-view>
</div>
<script>
const itemCom = {
props: ['id', 'name', 'price'],
template: `
<div>
<h3> {{name}} </h3>
<hr>
商品ID: {{id}} -- 商品名称: {{name}} -- 商品价格: {{price}}
</div>
`
}
const router = new VueRouter({
routes: [
{path: '/item/:id', name: 'item', component: itemCom, props: true}
]
})
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
- 定义路由规则时可以通过
name
属性来给路由规则命名:{path: '/item/:id', name: 'item', component: itemCom, props: true}
。在<router-link>
标签中做如下配置<router-link :to='{name: "item", params:{id: 2, name: "商品2", price: 40}}'>商品2</router-link>
,name
属性值要和路由规则的name
属性值保持一致。 - 在
<router-link>
的to
属性中我们还可以通过params
配置项传递参数。要实现该参数的传递需要在路由规则定义中添加props: true
,同时to
属性还需要由v-bind:(简写 :)
绑定,这样才能在路由组件中获取到传递的参数。
7. Vue-Router编程式导航和声明式导航
- 声明式导航
通过 <router-link>
来定义连接信息,实现页面跳转的,导航方式
- 编程式导航
通过Vue提供的API,实现页面跳转的导航方式
Vue提供了 this.$router.push(url)
和 this.$router.go(n)
可以实现页面的跳转。
7-1. 编程式导航示例
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
<div id="app">
<router-link v-bind:to="{name: 'user', params: {id: 1, name: '用户1', age: 16}}">用户1</router-link>
<router-link :to="{name: 'user', params: {id: 2, name: '用户2', age: 25}}">用户2</router-link>
<router-link :to="{name: 'user', params: {id: 3, name: '用户3', age: 24}}">用户3</router-link>
<router-link :to="{name: 'reg'}">用户注册</router-link>
<router-view></router-view>
</div>
<script>
const userCom = {
props: ['id', 'name', 'age'],
template: `<div>
<h1> {{name}} </h1>
用户ID:{{id}} -- 用户名:{{name}} -- 用户年龄:{{age}}
<hr/>
<button @click="userRegister">User Register</button>
</div>`,
methods: {
userRegister() {
this.$router.push("/register");
}
}
}
const registerCom = {
template: `
<div>
<h1>User Register</h1>
<button @click="back">后退</button>
</div>
`,
methods: {
back() {
console.log("aaaa");
this.$router.go(-1);
}
}
}
const router = new VueRouter({
routes: [
{path: '/user/:id', name: 'user', component: userCom, props: true},
{path: '/register', name: 'reg', component: registerCom}
]
})
var vm=new Vue({
el:'#app',
data:{},
methods:{},
router
});
</script>
this.$router.push()
方法的参数一个要跳转到的页面的URL,this.$router.go(n)
,n为整数,n为负数表示回退到n步;n为整数表示前进n步。this.$router.go(1)
等同于 history.forward()
,this.$router.go(-1)
等同于history.back()
7-2. 编程式导航参数传递
this.$router.push()
参数类型:
- 字符串
this.$router.push("/register");
- 对象类型
this.$router.push({path: "/register");
- 命名路由
this.$router.push({name: 'reg', params: {name: 'Jack'}})
- 指定查询参数
this.$router.push({path: 'search', query: {name: 'Jack'}})
该配置会被VUe翻译为/search?name=Jack
**说明
如果提供了 path,params 会被忽略,router.push({ path: '/user', params: { userId }}) // -> /user
,上述配置不会把userId参数及参数值传递到目标页面。但是仅限于params
配置项,query
配置项指定的参数可以传递
**
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。