飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

Vue2和Vue3技术整理3 - 高级篇

时间:2022-02-11  作者:xiegongzi  

3、高级篇

前言

  • 基础篇链接:https://域名/xiegongzi/p/域名
  • 组件化开发篇链接:https://域名/xiegongzi/p/域名




3.1、回顾浏览器本地存储

  • 就是localstorage和sessionstorage这两个( 前者浏览器关闭不会清空,后者关闭浏览器会清空 ),二者常用的API都一模一样,二者里面存的数据都是key-value的形式
    • 存数据 setItem( \'key\', \'value\' ) 使用:域名tem( \'key\' , \'value\' )其他的都是差不多的
    • 取数据 getItem( \'key\' ) 注:若key不存在,则:此API返回值是null( 若key是对象字符串 那么用域名e()转成对象 返回值也是null )
    • 删除某一个数据 removeItem()
    • 清空所有 clear()
  • 二者存储的内容大小一般为5M的字符串( 不同浏览器可能会不一样 )




3.3、组件的自定义事件

3.3.1、绑定自定义事件
  • 这里实现方式有两种:一种是用v-on搭配VueComponent.$emit实现【 ps:此种方式有点类似子传父 】;另一种是使用ref属性搭配mounted()来实现【 此种方式:复杂一点,但是更灵活 】
  • 两种实现方式都可以,而二者的区别和computed与watch的区别很像【 ps:第二种方式可以实现异步操作,如:等到ajax发送请求得到数据之后,再进行事件绑定 】,接下来看实例,从而了解更明确点,用如下实例做演示【 ps:不用前面玩的子传父啊,但是:自行可以先回顾一下子传父的传统方式:父给子一个函数,子执行,参数即为父要得到的数据 】

image




3.3.1.1、v-on搭配emit实现

image

image

image

  • v-on是可以简写的啊!!!!



3.3.1.2、ref搭配mounted实现
  • 在前面实现的基础上,子组件代码不变,在父组件中加入如下的代码

image

image

  • mounted()中是可以进行异步操作的啊,所以才可以让这种自定义事件更灵活

  • 另外:既然是事件,那么也可以使用事件修饰符:prevent、stop、once

    • 在v-on中,这三者和以前一样的玩法,都是加在事件名后面即可,如:@域名 = "xxxxx"
    • 在ref中,是用在this.\(域名on.\)on(\'zixieqing\',域名 )中的\(on这里的,once就是使用\)once,替换掉原来的$on



3.3.2、解绑自定义事件
  • 这玩意用的就是VueComponent.$off( [\'要解绑的事件名\'] )这个内置函数来实现解绑的,
    • 当然:数组[ ]中,如果是解绑单个事件,那么[ ]这个括号不要也行;
    • 如果是解绑多个自定义事件,那么使用 , 逗号隔开即可;
    • 另外:$off()不传递参数时,默认是把组件的所有自定义事件都解绑了【 ps:有一个解绑一个 】
    • 自定义事件的核心话:给谁绑定事件,那么事件就在谁身上;给谁解绑自定义事件,那么就去谁身上解绑

image

  • 另外:前面玩Vue生命周期的beforeDestroy时有一个小点只是简单提了一下,生命周期图如下

image

  • 上图中的内容,有最后一点没有验证:

image

说在beforeDestroy中,会销毁子组件和自定义事件

  • 说此时销毁自定义事件

image

image

  • 而所谓的销毁子组件也就好理解了,就是把父组件销毁之后,那么:子组件也活不成了【 ps:要验证的话,可以使用销毁vm,然后看旗下的子组件还能活不?答案肯定是活不成的 】



3.3.3、自定义事件中的两大坑

子组件是如下的样子

  • image


1、在ref属性实现的方式中,关于this的指向问题

  • 第一种就是将回调函数放到父组件的methods中
    • image
    • image
    • 此种方式,会发现this指向的是父组件
  • 第二种:将回调函数直接放到this.\(域名le.\)on( \'event\',xxxx ) ]中的xxxx中
    • image
    • image
    • 这种情况:会发现,this不再是父组件实例对象,而是子组件的实例对象,但是:可以让它变为子组件实例对象【 ps:把回调的普通函数写成兰姆达表达式就可以了 】
      • image
      • image


2、组件使用原生DOM事件的坑【 ps:了解native修饰符,学后端的人看源码的时候,对这个修饰符再熟悉不过了 】

  • image
  • image
  • image
  • image



3.3.4、自定义事件总结
  • 自定义事件是一种组件间通信的方式,适用于:子组件 ——> 父组件通信

  • 使用场景:想让子组件给父组件传递数据时,就在父组件中给子组件绑定自定义事件【 ps:事件回调在父组件methods / 其他地方 中 】,而要解绑自定义事件就找子组件本身

  • 绑定自定义事件:

    • 1、在父组件中:<Person @zixieqing="demo"/><Person v-on:zixieqing="demo"/>

    • 2、在父组件中:

      • <Person ref = "demo"/>
        	.........
        methods: {
        	test(){......}
        }
        	.........
        mounted(){
        	this.$域名.$on(\'eventName\',域名)
        }
        
        
    • 3、若想让自定义事件只能触发一次,可以使用once修饰符【 ps:使用v-on的方式实现的那种 】 或 $once【 ps:使用ref属性实现方式的那种 】

  • 触发自定义事件: this.$emit(\'eventName\',sendData) 【 ps:给谁绑定自定义事件,就找谁去触发 】

  • 解绑自定义事件:this.$off([\'eventName\',.......]) 【 ps:给谁绑定自定义事件,就找谁解绑;另:注意解绑事件是单个、多个、全解的写法 】

  • 组件上也可以绑定元素DOM事件,但是:需要使用native修饰符

  • 注意项:通过this.$域名.$on(\'eventName\',回调)绑定自定义事件时,回调要么配置在父组件的methods中,要么用兰姆达表达式【 ps:或箭头函数 】,否则:this执行会出现问题

3.4、全局事件总线

  • 这玩意儿吧,不算知识点,是开发中使用的技巧而已,里面包含的只是在前面全都玩过了,只是:把知识做了巧妙的应用,把自定义事件变化一下,然后加上Vue中的一个内置关系域名otype._ _proto _ _ === 域名otype从而实现出来的一个开发技巧
  • 此技巧:可以实现任意组件间的通信


3.4.1、疏通全局事件总线逻辑

image

但是:现在把思路换一下来实现它

image



通过上面的分析图了解之后,就可以分析出:单独选取的那个组件需要具有如下的特性:

  • 1、此组件能够被所有的组件看到
  • 2、此组件可以调用\(on()、\)emit()、$off()


1、那么为了实现第一步:能够让所有的组件都看得到可以怎么做?

  • 1)、使用window对象,可以做到( 但是:不推荐用 )
    • image
    • image
    • image
    • 此种方式不推荐用呢,是因为:本来就是框架,谁还去window上放点东西呀,不是找事吗
  • 2、就是利用Vue中的内置关系域名otype._ _proto _ _ === 域名otype,即:公共组件选为Vue实例对象vm,这个诶之关系怎么来的,这里不再说明了,在基础篇VueComponent()中已经说明过了,利用此内置关系就是利用:VueComponent可以获取Vue原型上的属性和方法,同时选取了Vue实例对象之后,\(on()、\)emit()、$off()都可以调用了,这些本来就是Vue的内置函数啊,Vue实例对象还没有这些函数吗



3.4.2、全局事件总线实例
  • 实现方式:vm + beforeCreate()【 ps:初始化嘛,让关系在一开始就建立 】 + mounted() + $on() + $emit() + beforeDestroy()【 ps:做收尾工作,解绑自定义事件 】+ $off()


实例演示:

  • image
    • 注:上图中的\(bus是自己起的名字,但是开发中一般起的都是这个名字,bus公交车嘛,谁的都可以上,而且还可以载很多人,放到组件中就是:谁都可以访问嘛,加了一个\)是因为迎合Vue的设计,内置函数嘛,假装不是程序员自己设计的【 ps:实际上,bus还有总线的意思 】
  • image
  • image
  • image



3.4.3、全局事件总线总结
  • 全局事件总线又名GlobalEventBus

  • 它是一种组件间的通信方式,可以适用于任何组件间通信

  • 全局事件总线的玩法:

    • 1、安装全局事件总线

      •     new Vue({
                .......
                beforeCreate(){
                    域名otype.$bus = this
                },
                ......
            })
        
    • 2、使用事件总线

      • 发送数据:this.$bus.$emit(\'EventName\',sendData)

      • 接收数据:A组件想接收数据,则:在A组件中给$bus绑定自定义事件,把事件的回调放到A组件自身中【 ps:靠回调来得到数据 】

        •     // 使用methods也行;不使用,把回调放到$on()中也可以【 ps:推荐使用methods,因为不必考虑$on()中的this问题 】
              methods: {
                  sendData(){ ...... }
              },
              ........
              mounted(){
                  this.$bus.$on(\'eventName\',receiveData)
              },
              .......
              beforeDestroy(){
                  this.$bus.$off([ \'eventName\' , ..... ])
              }
          



3.5、消息订阅与发布

什么是消息订阅与发布?

  • 这个东西每天都见到,就是:关注,关注了人,那别人发了一个通知 / 文章,自己就可以收到,这就是订阅与发布嘛
  • 这里使用pubsub-js这个库来演示( 使用其他库也行,这些玩意儿的思路都一样,这是第三方库啊,不是vue自己的 ),其中:
    • pub 就是publish,推送、发布的意思
    • sub 就是subscribe 订阅的意思
    • 也就是:一方发布、一方订阅嘛,这个东西玩后端的人再熟悉不过了,Redis中就有消息订阅与发布,而且用的指令都是这两个单词,RabbitMQ也是同样的套路,只是更复杂而已


3.5.1、玩一下pubsub-js

基础代码

  • image
  • image


1、给项目安装pubsub-js库,指令:npm install pubsub-js

  • image


2、消息发布方

  • 2.1、引入pubsub-js库

  • 2.2、使用publish( \'msgName\' , sendData )这个API进行数据发送

    • image


3、消息接收方

  • 3.1、引入pubsub-js库
  • 3.2、使用subscribe( \'msgName\' , callback )这个API利用回调进行数据接收
  • 3.3、关闭订阅
    • image


4、效果如下

  • image



3.5.2、消息订阅与发布总结
  • 它是一种组件间通信的方式,适用于:任意组件间通信

  • 使用步骤:

    • 1、安装pubsub-js 指令:npm install pubsub-js

    • 2、消息接收方、发送方都要引入pubsub 代码;:import pubsub from "pubsub-js"

      • 数据发送方:域名ish(\'msgName\',sendData)

      • 数据接收方:

        • // methods可写可不写【 ps:推荐写,不用考虑this的指向问题,和自定义事件一样的 】
          methods: {
          	demo(){.....}
          }
          ........
          mounted(){
          	// 使用域名ame把每条订阅都绑在组件实例对象vc上,方便取消订阅时获取到这个订阅id
          	域名ame = 域名cribe(\'msgName\', callback)	// 如果不写methods,那么回调就写在这里,注意:使用箭头函数
          }
          .......
          beforeDestroy(){
          	域名bscribe( 域名ame )
          }
          



3.6、插槽

1、基础代码

  • image
  • image
  • image



3.6.1、默认插槽
  • 此种插槽适合只占用一个位置的时候

需求、让食品分类中显示具体的一张食品图片、让电影分类中电视某一部具体的电影,使用默认插槽改造

  • image

  •     <template>
          <div class="container">
            <Category title = "食品">
              <!-- 2、将内容套在组件标签里面从而携带到slot处 
                      此种方式:是vue在解析完App这个组件的模板时,
                                将整个组件中的内容给解析完了,然后放到了Category组件里面使用slot占位处
                                所以:slot所放位置 和 这里面代码解析之后放过去的位置有关
                      另外:由于是先解析完APP组件中的东西之后 再放到 所用组件里面slot处的位置
                            因此:这里可以使用css+js,这样就会让 模板 + 样式解析完了一起放过去
                                  不用css+js就是先把模板解析完了放过去,然后找组件里面定义的css+js
              -->
              <img src="./assets/域名" alt="照片开小差去了">
            </Category>
    
            <Category title = "游戏">
              <ul>
                  <li v-for=" (game,index) in games" :key="index">{{game}}</li>
              </ul>
            </Category>
    
            <Category title = "电影">
              <video controls src="./assets/枕刀歌(7) -  山雨欲来.mp4"></video>
            </Category>
          </div>
        </template>
    
        <script>
        import Category from "./components/域名"
          export default {
            name: \'App\',
            components: {Category},
            data() {
              return {
                foods: [\'紫菜\',\'奥尔良烤翅\',\'各类慕斯\',\'黑森林\',\'布朗尼\',\'提拉米苏\',\'牛排\',\'熟寿司\'],
                games: [\'王者荣耀\',\'和平精英\',\'英雄联盟\',\'文明与征服\',\'拳皇\',\'QQ飞车\',\'魔兽争霸\'],
                filems: [\'无间道\',\'赤道\',\'禁闭岛\',\'唐人街探案1\',\'肖申克的救赎\',\'盗梦空间\',\'无双\']
              }
            },
          }
        </script>
    
        <style>
          .container {
            display: flex;
            justify-content: space-around;
          }
    
          img,video {
            width: 100%;
          }
        </style>
    
    
  • image




3.6.2、具名插槽
  • 指的就是有具体名字的插槽而已,也就比默认插槽多了两步罢了
  • 在使用slot进行占位时就利用name属性起一个名字,然后在传递结构时使用slot="xxx"属性指定把内容插入到哪个插槽就OK了


需求、在电影分类的底部显示"热门"和"悬疑"

  • image
  • image
  • image



3.6.3、作用域插槽
  • 这个玩意儿的玩法和具名插槽差不多,只是多了一点步骤、多了一个要求、以及解决的问题反一下即可


基础代码

  • image
  • image
  • image



需求:多个组件一起使用,数据都是一样的,但是有如下要求:

  • 数据显示时要求不是全都是无序列表,还可以用有序列表、h标签......
  • 要求data数据是在子组件中【 ps:就是Category中 】,而结构需要写在父组件中【 ps:就是App中 】,也就是父组件要拿到子组件中的data
  • 利用前面已经玩过的子父组件通信方式可以做到,但是麻烦。因此:改造代码


开始改造代码:

  • 第一步:提data
    • image
    • 查看效果:
      • image
      • 可能会想:明明可以将data放到父组件中 / 将结构ul放到子组件中,从而实现效果,为什么非要像上面那有折腾,没事找事干?开发中有时别人就不会把数据交给你,他只是给了你一条路,让你能够拿到就行
  • 第二步:使用作用域插槽进行改造
    • image
    • image
    • image
    • image


既然作用域插槽会玩了,那就实现需求吧

  • image
  • image
  • image


另外:父组件接收数据时的scope还有一种写法,就是使用slot-scope

  • image



3.6.4、插槽总结

1、作用:让父组件可以向子组件指定位置插入HTML结构,也是一种组件间通信的方式,适用于:父组件 ===》 子组件

2、分类:默认插槽、具名插槽、作用域插槽

3、使用方式

  • 1)、默认插槽

    •     // 父组件
          <Category>
              <div>
                  HTML结构
              </div>
          </Category>
      
          // 子组件
          <template>
              <div>
                  <!-- 定义插槽 -->
                  <slot>插槽默认内容</slot>
              </div>
          </template>
      
  • 2)、具名插槽

    •     // 父组件
          <template>
              <!-- 指定使用哪个插槽 -->
              <Category slot = "footer">也可以加入另外的HTML结构</Category>
          </template>
      
      
      
          // 子组件
          <template>
              <div>
                  <!-- 定义插槽 并 起个名字-->
                  <slot name = "footer">插槽默认内容</slot>
              </div>
          </template>
      
  • 3)、作用域插槽

    •     // 子组件
          <template>
            <div class="category">
                <h3>{{title}}分类</h3>
                <!-- 作用域插槽
                  1、子组件( 传递数据 ) 
                      提供一个路口,把父组件想要的数据传给它【 ps:有点类似于props的思路,只是反过来了 】
                      :filems中的filems就是提供的路,给父组件传想要的东西【 ps:对象、数据都行 】
                -->
                <slot :filems = "filems">这是默认值</slot>
            </div>
          </template>
      
          <script>
              export default {
                  name: \'Category\',
                  props: [\'title\'],
                  data() { // 数据在子组件自身中
                      return {
                          filems: [\'无间道\',\'赤道\',\'禁闭岛\',\'唐人街探案1\',\'肖申克的救赎\',\'盗梦空间\',\'无双\']
                      }
                  },
              }
          </script>
      
      
          // 父组件
          <template>
            <div class="container">
              <Category title = "电影">
                <!-- 
                  2、父组件( 接收数据 )
                    前面说的 多了一个要求   就是这里"必须用template标签套起来"
                    怎么接收?使用scope="xxxx"属性   xxx就是接收到的数据,这个名字随便取
                        这个名字不用和子组件中用的 :filems 这个filems这个名字保持一致,因:它接收的就是这里面传过来的东西
                        但是:这个数据有点特殊,需要处理一下
                 -->
                 <template scope="receiveData">
                   <!-- {{receiveData}} -->
                   <!-- 拿到了数据,那"页面的结构就可以随插槽的使用者随便玩"了 -->
                   <ul>
                     <li v-for="(filem,index) in 域名ms" :key="index">{{filem}}</li>
                   </ul>
                 </template>
              </Category>
      
              <Category title = "电影">
                <!-- ES6中的"结构赋值"简化一下 -->
                 <template scope="{filems}">
                   <ol>
                     <li v-for="(filem,index) in filems" :key="index">{{filem}}</li>
                   </ol>
                 </template>
              </Category>
      
              <Category title = "电影">
                <!-- ES6中的"结构赋值"简化一下 -->
                 <template scope="{filems}">
                    <h4 v-for="(filem,index) in filems" :key="index">{{filem}}</h4>
                 </template>
              </Category>
      
              <!-- scope还有一种写法 使用slot-scope-->
              <Category title = "电影">
                <!-- ES6中的"结构赋值"简化一下 -->
                 <template slot-scope="{filems}">
                    <h4 v-for="(filem,index) in filems" :key="index">{{filem}}</h4>
                 </template>
              </Category>
            </div>
          </template>
      
          <script>
          import Category from "./components/域名"
            export default {
              name: \'App\',
              components: {Category},
            }
          </script>
      



3.7、Vuex

  • 概念:在Vue实例中集中式状态( 数据,状态和数据是等价的 )管理的一个插件,说得通俗一点就是:数据共享,对多个组件间的同一个数据进行读/写,不就是集中式管理了吗( 对立的观点就是"分布式",学Java的人最熟悉为什么有分布式
  • github地址:https://域名/vuejs/vuex 官网的话,在vue官网的生态中有vuex
  • 什么时候用vuex?
    • 1、多个组件依赖同一状态( 数据 )【 ps:两个帅哥,都想要同一个靓妹 】
    • 2、不同组件的行为 需要 变更同一状态【 ps:洗脚城的两个妹子 都想要把 客户钱包中的money变到自己荷包中 】
    • 3、上面的使用一句话概括:多组件需要分享数据时就使用Vuex



3.7.1、vuex原理
  • 首先这个东西在官网中有,但是:不全

image

  • 所以:把官网的原图改一下
    • image
    • 上述内容只是对原理图有一个大概认识而已,接下来会通过代码逐步演示就懂了



3.7.2、搭建Vuex环境

1、在项目中安装vuex 指令:npm install vuex



2、编写store

  • image


3、让store在任意组件中都可以拿到

  • image
  • image
  • 这样store就自然出现在其他组件身上了【 ps:利用了vc和vm的内置关系 ,验证自行验证,在其他组件中输出this就可以看到了】



vuex环境搭建小结

  • 1、创建文件src/store/域名

    •     // 引入vuex
          import vuex from "vuex"
      
          // 使用vuex —— 需要vue 所以引入vue
          import Vue from "vue"
          域名(vuex)
      
      
          // 创建store中的三个东西actions、mutations、state
          const actions = {}
      
          const mutations = {}
      
          const state = {}
      
          // 创建store ———— 和创建vue差不多的套路
          export default new 域名e({
              // 传入配置项 ———— store是actions,mutations,state三者的管理者,所以配置项就是它们
              actions,    // 完整写法 actions:actions ,是对象嘛,所以可以简写
              mutations,state
          })
      
      
      
  • 2、在域名中配置store

    •     import App from "./域名"
          import Vue from "vue"
      
          // 引入store
          import store from "./store"     
          // 由于起的名字是index,所以只写./store即可,这样默认是找index,没有这个index才报错
      
          const vm = new Vue({
              render: h=>h(App),
              components: {App},
              // 让store能够被任意组件看到 ———— 加入到vm配置项中【 ps:和全局事件总线很像 】
              store,
              template: `<App></App>`,
          }).$mount(\'#app\')
          
      



3.7.3、简单玩一下vuex的流程
  • 对照原理图来看


1、先把要操作的数据 / 共享数据放到state中

  • image
  • image


2、在组件中使用dispatch这个API把key-value传给actions

  • image
  • actions就是第一层处理【 ps:服务员嘛 】
  • image


2、actions接收key-value【 ps:要是有逻辑操作,也放在这里面,ajax也是 】

  • 这里就是调用commit这个API把key-value传给mutation,这个mutation才是真正做事的人【 ps:后厨嘛 】
  • image
  • image


3、mutations接收key-value

  • image
  • image
  • image
  • image


4、查看开发者工具【 ps:简单了解,自行万一下 】

  • 另外:vuejs devtools开发工具版本不一样,则:页面布局也不一样,但是:功能是一样的

  • image

当然:前面说过,直接在组件中调commit这个API从而去和mutations打交道,这种是可以的,适用于:不需要逻辑操作的过程,示例就自行完了

以上便是简单了解vuex,前面的例子看起来没什么用,但是vuex这个东西其实好用得很




3.7.4、认识getters配置项
  • 这玩意儿就和data与computed的关系一样
  • image
  • image
  • image



3.7.5、四个map方法
3.7.5.1、mapState和mapGetters

image



1、改造源代码 —— 使用计算属性实现

  • image
  • image
  • 但是:上面这种是我们自己去编写计算属性,从而做到的,而Vuex中已经提供了一个东西,来帮我们自动生成计算属性中的哪些东西,只需一句代码就搞定


2、使用mapState改造获取state中的数据,从而生成计算属性

  • 1、引入mapState 代码:import {mapState} from "vuex"
  • 2、使用mapState【 ps:对象写法 】
    • image
    • image
  • 3、数组写法【 ps:推荐用的一种 】
    • ...mapState({sum:\'sum\'})这里面的sum:\'sum\'这两个是一样的,那么:一名多用
    • image
    • image



3、使用mapGetters把getters中的东西生成为计算属性

  • 1、引入mapGetters 代码:import {mapState,mapGetters} from "vuex"
  • 2、使用mapGetters【 ps:和mapState一模一样 ,对象写法 】
    • image
    • image
  • 3、数组写法
    • image



3.7.5.2、mapActions 和 mapMutations
  • 会了mapState,那么其他的map方法也会了,差不多的,只是原理是调了不同的API罢了,当然:也会有注意点
  • mapState 和 mapGetters是生成在computed中的,而mapActions和mapMutations是生成在methods中的


1、mapActions —— 调的API就是dispatch

image

  • 使用mapActions改造
    • 1、引入mapActions 代码: import {mapActions} from \'vuex\'
    • 2、使用mapActions【 ps:对象写法 】 —— 准备调入坑中
      • image
      • image
      • 原因:
        • image
        • image
    • 3、数组写法 —— 一样的,函数名和actions中的名字一样【 ps:一名多用 】
      • image
      • image


2、mapMutations —— 这个和mapActions一模一样,只是调用的API是commit

  • image
  • 所以:此种方式不演示了,会了前面的三种中任意一种,也就会了这个



3.7.6、简单玩一下组件共享数据

1、在state中再加一点共享数据

  • image


2、新增Person组件

  • image
  • image
  • image


3、共享数据

  • 在Count组件中获取person,在person中获取Count【 ps:此步不演示,会了前者后者就会了 】

操作如下:

  • image
  • image



3.8、路由器 router

3.8.1、认识路由和路由器
  • 路由:就是一组key-value的映射关系 也就是route
    • key就是网站中的那个路径
    • value 就是function 或 component组件
      • function 是因为后端路由( 后端调用函数 对该路径的请求做响应处理 )
      • component 组件就不用多说了
  • 路由器 router:就是专门用来管理路由的【 ps:理解的话,就参照生活中的那个路由器,它背后有很多插孔,然后可以链接到电视机,那个插孔就是key ,而链接的电视机就是value嘛 】


  • 在vue中,router路由器是一个插件库,所以需要使用npm install vue-router来进行安装,这个东西就是专门用来做单页面网站应用的
  • 所谓的单页面网站应用就是 SPA,即:只在一个页面中进行操作,路径地址发生改变即可,然后就把相应的东西展示到当前页面,不会发生新建标签页打开的情况【 参照美团网址,进行点一下,看看地址、页面更新、是否新建标签页打开、美团就是单页面网站应用 】
    • SPA 整个应用只有一个完整的页面、点击页面中的导航链接不会刷新页面,只会做页面的局部刷新、数据需要通过ajax请求获取



域名、路由器 router

域名.1、认识路由和路由器
  • 路由:就是一组key-value的映射关系 也就是route
    • key就是网站中的那个路径
    • value 就是function 或 component组件
      • function 是因为后端路由( 后端调用函数 对该路径的请求做响应处理 )
      • component 组件就不用多说了
  • 路由器 router:就是专门用来管理路由的【 ps:理解的话,就参照生活中的那个路由器,它背后有很多插孔,然后可以链接到电视机,那个插孔就是key ,而链接的电视机就是value嘛 】


  • 在vue中,router路由器是一个插件库,所以需要使用npm install vue-router来进行安装,这个东西就是专门用来做单页面网站应用的
  • 所谓的单页面网站应用就是 SPA,即:只在一个页面中进行操作,路径地址发生改变即可,然后就把相应的东西展示到当前页面,不会发生新建标签页打开的情况【 参照美团网址,进行点一下,看看地址、页面更新、是否新建标签页打开、美团就是单页面网站应用 】
    • SPA 整个应用只有一个完整的页面、点击页面中的导航链接不会刷新页面,只会做页面的局部刷新、数据需要通过ajax请求获取



域名.2、简单使用路由器

1、准备工作:

  • 1)、引入域名
    • image



2、开始玩路由器 router

  • 1)、给项目安装路由 指令:npm install vue-router

  • 2)、在域名中引入并使用路由器【 ps:路由器是一个插件 】

    • image
  • 3)、编写组件

    • image
  • 4)、配置路由器【 ps:这也叫配置路由规则,就是key-value的形式,在前端中,key是路径,value是组件 】

    • image
  • 5)、把配置的路由规则引入到域名中

    • image
  • 6)、在静态页面中使用路由【 ps:需要记住两个标签 <router-link ..... to = "路径名"></router-link><router-view></router-view> ]

    • <router-link ..... to = "路径名"></router-link> 是指:跳转 其中:路径名 就是 路由规则中配置的 path 参照a标签来理解 本质就是转成了a标签

    • <router-view></router-view> 是指:视图显示 就是告知路由器 路由规则中配置的component应该显示在什么位置,和slot插槽一样,占位

    • image

    • 页面结构源码如下:

      •     <template>
              <div>
                <div class="row">
                  <div class="col-xs-offset-2 col-xs-8">
                    <div class="page-header"> <h2>Vue Router Demo </h2></div>
                  </div>
                </div>
                <div class="row">
                  <div class="col-xs-2 col-xs-offset-2">
                    <div class="list-group">
                      <router-link class="list-group-item" active-class="active" to="./about">About</router-link>
                      <router-link class="list-group-item" active-class="active" to="./home">Home</router-link>
                      <!--对照a标签 <a class="list-group-item active" href="./域名">Home</a> -->
                    </div>
                  </div>
                  <div class="col-xs-6">
                    <div class="paner">
                      <div class="paner-body">
                        <router-view></router-view>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </template>
        
            <script>
              export default {
                name: \'App\',
              }
            </script>
        
        
  • 7)、运行效果如下:

    • image



另外:从此处开始,可以先摸索Element-ui组件库了,这是专门搭配vue来做页面的网站 和 bootstrap一个性质,这个东西后续要用,网址如下:

  • https://域名/#/zh-CN/component/changelog
  • image



vue-router使用小结

  • 1、安装vue-router ,命令:npm install vue-router

  • 2、在域名中 指令:import VueRouter from "vue-router"

  • 3、应用vue-router插件,指令:域名(VueRouter)

  • 4、编写router路由规则

    •     // 引入路由器
          import VueRouter from "vue-router"
          // 引入需要进行跳转页面内容的组件
          import About from "../components/域名"
          import Home from "../components/域名"
      
          // 创建并暴露路由器
          export default new VueRouter({
              routes: [   // 路由器管理的就是很多路由  所以:routes 是一个数组
                  {   // 数组里面每个路由都是一个对象 它有key和value两个配置项【 ps:还有其他的 】
                      path: \'/about\',     // 就是key  也就是路径名,如:域名/about这里的about
                      component: About    // 就是value  也就是组件
                  },{
                      path: \'/home\',
                      component: Home
                  },
              ]
          })
      
      
  • 5、实现切换( active-class 可配置高亮样式 )

    • 	<router-link class="list-group-item" active-class="active" to="./about">About</router-link>
      
      
  • 6、指定展示位置

    • 	<router-view></router-view>
      
      



域名.3、聊聊路由器的一些细节
  • 1、路由组件以后都放到page文件夹下,而一般组件都放到components中
  • 2、路由切换时,“隐藏”了的路由组件,默认是被销毁掉了,需要时再去重新挂载的【 ps:示例自行通过beforeDestroy和mounted进行测试 】
    • image
  • 3、每个组件都有自己的$route属性,里面存储这自己的路由信息
搜你所爱
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。