zoukankan      html  css  js  c++  java
  • vue router应用及总结

    编写一个小的demo,对router基础的应用学习和理解。
    效果图示:
    在这里插入图片描述
    说明: 点击About在右边显示相关信息.
    在这里插入图片描述
    说明: 点击Home,在下边显示相关信息,且Home下有两个路由链接,分别对应各自的路由组件.
    在这里插入图片描述
    说明: Message下有三个路由链接,对应的路由组件只有一个,只是根据传入的参数不同显示不同数据。

    项目目录:
    在这里插入图片描述

    代码:

    1.index.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>my-project</title>
        <link rel="stylesheet" href="./static/css/bootstrap.css">
        <style>
          .router-link-active {
            color: red !important;
          }
        </style>
      </head>
      <body>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    
    

    2.index.js(router模块)

    /**
     * 路由器对象模块
     */
    import Vue from 'vue';
    import Router from 'vue-router'
    
    import Home from '../views/Home'
    import About from '../views/About'
    import News from '../views/News'
    import Message from '../views/Message'
    import MessageDetail from "../views/MessageDetail";
    
    // 声明使用vue-router插件
    /*
    内部定义并注册了2个组件标签(router-link/router-view),
    给组件对象添加了2个属性:
      1. $router: 路由器
      2. $route: 当前路由
     */
    Vue.use(Router)
    
    export default new Router({
      // 注册应用中所有的路由
      routes: [
        {
          path: '/about',
          name: 'About',
          component: About
        },
        {
          path: '/home',
          name: 'Home',
          component: Home,
          children: [
            {
              path: '/home/news',   // 绝对路径:path左侧的'/'永远代表跟路由
              name: 'News',
              component: News
            },
            {
              path: 'message',  // 相对路径
              name: 'Message',
              component: Message,
              children: [
                {
                  path: 'detail/:id',  // id是变化的, :id 占位符来显示
                  name: 'MessageDetail',
                  component: MessageDetail
                }
              ]
            },
            {
              path: '',
              redirect: 'news'
            }
          ]
        },
        {
          path: '/',
          redirect: '/about'
        }
      ]
    })
    
    

    3.main.js

    /**
     * 入口js
     */
    import Vue from 'vue'
    import App from './App'
    import router2 from './router'
    
    
    new Vue({   // 配置对象的属性名都是一些确定的名称,不能随便修改
      el: '#app',
      components: {App},  // 映射组件标签
      template: '<App/>',   // 指定需要渲染到页面的模板
      router: router2   // 注册路由器
    })
    
    

    4.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">
              <!--生成路由链接:链接与路由配置中path一致-->
              <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>
                  <!-- 显示当前组件,并向路由组件传递数据(属性携带数据),与props用法类似 -->
                  <router-view msg="abc"></router-view>
                </keep-alive>
    
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>
    
    <script>
      export default {
        name: 'App',
    
      }
    </script>
    
    <style>
    
    </style>
    
    

    5.About.vue

    <template>
      <div>
        <h2>About</h2>
        <input type="text" />
        <h4>{{msg}}</h4>
      </div>
    </template>
    
    <script>
      export default {
        name: "About",
        props: {  // 声明接受数据
          msg: String
        }
      }
    </script>
    
    <style scoped>
    
    </style>
    
    

    6.Home.vue

    <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="message">Message</router-link></li>
          </ul>
          <!-- 根据路由链接显示路由组件 -->
          <router-view></router-view>
        </div>
      </div>
    </template>
    
    <script>
        export default {
            name: "Header"
        }
    </script>
    
    <style scoped>
    
    </style>
    
    

    7.News.vue

    <template>
      <div>
        <ul>
          <li v-for="(news, index) in newsArr" :key="index">{{news}}</li>
        </ul>
      </div>
    </template>
    
    <script>
      export default {
        name: "News",
        data () {
          return {
            newsArr: ['news01','news02','news03','news04']
          }
        }
      }
    </script>
    
    <style scoped>
    
    </style>
    
    

    8.Message.vue

    <template>
    	<!-- 一个组件只能有一个根标签 -->
      <div>
        <ul>
          <li v-for="message in messages" :key="message.id">
          <!-- 这里to绑定表达式,链接是动态的;不能用相对路径,不然连续点链接时会出错 -->
            <router-link :to="`/home/message/detail/${message.id}`">{{message.title}}</router-link>
            <button @click="pushShow(message.id)">push查看</button>
            <button @click="replaceShow(message.id)">replace查看</button>
          </li>
        </ul>
        <hr>
        <button @click="$router.back()">回退</button>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
      export default {
        name: "Message",
        data() {
          return {
            messages: []
          }
        },
        mounted() {
          // 模拟ajax异步从后台请求数据
          setTimeout(() => {
            const messages = [
              {
                id: 1,
                title: 'message01'
              },
              {
                id: 2,
                title: 'message02'
              },
              {
                id: 3,
                title: 'message03'
              },
            ]
            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 scoped>
    
    </style>
    
    

    9.MessageDetail.vue

    <template>
      <div>
        <ul>
          <li>id: {{$route.params.id}}</li>
          <li>title: {{detail.title}}</li>
          <li>content: {{detail.content}}</li>
        </ul>
      </div>
    </template>
    
    <script>
    
      export default {
        name: "MessageDetail",
        data() {
          return {
            detail: {},
          }
        },
        mounted() {  // 改变当前路由组件参数数据时, 不会重新创建组件对象, mounted不会重新执行
          // setTimeout含义是定时器,到达一定的时间触发一次,在代码的执行时间上加1s
          // 但是setInterval含义是计时器,到达一定时间触发一次,并且会持续触发
          setTimeout(() => {
            const messageDetails = [
              {
                id: 1,
                title: 'message01',
                content: 'message01 content...'
              },
              {
                id: 2,
                title: 'message02',
                content: 'message02 content...'
              },
              {
                id: 3,
                title: 'message03',
                content: 'message03 content...'
              },
            ]
    
            this.messageDetails = messageDetails    //初始化数据,声明全局messageDetails
            const id = this.$route.params.id * 1  // id有可能为文本,故乘以1
            this.detail = messageDetails.find(detail => detail.id === id)
          }, 1000)
    
        },
    
        watch: {
          $route: function(value) {   // 改变当前路由组件参数数据时自动调用
            const id = value.params.id * 1
            this.detail = this.messageDetails.find(detail => detail.id === id)
          }
        }
    
      }
    </script>
    
    <style scoped>
    
    </style>
    
    

    总结

    1.路由组件跳转

    路由跳转与页面跳转相似,页面跳转是从一个页面跳到另一个页面,但路由跳转是从一个路由组件跳到另一个路由组件,类似tab页切换和导航栏效果。

    页面跳转方式:

    • a链接 -- html
    • window.location.href -- js

    路由组件跳转方式:

    • router-link -- html,等同于 $router.push, replace默认为false
    • router-link replace -- 当添加replace=true时等同于$router.replace
    • $router.push -- 在 history 栈中添加新记录
    • $router.replace -- 替换掉当前的 history 记录
    • $router.back() -- 回退
      都是在 router-view 标签定义的地方显示url指向的路由组件

    router.push(location)
    这个方法会向 history 栈添加一个新的记录,当用户点击浏览器后退按钮时,则回到之前的 URL。
    router.replace(location)
    这个方法不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录,点击返回按钮也不会回到之前的URL页面.

    2.路由组件跳转时传递数据

    声明式:
    router-link :to="..." path上传递参数
    params: /home/message/detail/${message.id}
    query: '/home/message/detail?id='+message.id

    router-view :abc="data" 属性携带参数
    类似与同props进行组件通信,跳转的下一路由组件需声明接受属性props

    编程式:
    router.push(...)
    该方法的参数可以是一个字符串路径,或者一个描述地址的对象。

    // 字符串
    router.push('/home')	// 添加新记录
    //push方法也可以传replace
    this.$router.push({path: '/home', replace: true})	// 替换当前记录
    
    // 对象
    this.$router.push({path: '/login?url=' + this.$route.path});
    // 带查询参数,变成/backend/order?selected=2
    this.$router.push({path: '/backend/order', query: {selected: "2"}});
    // 命名的路由
    router.push({ name: 'user', params: { userId: 123 }})
    
    

    params与query传参区别

    1. query 传参配置的是path,而params传参配置的是name,在params中配置path无效
    2. query在路由配置不需要设置参数,而params必须设置
    3. query传递的参数会显示在地址栏中
    4. params传参刷新会无效,但是query会保存传递过来的值,刷新不变
    5. 路由配置:
      query: {path: '/home', name: Home, component: Home}
      params: {path: '/home/:site/:bu', name: Home, component: Home}
    6. 获取路由参数
    	created () {
    	let self = this
    	self.getParams()
    	},
    	watch () {
    	'$route': 'getParams'
    	},
    	methods: {
    	  getParams () {
    	  let site = this.$route.query.site
    	  let bu = this.$route.query.bu
    	  // 如果是params 传参,那就是this.$route.params.site
    	  上面就可以获取到传递的参数了
    	 }
    	}
    
    

    说明: 路由传递参数和传统传递参数是一样的,命名路由类似表单提交而查询就是url传递.

    1. 命名路由搭配params,刷新页面参数会丢失
    2. 传递参数搭配query,刷新页面数据不会丢失
    3. 接受参数使用this.$router后面就是搭配路由的名称就能获取到参数的值
    4. $route为当前router跳转对象,携带数据。对象可以获取name、path、query、params等
    5. $router为VueRouter实例,调用相关router方法来进行路由跳转
  • 相关阅读:
    javascript入门经典(第五版)-清华出版社之“经典”错误
    在自学css开始就遇到问题,“链入外部样式表”在多浏览器显示问题
    sublime text3 =个人插件
    不错的文章
    Golang逃逸分析
    sublime常用快捷键
    同步机制之一--Synchronized,以及此机制下的锁的本质和种类
    UVa 10976
    LeetCode:Add Digits
    插入排序
  • 原文地址:https://www.cnblogs.com/itzlg/p/11902101.html
Copyright © 2011-2022 走看看