1

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来获取不同的内容。

目录结构

clipboard.png

配置路由 在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中所加载的组件会被渲染到<router-view></router-view>容器中

  <div id="app">
    <img src="./assets/logo.png">
    <router-view></router-view>
  </div>

在a.vue组件中,可以通过$route.params来获得路由参数,返回的是一个对象,无论中间是否有固定的参数,只返回路径中用:来定义的动态参数。

注意:此时用的是$route

clipboard.png

<template>
  <div>这是a视图{{$route.params.nameId}}</div>
</template>

嵌套路由

嵌套路由,顾名思义就是大组件中嵌套小组件。在路径上/parent/brother和/parent/sister前面都是加载到/parent是相同的。最好理解的就是导航栏的跳转。

目录结构

clipboard.png

配置路由 在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
另外要在父组件中加入<router-view>

clipboard.png

clipboard.png

编程式路由

顾名思义,就是通过JS来控制路由的跳转。

相关函数
$router.push(“name”);
$router.push({path:”name”});
$router.push({path:”name”?a=123}); //传参
$router.push({path:”name”,query:{a=123}});
$router.go();
参数查询:$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不会对路径进行字符串拼接

clipboard.png

clipboard.png

注意看两张图的URL

pash方法中也可以传入一个对象

  methods: {
    clickBtn () {
      this.$router.push({path: '/hello/a', query: { id: '123' }})
    }
  }

clipboard.png

clipboard.png

在子组件中我们用 $route.query.[参数名] 来获取参数
在a.vue子组件中,代码如下

<template>
 <div>
   <div>这是子组件</div>
   <div>获得的参数id:{{$route.query.id}}</div>
 </div>
</template>

clipboard.png
..]

值得注意的是,与动态路由用$route.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>

clipboard.png

clipboard.png

命名视图

当一个父视图中要同时放下两个子视图的时候,就可以用多个name不同的<router-view>来存放不同的视图。

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表示当父组件中的<router-view>没有命名时,默认存放的组件。
组件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>下只能有一个元素。一般结构是

<template>
  <div id="app">
  </div>
</template>

图片描述


老虎不长牙
128 声望6 粉丝