Vue2零碎笔记_myself

project_vue

Project setup

npm install

Compiles and hot-reloads for development

npm run serve

Compiles and minifies for production

npm run build

Lints and fixes files

npm run lint

Customize configuration

See Configuration Reference.

笔记

一、 关于不同版本的Vue:

  • 1、vue.js和vue.runtime.xxx.js的区别:
    • (1)、vue.js是完整版的Vue 包含:核心功能+模板解析器
    • (2)、vue.runtime.xxx.js 是运行版本地Vue 只包含:核心功能;没有模板解析器
  • 2、因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,
    需要使用render函数接收到createElement函数去指定具体内容

二、修改默认配置

  • 使用vue inspect > output.js 可以查看到Vue手脚架的默认配置

  • 使用Vue.config.js 可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

  • 在vue.config.js中修改:

    • 关闭语法检查:lintOnSave:false

三、ref属性

  1. 被用来给元素或子组件注册引用信息(id的替代者)
  2. 应用在html标签上获取的真实DOM元素,应用在组件标签上是组件实例对象(vc)
  3. 使用方式:
    • 打标识:<h1 ref="xxx"></h1><Person ref="xxx"></Person>
    • 获取:this.$refs.xxx

四、配置项props

功能:让组件接收外部传过来的数据

  1. 传递数据:
    1. <Demo name="xxx"/>
  2. 接收数据:
    1. 只接收:

      props:[‘name’]

    2. 限制类型:

      props:{name:String}

    3. 限制类型、限制必要性、指定默认值:

      props:{name:{type:String,required:true,default:‘xxx’}}

3.备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求要修改,则可以复制props的内容到data中一份,然后修改data中的数据

五、mixin(混入)

  • 功能:可以把多个组件共用的配置提取成一个混入对象
  • 使用方式:
    • 第一步定义混入,例如:

      {data(){…},methods:{…},… }

    • 第二步使用混入,例如:
      1. 全局混入:Vue.mixin(xxx)
      2. 局部混入:mixins:[‘xxx’,‘xxxx’]

六、插件

  • 功能:用于增强Vue

  • 本质:包含install方法的一个对象,install的以一个参数是Vue,以后第二个参数是插件使用者传递的数据。

  • 定义插件:

           对象.install = function (Vue,options){
          
          
           Vue.filter('函数名',function() {
          
          })//添加全局过滤器
           Vue.directives('函数名',function() {
          
          })//添加全局指令
           Vue.mixin('函数名',function() {
          
          })//配置全局混入
           Vue.prototype.$myMethod = function (){
          
          }
           Vue.prototype.$myPrototype = xxxx
          }
    
  • 使用插件:

       先引入:import plugins from "@/plugins";
       再使用:Vue.use(插件名,参数1,参数2,...)
    

七、scoped样式

  • 作用:让样式在局部生效,防止冲突
  • 写法:<style scoped></style>

八、总结案例

  1. 组件化编码流程:
    1. 拆分静态组件:组件按照功能点拆分,命名不要与html元素冲突
    2. 实现动态组件:考虑好数据存放的位置,数据是一个组件在用,还是一些组件在用:
      1. 一个组件在用:放在组件自身即可。
      2. 一些组件在用:放在它们共同的父组件上(动态提升)
    3. 实现交互:从绑定事件开始。
  2. props适用于:
    1. 父组件 ===> 子组件 通信
    2. 子组件 ===> 父组件 通信 (要求父先给子一个函数,子再调用该函数)
  3. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是只读不可修改,否则将违反原则!!!
  4. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这种操作!!

九、webStorage (本地存储/session存储)

  1. 存储内容大小一般支持5MB左右(不同浏览器可能不同)
  2. 浏览器端通过Window.sessionStorage和Window.localStorage属性实现本地存储机制
  3. 相关API:
    1. xxxStroage.setItem(‘key’,‘value’); 该方法接收一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值

    2. xxxStroage.getItem(‘key’); 该方法接收一个键名作为参数,并返回键名所对应的值

    3. xxxStroage.remove(‘key’); 该方法接收一个键名作为参数,并把该键名从存储中删去

    4. xxxStroage.clear() 该方法会清空存储中所有的数据

  4. 备注:
    1. SessionStorage存储的内容会随着浏览器窗口的关闭而消失
    2. LocalStorage存储内容,需要手动清除才会消失
    3. xxxStroage.getItem('key');如果xxx对应的value获取不到,那么返回的值为null
    4. JSON.parse(null)的结果依然是null,读取json格式
    5. JSON.stringify(数据)==>转换成json格式

十、组件自定义事件

  1. 一种组件间通信的方式,使用与:子组件 ===> 父组件
  2. 使用场景: A是父组件,B是子组件,B想给A传递数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)
  3. 绑定自定义事件:
    1. 第一种方式,在父组件中:<Demo @linture="test"/><Demo v-on:linture="test"/>

    2. 第二种方式:在父组件中:

       <Demo ref="demo"/> 
          ..... 
          mounted(){ 
              this.$refs.xxxx.$on('事件名',this.test(一个回调函数,写在父组件的methods中))
          }
      
      
    3. 若想让自定义事件只能触发一次,可 使用once修饰符,或$onec方法

  4. 触发自定义事件:this.$emit('linture',数据)
  5. 解绑自定义事件:this.$off(事件名)
  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符
  7. 注意:通过this.$refs.组件名.$on('event',回调函数)绑定自定义事件时,回调要么配置在methods中,要么使用箭头函数,否则this指向会出问题

十一、全局事件总线(GlobalEventBus)

  1. 一种组件间通信的方式,适用于任意组件间通信

  2. 安装全局事件总线:

    new Vue({ ....  
        beforeCreate(){
        Vue.prototype.$bus = this  //安装全局事件总线,$bus就是当前应用的vm
     })
    
    
  3. 使用事件总线:

    1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件回调留在A组件自身

        methods(){ 
          demo(data){...}
        },
        .....,
        mounted(){
          this.$bus.$on('xxxx',this.demo)
        }
      
      
    2. 提供数据:this.$bus.$emit('自定义事件名',数据)

  4. 最好在beforeDestroy钩子中,是用this. b u s . bus. bus.off(自定义事件名)去解绑当前组件所用到的事件。

十二、消息发布与订阅 (pubsub)

  1. 一种组件间通信的方式,适用于任意组件间通信。
  2. 使用步骤:
    1. 安装pubsub:npm i pubsub-js

    2. 引入:import pubsub from 'pubsub-js'

    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身

           method(){
             demo(消息名,数据){},
                 ...,
             mounted(){
                 this.pbId = pubsub.subscribe(事件名,this.demo)
             }
         } //订阅消息
      
      
      
    4. 地方提供数据:

          pubsub.publish(消息名,数据)
      
    5. 最好在beforeDestroy钩子中,使用pubsub.unsubscribe(pbId)去**取消订阅**

十三、nextTick

  1. 语法:this.$nextTick(回调函数)
  2. 作用:在下一次DOM更新结束后执行其指定的回调。
  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。

十四、Vue 封装的过渡与动画

  1. 作用:在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名

  2. 图示:
    在这里插入图片描述

  3. 写法:

    1. 准备好样式:
      • 元素进入的样式:
        1. v-enter:进入的起点
        2. v-enter-active:进入过程中
        3. v-enter-to:进入的终点
      • 元素离开时的样式:
        1. v-leave:离开的起点
        2. v-leave-active:离开过程中
        3. v-leave-to:离开的终点
    2. 使用<transition>包裹要过渡的元素,并配置name属性:
      <transition name='lin'> 
         <h1 v-show='isShow'>hello</h1> 
      </transition>
      
    3. 备注:若有多个元素需要过渡,则需要使用: <transition-group>,且每个元素都要指定key
    4. 使用 animate 提供是动画样式 用法:参考官方文档

十五、vue脚手架配置代理

  1. 方法一

    在vue.config.js中添加如下配置:
devServer:{
    
    
       proxy:"http://localhost:端口号1"
   } 

说明:

  1. 优点:配置简单,请求资源时直接发给前端(端口号,一般为8080)即可

  2. 缺点:不能配置多个代理,不能灵活的控制请求是否走代理
    3 . 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器(优先匹配前端资源)

  3. 方法二

    编写vue.config.js配置具体代理规则:

     devServer:{
          
          
     proxy:{
          
          
       '/linture':{
          
          
         target:'http://localhost:5000',
         pathRewrite:{
          
          '^/linture':''},
         ws:true, //用于支持webSocket
         changeOrigin:true // 用于控制请求头中的host值
       },
       '/lin':{
          
          
         target:'http://localhost:5001',
         pathRewrite:{
          
          '^/lin':''},
         ws:true, //用于支持webSocket
         changeOrigin:true // 用于控制请求头中的host值
       }
     }
    }
    /*
     changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
     changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
     changeOrigin默认为true
    */
    

说明:

  1. 优点:可以配置多个代理,且可以灵活地控制请求是否走代理
  2. 缺点:配置略微繁琐,请求资源必学加前缀

十六、插槽

  1. 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间的通信方式,适用于 父组件===>子组件
  2. 分类:默认插槽、具名插槽、作用域插槽
  3. 使用方式:
    1. 默认插槽:
        父组件中:
              <子组件名1>
                  <div>html结构</div>
              </子组件名1>
        子组件中:
              <div>
                  <slot>插槽的内容</slot> <!--定义插槽-->
              </div>
      
    2. 具名插槽:
            父组件中:
              <子组件名1>
                  <template slot="插槽名1">
                       <div>html结构</div>
                  </template>
                  <template v-slot:插槽名2>
                       <div>html结构</div>
                  </template>
              </子组件名1>
        子组件中:
              <div>
                  <slot name="插槽名1">插槽的内容</slot> <!--定义插槽-->
                  <slot name="插槽名2">插槽的内容</slot> <!--定义插槽-->
              </div>
      
    3. 作用域插槽:
      1. 理解:—数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据遍历出来的结构由App组件决定)
      2. 具体编码:
          父组件中:
             <子组件名1>
                 <template scope="scopeData">
                       <!--生成的是ul列表-->
                       <ul>
                           <li v-for="g in scopeData.games" :key="g">{
             
             {g}}</li>
                       </ul>
                 </template>
        
                 <template scope="scopeData">
                       <!--生成的是ol列表-->
                       <ol>
                           <li v-for="g in scopeData.games" :key="g">{
             
             {g}}</li>
                       </ol>
                 </template>
                 <template scope="scopeData">
                       <!--生成的是h4列表-->
                       <h4 v-for="g in scopeData.games" :key="g">{
             
             {g}}</h4>
                 </template>
             </子组件名1>
          子组件中:
             <div>
                 <slot :games="games">插槽的内容</slot> <!--定义插槽-->
             </div>
        
        
          <script>
              export default {
                  name: "Category",
                  props:['title'],
                  data(){
                      return{
                          games:['PUBG','csgo','英雄联盟']
                      }
                  }
              }
          </script>
      

十七、Vuex

1.概念

在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。   

2.何时使用?

多个组件需要共享数据时

3.搭建vuex环境

  1. 创建文件:src/store/index.js
        // 该文件用于创建Vuex中最为核心的store
        //引入Vue
        import Vue from "vue";
        Vue.use(Vuex);
        //引入Vuex
        import Vuex from "vuex";
        
        //准备actions 用于响应组件中的动作
        const  actions = {
          
          };
        //准备mutation,用于操作数据(state)
        const mutations = {
          
          };
        //准备state 用于存储数据
        const state = {
          
          };
        
        //创建并暴露store
        export default new Vuex.Store({
          
          
            actions,
            mutations,
            state
        });
    
  2. main.js中创建vm时传入store配置项
       //引入Vue
       import Vue from "vue";
       //引入App
       import App from "@/App";
       
       //引入插件$http
       import vueResource from "vue-resource";
       //引入vuex
       import Vuex from 'vuex'
       //引入store
       import store from '@/store';
       
       //关闭Vue的生产提示
       Vue.config.productionTip = false;
       
       //使用插件
       Vue.use(vueResource)
       Vue.use(Vuex)
       
       const vm = new Vue({
          
          
           el:'.wrap',
           render: h=>h(App),
           store,
           beforeCreate() {
          
          
               Vue.prototype.$bus = this;
           }
       });
    

4.基本使用

  1. 初始化数据、配置actions,mutations,操作文件store/index.js
        // 该文件用于创建Vuex中最为核心的store
        //引入Vue
        import Vue from "vue";
        Vue.use(Vuex);
        //引入Vuex
        import Vuex from "vuex";
        
        //准备actions 用于响应组件中的动作
        const  actions = {
          
          
            jia(context,value){
          
          
                console.log("action 的jia被调用");
                context.commit('JIA',value);
            },
            jian(context,value){
          
          
                console.log("action 的jian被调用");
                context.commit('JIAN',value);
            },
            jiaOdd(context,value){
          
          
                console.log("action 的jiaOdd被调用");
                if (context.state.sum % 2){
          
          
                    context.commit('JIAODD',value);
                }
            },
            jiaWait(context,value){
          
          
                console.log("action 的jiaWait被调用");
                setTimeout(()=>{
          
          
                    context.commit('JIAWAIT',value);
                },1000);
            }
        };
        //准备mutation,用于操作数据(state)
        const mutations = {
          
          
            JIA(state,value){
          
          
                console.log("mutations 的JIA被调用")
                state.sum += value;
            },
            JIAN(state,value){
          
          
                console.log("mutations 的JIAN被调用")
                state.sum -= value;
            },
            JIAODD(state,value){
          
          
                console.log("mutations 的JIAODD被调用")
                state.sum += value;
            },
            JIAWAIT(state,value){
          
          
                console.log("mutations JIAWAIT")
                state.sum += value;
            }
        };
        //准备state 用于存储数据
        const state = {
          
          
            sum:0
        };
        
        //创建并暴露store
        export default new Vuex.Store({
          
          
            actions,
            mutations,
            state
        });
    
    
  2. 组件中读取vuex中的数据:$store.state.sum(属性名)
  3. 组件中修改vuex中的数据:$store.dispatch('actions中的方法名',数据)$store.commit('mutations中的方法名',数据)
  4. 备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch直接写commit

5.getters的使用

  1. 概念:当state中的数据需要经过加工后再使用,可以使用getters加工。
  2. store/index.js文件中追加getters配置
        //准备getters 用于将state中的数据进行加工
        const getters = {
          
          
            bigSum(state){
          
          
                return state.sum*10;
            }
        }
        
        //创建并暴露store
        export default new Vuex.Store({
          
          
            actions,
            mutations,
            state,
            getters
        });
    
    
  3. 组件中读取数据:$store.getters.(getters中的方法名)bigSum

6.四个map方法使用

  1. mapState方法使用:用于帮我们映射state中的数据为计算属性
       computed:{
           //借助mapState自动生成计算属性的代码,从state中读取数据。(对象写法)
           ...mapState({sum: 'sum', myName: 'myName', mySubject: 'mySubject'}),
           //借助mapState自动生成计算属性的代码,从state中读取数据。(数组写法)
           ...mapState(['sum','myName','mySubject'])
       }
    
  2. mapGetters方法:用于帮我们映射getters中的数据为计算属性
       computed:{
           //借助mapGetters自动生成计算属性的代码,从getters中读取数据。(对象写法)
           ...mapGetters({bigSum:'bigSum'}),
           //借助mapGetters自动生成计算属性的代码,从getters中读取数据。(数组写法)
           ...mapGetters(['bigSum'])
       }
    
  3. mapActions方法:用于帮助我们生成与actions对话的方法,即包含$store.dispatch(xxx)的函数
       methods:{
           //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
           ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
    
           //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
           ...mapActions(['jiaOdd','jiaWait'])
       }
    
  4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数
       methods:{
           //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
           ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    
           //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
           ...mapMutations(['JIA','JIAN'])
       }
    
  5. **备注:**mapActions与mapMutations使用时,若需要传递参数,需在模板中绑定事件时传递好参数,否则参数是事件对象

7.模块化+命名空间

  1. 目的:让代码更好维护,让多种数据分类更加明确。
  2. 修改store/index.js文件
       const CountOption = {
          
          
           namespaced:true,//开启命名空间
           actions:{
          
          
               jia(context,value){
          
          
                   console.log("action 的jia被调用");
                   context.commit('JIA',value);
               },
               jian(context,value){
          
          
                   console.log("action 的jian被调用");
                   context.commit('JIAN',value);
               },
               jiaOdd(context,value){
          
          
                   console.log("action 的jiaOdd被调用");
                   if (context.state.sum % 2){
          
          
                       context.commit('JIAODD',value);
                   }
               },
               jiaWait(context,value){
          
          
                   console.log("action 的jiaWait被调用");
                   setTimeout(()=>{
          
          
                       context.commit('JIAWAIT',value);
                   },1000);
               }
           },
           mutations:{
          
          
               JIA(state,value){
          
          
                   console.log("mutations 的JIA被调用")
                   state.sum += value;
               },
               JIAN(state,value){
          
          
                   console.log("mutations 的JIAN被调用")
                   state.sum -= value;
               },
               JIAODD(state,value){
          
          
                   console.log("mutations 的JIAODD被调用")
                   state.sum += value;
               },
               JIAWAIT(state,value){
          
          
                   console.log("mutations JIAWAIT")
                   state.sum += value;
               }
           },
           state:{
          
          
               sum:0,//当前和
               myName:'linture',
               mySubject:'vue'
           },
           getters:{
          
          
               bigSum(state){
          
          
                   return state.sum*10;
               }
           }       
      }       
      const PersonOption = {
          
          
          namespaced:true, //开启命名空间 
          actions:{
          
          
              addPerson(context,value){
          
          
                 console.log('@@',context.state.personList,value);
                 axios.get("https://api.uixsj.cn/hitokoto/get").then(
                     response => {
          
          
                         let newPId = 1;
                         let motto = '>_<';
                         if (context.state.personList.length>0){
          
          
                             newPId = context.state.personList[0].id + 1;
                         }
                         motto = response.data;
                         console.log("找到啦!",response.data);
                         const per = {
          
          id:newPId,name:value,motto:motto};
                         context.commit("ADD_PERSON",per);
                     },
                     error => {
          
          
                         console.log('没有找到。。。',error.message);
                     }
                 )
    
              }
          },
          mutations:{
          
          
              ADD_PERSON(state,value){
          
          
                  state.personList.unshift(value);
                  localStorage.setItem("personList",JSON.stringify(state.personList));
              }
          },
          state:{
          
          
              personList:JSON.parse(localStorage.getItem('personList')) || [{
          
          id:2,name:'linture',motto:'加倍爱你'},{
          
          id:1,name:'小林',motto:'爱你'}]
          },
          getters:{
          
          
              topPerson(state){
          
          
                  return state.personList[0].name;
              }
          }
      }
    
      //创建并暴露store
      export default new Vuex.Store({
          
          
          modules:{
          
          
              CA:CountOption,
              PA:PersonOption
          }
      });
    
  3. 开启命名空间后,组件中读取state数据:
       this.$store.state.PA.personList;//方式一:自己直接读取
       ...mapState('PA',['personList']) //方式二:借助mapState读取
    
  4. 开启命名空间后,组件中读取getters数据:
       this.$store.getters['PA/topPerson'];//方式一:自己直接读取
       ...mapGetters('CA',['bigSum']) //方式二:借助mapGetters读取
    
  5. 开启命名空间后,组件中调用dispatch:
       this.$store.dispatch('PA/addPerson',this.name);方式一:自己直接调用
       ...mapActions('CA',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'}) //方式二:借助mapActions调用
    
  6. 开启命名空间后,组件中调用commit:
       this.$store.commit('PA/addPerson',this.name);方式一:自己直接调用
       ...mapMutations('CA',{increment:'JIA',decrement:'JIAN'}) //方式二:借助mapMutation调用
    

十八、路由

  1. 理解:一个路由(route)就是由一组映射关系(key-value),多个路由需要路由器(router)进行管理。
  2. 前端路由:key是路径,value是组件
  3. 后端路由:key是路径,value是function

1.基本使用

  1. 安装vue-router,命令:npm i vue-router@3(安装3版本,适用于vue2,默认为4版本,只能用于vue3)
  2. 应用插件:Vue.use(router)
  3. 编写router配置项:
         // 该文件专门用于创建整个应用的路由器
         //引入VueRouter
         import VueRouter from "vue-router";
         import About from "@/components/About";
         import Home from "@/components/Home";
         
         //创建一个路由器,并暴露
         export default new VueRouter({
          
          
             routes:[
                 {
          
          
                     path:'/about',
                     component:About
                 },
                 {
          
          
                     path:'/home',
                     component:Home
                 }
             ]
         });
    
  4. 实现切换(active-class可以配置高亮激活样式)
        <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>
    
  5. 指定展示位置:
       <router-view></router-view>
    

2.几个注意点

  1. 路由组件通常存放在pages文件夹中,一般组件通常存放在components文件夹中。
  2. 通过切换,“隐藏”了路由组件,默认是被销毁掉的,需要是再重新挂载
  3. 每个组件都有自己的$route属性,里面存储着自己的路由信息
  4. 整个应用只有一个router,可以通过组件的$router属性获取到

3.多级路由

  1. 配置路由规则,使用children配置项:
         routes:[
        {
          
          
            path:'/home',
            component:Home,
            children:[ //通过children配置子路由
                {
          
          
                    path: 'news', //此处一定不要写 /news
                    component: News,
                },
                {
          
          
                    path: 'message', //此处一定不要写 /message
                    component: Message,
                }
            ]
    
        }]
    
  2. 跳转(要写完整的路径)
       <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
    
       <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
    

4.路由的query参数

  1. 传递参数
       <!--        跳转路由并携带query参数,to的字符串写法-->
       <!--        <router-link :to="`/home/message/detail?${m.id}&${m.title}`">{
         
         {m.title}}</router-link>-->
    
         <router-link :to="{
           path:'/home/message/detail',
           query:{
             id:m.id,
             title:m.title
           }
         }">{
         
         {m.title}}</router-link>
    
  2. 接收参数:
       $route.query.id
       $route.query.title
    

5.路由的命名

  1. 作用:可以简化路由的跳转
  2. 如何使用
    1. 给路由命名:

         routes:[      
             {
              
              
                   path: 'message', //此处一定不要写 /message
                   component: Message,
                   children:[
                       {
              
              
                           name:"msg", //给路由命名
                           path:'detail',
                           component:Detail
                       }
                   ]
               }
         ]
      
    2. 简化跳转:

          <router-link :to="{
          name:'msg', //简化写法
          // path:'/home/message/detail', //简化前
          query:{
            id:m.id,
            title:m.title
          }
        }">{
             
             {m.title}}</router-link>
      

6. 路由的params参数

  1. 配置路由,声明接收params参数
         routes:[      
              {
          
          
                    path: 'message', //此处一定不要写 /message
                    component: Message,
                    children:[
                        {
          
          
                            name:"msg", //给路由命名
                            path:'detail/:id/:msg', //必须使用占位符声明接收params参数
                            component:Detail
                        }
                    ]
                }
          ]
    
  2. 传递参数
     <li v-for="m in messageList" :key="m.id">
    
      <!--        跳转路由并携带query参数,to的字符串写法-->
      <!--        <router-link :to="`/home/message/detail/${m.id}/${m.msg}`">{
         
         {m.title}}</router-link>-->
    
         <router-link :to="{
           name:'msg', //使用params必须使用name
           // path:'/home/message/detail',
           params:{
             id:m.id,
             msg:m.msg
           }
         }">{
         
         {m.title}}</router-link>
    
  3. 接收参数:
       $route.params.id
       $route.params.msg
    

7.路由的props配置

作用:让路由组件更加方便地收到参数

   const router = new VueRouter({
    
    
   routes: [
       {
    
    
           name: "msg",
           path: 'detail/:id/:msg',// ()
           component: Detail,
           /*
             props的第一种写法:值为对象,
              该对象中的所有key-value都会以props的形式传给Detail组件
           */
           // props:{
    
    
           //     a:1,
           //     b:'hello'
           // }

           /*
           * props的第二种写法:值为布尔值,
           * 若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件
           * */
           props: true
           /*
           * props的第三种写法:值为函数
           * */
           // props($router){
    
    
           //     return{
    
    
           //         id:$router.query.id,
           //         msg:$router.query.msg
           //     }
           // }
         }]
       })
      
    

8.路由对浏览器历史记录的影响

**<router-link>**的replace属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式
  2. 浏览器的历史记录有两种写入方式:分别为pushreplace,push是追加历史记录,replace是替换当前记录。路由跳转时默认是push
  3. 如何开启replace模式:<router-link replace ...>News</router-link>

9.编程式路由导航

  1. 作用:不用借助<router-link>实现路由跳转,让路由跳转更加灵活
  2. 具体编码:
       pushShow(m){
       this.$router.push({
         name:'msg', //使用params必须使用name
         params:{
           id:m.id,
           msg:m.msg
         }
       });
     },
     replaceShow(m){
       this.$router.replace({
         name:'msg', //使用params必须使用name
         params:{
           id:m.id,
           msg:m.msg
         }
       });
     }
    
    
    this.$router.forward();//前进
    this.$router.back();//后退
    this.$router.go(2)//正数为几,则前进几步;负数为几,则后退几步
    

10.缓存路由组件

  1. 作用:让不展示的路由组件保持挂载状态,不被销毁
  2. 具体编码:
        <!--缓存一个-->
        <keep-alive include="News"> <!--这里的News是组件名-->
           <router-view></router-view>
        </keep-alive>
    
        <!--缓存多个-->
      <keep-alive :include="['News','Message']">
        <router-view></router-view>
      </keep-alive>
    

11.两个新的生命周期钩子

  1. 作用:路由组件所独有的两个钩子用于捕获路由组件的激活状态。
  2. 具体名字:
    1. actived路由组件被激活时触发
    2. deactived路由组件失活时触发

12.路由守卫

  1. 作用:对路由进行权限控制
  2. 分类:全局守卫、独享守卫、组件内守卫
  3. 全局守卫:
         //全局前置路由守卫--初始化的时候、每次路由切换之前被调用
         router.beforeEach((to,from,next)=>{
          
          
         // if (to.path === '/home/news' || to.path === '/home/message'){
          
          
             if (to.meta.isAuth){
          
          
                 if (localStorage.getItem("user")==="linture"){
          
          
                     next();
                 }else{
          
          
                     alert("暂无权限!");
                 }
             }else {
          
          
                 next();
             }
         });
         
         //全局前置路由守卫--初始化的时候、每次路由切换之后被调用
         router.afterEach((to, from)=>{
          
          
             document.title = to.meta.title || 'linTureStudio' ; //修改网页页签上的标题
         });
    
  4. 独享路由守卫:
         //在需要单独路由守卫的路由中配置beforeEnter()函数
        const router = new VueRouter({
          
          
            routes:[
            {
          
               
              beforeEnter(to,from,next){
          
          
    
              }
            }
          ]
        })
    
  5. 组件内守卫:
       //进入守卫,通过路由规则进入组件时调用
       beforeRouteEnter(to,from,next){
           if (to.meta.isAuth){
               if (localStorage.getItem("user")==="linture"){
                   next();
               }else{
                  alert("暂无权限!");
               }
           }else{
               next();
           }
       },
       //离开守卫,通过路由规则离开组件时调用
       beforeRouteLeave(to,from,next){
          next(); //不写会无法离开组件
       }
    

13.路由器的两种工作模式

  1. 对于一个url来说,什么是hash值?— #及其后面的内容就是hash值
  2. hash值不会包含在HTTP请求中,即:hash值不会带给服务器
  3. hash模式:
    1. 地址中永远带着#号,不过美观
    2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
    3. 兼容性较好
  4. history模式:
    1. 地址干净,美观
    2. 兼容性和hash模式相比略差
    3. 应用部署上线是需要后端人员支持,解决刷新页面服务器端404问题

十九、Vue项目打包

npm run build 将vue文件,转换为html、css、js
生成dist目录

二十、Element-ui 的使用

参考官方文档
按需引入时需修改相应文件,官方文档中所述的.babelrc 文件不存在或找不到,应修改babel.config.js文件,修改如下:
修改babel.config.js文件

     module.exports = {
    
    
 presets: [
     '@vue/cli-plugin-babel/preset',["@babel/preset-env", {
    
     "modules": false }]
 ],
 plugins: [
     [
         "component",
         {
    
    
             "libraryName": "element-ui",
             "styleLibraryName": "theme-chalk"
         }
     ]
 ]
}

写在最后

个人学习尚硅谷vue2所记录的笔记,会不全,尽请指正。

猜你喜欢

转载自blog.csdn.net/m0_56942812/article/details/126675203