乐趣区

20190613Vue-Router-基础一

什么是 Vue Router?

Vue Router 是 Vue.js 的官方路由管理器,可以控制 Vue 单页应用的路由。

如何快速上手?

vue-cli 脚手架自带 Vue-Router 依赖

新版的 vue-cli 脚手架中,默认 default 模式没有 router 依赖,请选择 Manually select features 后添加 Router 依赖后,选择 History 模式。

vue-cli 官网

在 HTML 进行路由设置

<el-dropdown-menu slot="dropdown">
    <router-link to="/profile/index">
    <el-dropdown-item> 新建分类 </el-dropdown-item>
    </router-link>
</el-dropdown-menu>

我们可以利用 <router-link to="path"> 标签来控制单页应用的跳转路径

使用单文件组件内进行路由设置

<el-dropdown-menu slot="dropdown">
    <el-menu-item @click="onCreate"> 新建分类 </el-menu-item>
</el-dropdown-menu>

export default {
  methods: {onCreate() {
      this.$router.push({path: '/categories/create'})
    }
  }
}

我可以使用 this.$router 方法进行操作路由

执行了 push 或 <router-link> 跳转操作还远远不够,我们还在 router.js 上进行路由(目录)添加你需要对应标准的地址以及地址包含 component 组件,不然编译器不知道你要跳转的实质内容是什么~

router.js 配置

// 按需加载你需要的依赖

import Vue from 'vue'
import Router from 'vue-router'
import Main from './views/main.vue'
import CategoryEdit from './components/categoryEdit.vue'

Vue.use(Router)

export default new Router({
  mode: 'history',   // history 模式
  base: process.env.BASE_URL, // 环境内部基础地址
  routes: [
    {
      path: '/', // 当地址在根目录的时候,跳转到 Main 的组件,这就是首页
      name: 'main',
      component: Main,
      children: [
        {
          path: '/categories/create',// 它是 Main 的子路由,默认在首页 调用 CategoryEdit 组件
          name: 'categoryCreate',
          component: CategoryEdit
        },
        {
          path: '/categories/create', // 它是 Main 的子路由,当地址转到 /categories/create 上,则调用 CategoryEdit 组件
          name: 'categoryCreate',
          component: CategoryEdit
        }
      ]
    }
  ]
})

嵌套路由

刚刚在上面我们提高了「子路由」,然后我们开始了解下嵌套路由

/user/foo/profile                     /user/foo/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

这是官网的栗子,我们看来下更直观。

我们要做的是改变这个网页的子路由内容组件人,让我们看下代码吧~

<el-container style="height: 500px; border: 1px solid #eee">
    <el-aside width="200px"
              style="background-color: rgb(238, 241, 246)">
      <el-menu router
               :default-openeds="['1','3']">
        <el-submenu index="1">
          <template slot="title"> 分类 </template>
          <el-menu-item-group>
            <el-menu-item @click="onCreate"> 新建分类 </el-menu-item>
            <el-menu-item> 分类列表 </el-menu-item>
          </el-menu-item-group>
        </el-submenu>
      </el-menu>
    </el-aside>
    <el-container>
      <el-header style="text-align: right; font-size: 12px">
      </el-header>
      <el-main>
        <!-- 这里是我们需要的子路由标签 -->
        <router-view>
        </router-view>
      </el-main>
    </el-container>
</el-container>

export default {
  methods: {onCreate() {
      this.$router.push({path: '/categories/create'})
    }
  }
}

当我们在进行执行 $this.router.push 或者 <router-link> 跳转的时候,
我们可以看到,push 的路径是「/categories/create」,回到 router.js 代码上, 我们可以看到,/categories/create是在 / 根目录下的 children 里面,这就说明它是根目录的子路由,子路由在子路由标签 <router-view> 上进行渲染。

我们还可以利用 <router-view> 的 name 属性进行跳转制定的子路由容器

如图上,父容器 HTML 中有 3 个 route 视图:
  • header
  • side
  • content

我们需要这三个都是动态的,都是需要根据需求加载不同的内容。

<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>

那么这个时候,我们需要在 router.js 中,加载配置三个组件

components 为复数。

import Header from './components/header.vue'
import Side from './components/side.vue'
import Content from './components/content.vue'
import CategoryEdit from './components/categoryEdit.vue'
import CategoryList from './components/categoryList.vue'

 routes: [
    {
      path: '/',
      name: 'main',
      components: {
        efault: Header,
        a: Side,
        b: Content
      },
      children: [
        {
          path: '/categories/create/:userid',
          name: 'categoryCreate',
          component: CategoryEdit
        },
        {
          path: '/',
          name: 'categoryList',
          component: CategoryList
        }
      ]
    }
  ]

动态路由分配(如何给函数添加参数以及如何保证跳转的唯一性)

在绝大分部情况下,我们需要利用同一个组件加载不同的数据内容(比如详情、用户表信息等等),那我们怎么保证跳转的唯一性呢?

这时候,我们需要利用路由命名方法

1.router.js 配置对应路径以及名字

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'main',
      component: Main,
      children: [
        {
          path: '/categories/create/:userid', // 这是 userid 就是参数名
          name: 'categoryCreate',
          component: CategoryEdit
        },
        {
          path: '/',
          name: 'categoryList',
          component: CategoryList
        }
      ]
    }
  ]
})

2. 路由容器,执行跳转操作

  onCreate() {
      this.$router.push({
        name: 'categoryCreate',
        params: {userid: 123}
      })
    }

3. 点击跳转,则地址变成

http://localhost:8080/categories/create/123

4. 在子路由容器中获取到参数名字和内容

mounted() {
    // 注意是 this.$route,是路由对象
    console.log('你获取的参数是:' + this.$route.params); 
},

打印出来的数据

{userid: "123"}

关于命名路由,还有其他的写法

// HTML 上
<router-link :to="{name:'categoryCreate', params: { userId: 123}}">User</router-link>

// .vue 组件的其他写法
const userId = '123'

router.push({name: 'user', params: { userId}}) // -> /user/123
router.push({path: `/user/${userId}` }) // -> /user/123

// 这里的 params 不生效,必须使用上面的写法
router.push({path: '/user', params: { userId}}) // -> /user

GET 请求 - 路由组件传参数

这个和一般的 url 上拼接参数,获取一样,只不过 router 提供一个设置和获取方法。

http://localhost:8080/categories/create/123?dataval=admin

传递参数

    this.$router.push({
        name: 'categoryCreate?ad=11',
        params: {userid: 123},
        query: {dataval: 'admin'}
      })

不需要在 router.js 中进行配置

获取参数

let val = this.$route.query.dataval; // admin

其他的写法

<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{path:'register', query: { plan:'private'}}">Register</router-link>

<!-- 拼到 path 中 -->
this.$router.push({path: `/categories/create/${userid}?admin=tre`});
退出移动版