vue-router安装
方法一: 在vue-cli项目创建时,就会提示是否需要安装vue-router
方法二: 在项目文件夹下使用npm安装
npm install vue-router
方法三:在vue或者html文件中引入vue-router.js
<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>
动态路由
动态路由主要是不同的url加载同个一组件。在项目中经常会碰到不同内容但是相同的渲染结构,那么就可以通过向后台发送动态的url来获取不同的内容。
目录结构
配置路由 在router/index.js中
import Vue from 'vue'
// 引入router
import Router from 'vue-router'
// 加载组件
import a from '../views/a'
// 使用路由
Vue.use(Router)
// 在path中 用:表示参数是动态的
// component 代表加载到相应路由上后所使用的组件
const routes = [
{
path: '/:nameId',
component: a
}
]
// 暴露路由接口
export default new Router({
routes
})
在App.vue中所加载的组件会被渲染到容器中
<div id="app">
<img src="./assets/logo.png">
<router-view></router-view>
</div>
在a.vue组件中,可以通过$route.params来获得路由参数,返回的是一个对象,无论中间是否有固定的参数,只返回路径中用:来定义的动态参数。
注意:此时用的是$route
<template>
<div>这是a视图{{$route.params.nameId}}</div>
</template>
嵌套路由
嵌套路由,顾名思义就是大组件中嵌套小组件。在路径上/parent/brother和/parent/sister前面都是加载到/parent是相同的。最好理解的就是导航栏的跳转。
目录结构
配置路由 在router/index.js中,说明:HelloWorld是a组件与b组件的父组件
import Vue from 'vue'
// 引入router
import Router from 'vue-router'
// 加载子组件
import a from '../views/a'
import HelloWorld from '../components/HelloWorld'
import b from '../views/b'
// 使用路由
Vue.use(Router)
// 在path中 用:表示参数是动态的
const routes = [
{
path: '/hello',
component: HelloWorld,
children: [
{
path: 'a',
component: a
},
{
path: 'b',
component: b
}
]
}
]
// 暴露路由接口
export default new Router({
routes
})
将子组件的配置写在父组件的children中,其中子组件path的配置不可以加上反斜杠,因为反斜杠是绝对路径。会让/hello/a变成/a
另外要在父组件中加入
编程式路由
顾名思义,就是通过JS来控制路由的跳转。
相关函数
router.push(“name”);
r
o
u
t
e
r
.
p
u
s
h
(
“
n
a
m
e
”
)
;
router.push({path:”name”});
router.push(path:”name”?a=123);//传参
r
o
u
t
e
r
.
p
u
s
h
(
p
a
t
h
:
”
n
a
m
e
”
?
a
=
123
)
;
/
/
传
参
router.push({path:”name”,query:{a=123}});
router.go();参数查询:
r
o
u
t
e
r
.
g
o
(
)
;
参
数
查
询
:
route.query.[参数名]
在router/index.vue中进行配置
<template>
<div>
<button @click="clickBtn">点击加载a视图</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods: {
clickBtn () {
// 注意,这里一定要将路径写全,要写绝对路径。
this.$router.push('/hello/a')
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
注意,在push中要将路径写全,push不会对路径进行字符串拼接
注意看两张图的URL
pash方法中也可以传入一个对象
methods: {
clickBtn () {
this.$router.push({path: '/hello/a', query: { id: '123' }})
}
}
在子组件中我们用 $route.query.[参数名] 来获取参数
在a.vue子组件中,代码如下
<template>
<div>
<div>这是子组件</div>
<div>获得的参数id:{{$route.query.id}}</div>
</div>
</template>
值得注意的是,与动态路由router.params获取参数不同,编程式路由是用$route.query来获取
params与query都可以向后台发送请求,将参数传递过去。但是params中传参必需要在路由中进行参数名的配置,但是query就没有这个要求,无论传参多少个都没有问题。但是query会将所有的信息显示在url上,有点像get请求。而query则有点像post请求,在url上面不会显示参数名。params是路由的一部分,必须要有。query是拼接在url后面的参数,没有也没关系。
命名路由
路由的命名其实就是更语义化了。
对路由的配置
import Vue from 'vue'
// 引入router
import Router from 'vue-router'
// 加载子组件
import a from '../views/a'
import HelloWorld from '../components/HelloWorld'
import b from '../views/b'
// 使用路由
Vue.use(Router)
// 在path中 用:表示参数是动态的
const routes = [
{
path: '/hello',
component: HelloWorld,
children: [
{
path: 'a',
name: 'a',
component: a
},
{
path: 'b',
name: 'b',
component: b
}
]
}
]
// 暴露路由接口
export default new Router({
routes
})
注意在命名的时候,如果不是变量要记得带引号,命名是字符串形式。
在父组件中也可以传参给子组件
在父组件HelloWorld.vue中
<template>
<div>
<router-link :to="{ name: 'a', params: { id: 123 }">点击加载a视图</router-link>
<router-view></router-view>
</div>
</template>
千万注意,这里要用 :to或者v-bind:to来代替to,name必需与路由配置中的命名一样。
在子视图a.vue中用params接受参数
<template>
<div>
<div>这是子组件</div>
<div>获得的参数id:{{$route.params.id}}</div>
</div>
</template>
命名视图
当一个父视图中要同时放下两个子视图的时候,就可以用多个name不同的来存放不同的视图。
import Vue from 'vue'
// 引入router
import Router from 'vue-router'
// 加载子组件
import a from '../views/a'
import HelloWorld from '../components/HelloWorld'
import b from '../views/b'
// 使用路由
Vue.use(Router)
// 在path中 用:表示参数是动态的
const routes = [
{
path: '/hello',
components: {
default: HelloWorld,
one: a,
two: b
}
}
]
// 暴露路由接口
export default new Router({
routes
})
特别注意,此时用的是components,而不是component。另外,default表示当父组件中的没有命名时,默认存放的组件。
组件HelloWorld.vue、a.vue、b.vue大致相同
<template>
<div>
<div>这里是hello组件</div>
</div>
</template>
父组件中:
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view></router-view>
<router-view name="one"></router-view>
<router-view name="two"></router-view>
</div>
</template>
每个组件存放的容器名字都要与路由配置中的相一致。
$$ 在编写代码的时候,遇到报错:Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
是说明在下只能有一个元素。一般结构是
<template>
<div id="app">
</div>
</template>