zoukankan      html  css  js  c++  java
  • 5.0 路由组件的使用

    一、概述

    路由器:路由器管理路由;

    路由:路由是一种映射关系,一个key对应一个value,key是path,对于后台路由,

          value是处理请求的回调函数,对于前台路由value是组件。

    一般的组件映射成标签,路由组件映射成路由。 

    说明:
    1) 官方提供的用来实现 SPA(单个页面) 的 vue 插件
    2) github: https://github.com/vuejs/vue-router
    3) 中文文档: http://router.vuejs.org/zh-cn/
    4) 下载: npm install vue-router --save

    vue-router的理解和使用:

    router-view/router-link/keep-alive

    $router: 路由器对象,包含一些操作路由的功能函数,来实现编程式导航(跳转路由);

    $route: 当前路由对象,一些当前路由信息数据的容器,path/meta/query/params   

    1. 路由的使用

    (1) VueRouter(): 用于创建路由器的构建函数
      new VueRouter({  // 创建路由器实例
        // 多个配置项(配置对象)
      })


    (2)路由配置
      routes: [
        { // 一般路由
          path: '/about',  
          component: About
        },
        { // 自动跳转路由
          path: '/',
          redirect: '/about'
        }
      ]


    (3)注册路由器
      import router from './router'
      new Vue({
        router
      })


    (4)使用路由组件标签
       <router-link>: 用来生成路由链接(当点击路由连接的时候需要在界面上显示当前路由组件)
       eg: <router-link to="/home">Go to home</router-link>

          <router-link to="/about">Go to about</router-link>


       <router-view>: 用来显示当前路由组件界面
       eg: <div> 

          <router-view></router-view>  //表示如果点击了路由链接(/about),则该路由链接的界面显示在这里,即显示在这个div里面.

        </div>

    2. 缓存路由组件对象

    正常情况下,一个路由组件被切换的时候,这个路由组件就会死亡,在切换回来时,又重先创建。

    路由组件的缓存就是,在切换的时候将路由组件进行缓存,不要让它死亡。实现:

    <keep-alive>
      <router-view></router-view>   // 缓存路由组件对象,只是平时我们会说缓存路由组件  (这里为保持About和Home活着)
    </keep-alive>

    现象:在如下图About组件的输入框输入abc后,切换到Home组件,然后在切回About组件,此时输入框还显示abc。

    3. 向路由组件传递参数

    方式一:  路由路径携带参数(param/query)

    这里的参数有两种类型,param参数和query参数(这两种参数的传递等效),以下实例为param参数的传递,如果要使用query参数类型

    传递参数,则不需要写下面的:id占位符,<router-link>路由链接中,路径的拼接方式和以前一样如: xxxx?id=1
    1) 配置路由
    children: [
      {
        path: 'mdetail/:id',  //占位符
        component: MessageDetail
      }
    ]
    2) 路由路径
      <router-link :to="'/home/message/mdetail/'+m.id">{{m.title}}</router-link>
    3) 路由组件中读取请求参数
      this.$route.params.id

    方式二:<router-view>属性携带数据

    <router-view :msg="msg"></router-view>

    以下实例中App.vue通过msg属性将数据传递至About组件中。

    4. 编程式路由导航

    相关 API
    1) this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)
    2) this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)
    3) this.$router.back(): 请求(返回)上一个记录路由
    4) this.$router.go(-1): 请求(返回)上一个记录路由
    5) this.$router.go(1): 请求下一个记录路由

    二、使用(基本路由/嵌套路由)

    先下载vue-router包:npm install vue-router --save

    非路由组件一般放在components文件夹下,路由组件一般放在views|pages文件夹下; 

    1. 路由的使用步骤:

    步骤一: 定义路由组件

    index.html:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1.0">
      <link rel="stylesheet" href="/static/css/bootstrap.css">
      <title>vue_demo</title>
    
      <style> /*设置选择路由时的样式,!important表示 提高指定样式规则的应用优先权*/
        .router-link-active {
          color: red !important;
        }
      </style>
    </head>
    <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    </body>
    </html>
    View Code

    App.vue:

    <template>
      <div>
        <div class="row">
          <div class="col-xs-offset-2 col-xs-8">
            <div class="page-header"><h2>Router Test</h2></div>
          </div>
        </div>
    
        <div class="row">
          <!--左边部分-->
          <div class="col-xs-2 col-xs-offset-2">
            <div class="list-group">
              <!--5.使用路由标签-->
              <!-- 生成路由链接 -->
              <router-link to="/about" class="list-group-item">About</router-link>
              <router-link to="/home" class="list-group-item">Home</router-link>
            </div>
          </div>
    
          <!--右边部分-->
          <div class="col-xs-6">
            <div class="panel">
              <div class="panel-body">
                <!-- 显示当前组件 -->
                <keep-alive>
                  <!--传递一个属性,值为abc,如果写成:msg="abc", 则abc为变量-->
                  <router-view msg="abc"></router-view>
                </keep-alive>
              </div>
            </div>
          </div>
    
        </div>
      </div>
    </template>
    
    <!--根组件-->
    <script>
      export default {}
    </script>
    
    <style>
    
    </style>
    View Code

     About.vue/Home.vue:用户演示基本路由

    <template>
      <div>
        <h2>About</h2>
        <p>{{msg}}</p>
        <input type="text">
      </div>
    </template>
    
    <!--About组件-->
    <script>
      export default {
        // 接收一个属性,这个属性是由App组件路由传递过来的
        props: {
          msg: String
        }
      }
    </script>
    
    <style>
    
    </style>
    View Code
    <template>
      <div>
        <h2>Home</h2>
        <div>
          <ul class="nav nav-tabs">
            <!--使用路由:路由链接-->
            <li><router-link to="/home/news">News</router-link></li>
            <li><router-link to="/home/message">Message</router-link></li>
          </ul>
    
          <!--使用路由:当前路由-->
          <router-view></router-view>
        </div>
      </div>
    </template>
    
    <!--Home组件-->
    <script>
      export default {}
    </script>
    
    <style>
    
    </style>
    View Code

    News.vue/Message.vue:Home下的子路由,用户演示嵌套路由

    <template>
      <ul>
        <li v-for="(news, index) in newsArr" :key="index">{{news}}</li>
      </ul>
    </template>
    
    <script>
      export default {
        data () {
          return {
            newsArr: ['News001', 'News002', 'News003']
          }
        }
      }
    </script>
    
    <style>
    
    </style>
    View Code
    <template>
      <!--根标签div:只能有一个-->
      <div>
        <ul>
          <!-- :key一般写index,如果这个对象里面有标识属性,则最好写标识属性-->
          <li v-for="m in messages" :key="m.id">
            <!--要拼接字符串得是js语法,不能是html的语法,所以,这里是:to="" , 如果用es5的语法则为 :to="''", 如果用es6的语法则为:to="``"-->
            <router-link :to="`/home/message/detail/${m.id}`">{{m.title}}</router-link>
            <button @click="pushShow(m.id)">push查看</button>
            <button @click="replaceShow(m.id)">replace查看</button>
          </li>
        </ul>
        <button @click="$router.back()">回退</button>
        <hr>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
      export default {
        data () {
          return {
            messages: [
              /* {id: 1, title: 'Message001'},
               {id: 3, title: 'Message003'},
               {id: 5, title: 'Message005'}*/
            ]
          }
        },
    
        mounted () { // 用于异步操作
          // 模拟ajax请求从后台获取数据,注意:回调函数要用箭头函数
          setTimeout(() => {
            const messages = [
              {id: 1, title: 'Message001'},
              {id: 3, title: 'Message003'},
              {id: 5, title: 'Message005'}
            ]
            this.messages = messages
          }, 1000)
        },
    
        methods: {
          pushShow (id) {
            this.$router.push(`/home/message/detail/${id}`)
          },
    
          replaceShow (id) {
            this.$router.replace(`/home/message/detail/${id}`)
          }
        }
      }
    </script>
    
    <style>
    
    </style>
    View Code

    MessageDetail.vue: Message下的子路由

    <template>
      <ul>
        <!--$route表示当前路由-->
        <li>id: {{$route.params.id}}</li>
        <li>title: {{detail.title}}</li>
        <li>content: {{detail.content}}</li>
      </ul>
    </template>
    
    <script>
      /*这里面就没有做异步了,真实的情况应该是详情页面根据传递过来的id去后台查询*/
      const messageDetails = [
        {id: 1, title: 'Message001', content: 'message content00111....'},
        {id: 3, title: 'Message003', content: 'message content00222....'},
        {id: 5, title: 'Message005', content: 'message content00333....'}
      ]
      export default {
        data() {
          return {
            detail: {}  // 里面的属性不用列举
          }
        },
        mounted () {// 改变当前路由组件参数数据时, 不会重新创建组件对象, mounted不会重新执行,所以这里需要用watch去监视
          // 模拟异步到后台查询数据
          setTimeout(() => {
            const id = this.$route.params.id // 这是传递过来的id,有可能传递过来后就变成文本了,乘以1后就变成数字了
            this.detail = messageDetails.find(detail => detail.id===id*1)
          }, 1000)
        },
    
        watch: {
          // 方法一
          // $route: function () { // 改变当前路由组件参数数据时自动调用(组件对象有$route这个属性)
          //   console.log('$route()')
          //   const id = this.$route.params.id
          //   this.detail = messageDetails.find(detail => detail.id===id*1)
          // }
          $route: function (value) { // 方式二
            console.log(value);
            const id = value.params.id
            console.log(id);
            this.detail = messageDetails.find(detail => detail.id===id*1)
          }
        }
      }
    </script>
    
    <style>
    
    </style>
    View Code

    步骤二:注册路由组件(将路由组件映射成路由)

    router/ index.js:

    /*
    路由器对象模块
     */
    import Vue from 'vue' //引入vue
    import VueRouter from 'vue-router' //1. 引入vue的路由器组件
    
    import About from '../pages/About.vue' //引入路由组件
    import Home from '../pages/Home.vue'
    import News from '../pages/News.vue'
    import Message from '../pages/Message.vue'
    import MessageDetail from '../pages/MessageDetail.vue'
    
    Vue.use(VueRouter) // 2.声明使用vue-router插件
    
    // 3.对外暴露路由器对象(这里为默认暴露,默认暴露,引入时可以使用任何名字)
    export default new VueRouter({
      routes: [   // 注册应用中所有的路由
        {
          path: '/about',
          component: About
        },
        {
          path: '/home',
          component: Home,
          children: [  // 配置子路由组件
            {
              path: '/home/news', // path最左侧的/永远代表根路由
              component: News
            },
            {
              path: 'message', // 这是简化写法
              component: Message,
              children: [
                {
                  path: 'detail/:id',  // :id表示占位符
                  component: MessageDetail
                }
              ]
            },
            {
              path: '', // 设置子路由的默认显示,代表当前,这里为/home,因为这是/home下的自路由
              redirect: '/home/news'
            }
          ]
        },
        {
          path: '/',  // 设置默认请求about,即当请求根路径的时候
          redirect: '/about' // 重定向请求/about
        }
      ]
    })

    main.js:注册路由器

    /*
    入口JS
     */
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router' //引入路由器(因为是index.js,所以这里直接写到./router就可以了)
    
    
    new Vue({//配置对象的属性名都是一些确定的属性名,不能随便修改
      el: '#app',
      components: {App}, // 映射组件标签
      template: '<App/>', // 指定需要渲染到页面的模板
      router  // 4.注册路由器  等价于 router: router
    })
    View Code

    步骤三:使用路由(标签)

    关于路由的使用主要是使用路由标签-路由链接 <router-link> 、当前路由<router-view>,在以上实例中主要存在App.vue、

    News.vue、Messages中。

    效果图:

    |

            图1                           图2

  • 相关阅读:
    洛谷P1023 税收与补贴问题
    洛谷P2680 运输计划
    2014-11-3 NOIP模拟赛3
    一行Python代码就可以玩一些童年小游戏
    NuGet(微软.NET开发平台的软件包管理工具)在VisualStudio中的安装的使用
    Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象
    Electron中打开和关闭子窗口以及子窗口向父窗口传值
    Electron中实现通过webview实现内嵌网页并嵌入css样式和js脚本等
    Electron中实现拖拽文件进div中通过File对象获取文件的路径和内容
    Electron中通过process进程对象的api获取CPU、系统位数、环境变量等相关信息
  • 原文地址:https://www.cnblogs.com/shiyun32/p/10909141.html
Copyright © 2011-2022 走看看