Vue2学习笔记03——Vue组件化编程

一、组件的自定义事件——绑定

  1. 一种组件间的通信方式,适用于:子组件 ==> 父组件
  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就需要在A中给B绑定自定义事件(事件的回调在A中)
  3. 绑定自定义事件:
    • 第一种方式:在父组件中:<Demo @shijian="text"/> 或者 <Demo v-on:shijian="test"/>
    • 第二种方式:在父组件中:
      ``HTML ... mounted(){ this.$ref.xxx.$on('demo',this.test) }
      1
      2
      3
      4
      5
      6
      7
          - 若想让自定义事件只能触发一次,可以使用`once`修饰符或`$once()`方法
      4. 触发自定义事件:`this.emit('shijian',数据)`
      5. 解绑自定义事件
      - `$off()`可以解绑一个,多个,全部自定义事件
      - 解绑一个自定义事件
      ```javascript
      节点元素.$off('自定义事件名称')
      - 解绑多哥自定义事件
      1
      节点元素.$off(['自定义事件名称1','自定义事件名称2'])
      - 解绑一个元素的所有自定义事件
      1
      节点元素.$off()
    • $destory() 销毁后,所有自定义事件均会失效,而原生自定义事件不会被销毁
  4. 组件上也可绑定原生DOM事件,需要使用native`符号修饰
  5. 注意: 通过this.$ref.xxx.$on('demo',this.test)绑定的自定义事件,回调要么配置在methods中,要么使用箭头函数,否则this指向会出问题

二、全局事件总线(GlobalEventBus)

  1. 一种组件间的通方式,适用于任意组件间通信。
  2. 安装全局事件总线:
    1
    2
    3
    4
    5
    6
    7
    8
    new Vue({
    ...
    //在构建页面之前,生命周期中第一个钩子函数
    beforeCreate(){
    Vue.prototype.$bus=this //安装全局事件总线。 this指向Vm
    },
    ...
    })
  3. 使用事件总线:
    • 接收数据:A组件想要接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
      1
      2
      3
      4
      5
      6
      7
      methods(){
      demo(data){......}
      }
      ......
      mounted(){
      this.$bus.$on('xxx',this.demo) //也可写成箭头函数的回调函数
      }
    • 提供数据:this.$bus.$emit('xxx',数据)
  4. 最好是在beforeDestory钩子中,用$off()去解绑当前组件所用到的事件

三、消息订阅与发布

  1. 一种组件间通信方式,适用于任意组件之间通信
  2. 使用步骤:
    • 安装pubsub:
      1
      npm install pubsub-js
    • 引用:
      1
      import pubsub from 'pubsub-js'
    • 接收数据:A组件想要接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      methods:{
      demo(MagName,data){...}
      }
      mounted(){
      this.pubid=pubsub.subscribe('xxx',this.demo) //回调函数也可直接写成箭头函数
      }
      // beforeDestroy 生命周期选项被重命名为 beforeUnmount
      beforeUnmount() {
      pubsub.unsubscribe(this.pubid) //取消订阅
      },
    • 提供数据:pubsub.publish('xxx',数据)
    • 最好在beforeDestroy()钩子函数中去取消订阅, pubsub.unsubscribe(this.pubid)
  3. 这里遇到问题为pubsub会传回两个参数(MsgName,data),但实际函数运用只会使用一个,在定义函数时可以使用展位符号_, demo(_,data){…}来保证后面使用的数据是需要的数据

四、Vue相关技术

  1. 语法: $nextTick(回调函数)
    1
    this.$nextTick(function(){this.$refs.inputtype.focus()}) //可以直接使用定时器不加世间执行
  2. 作用:在下一次DOM更新结束后执行其指定的回调
  3. 什么时候使用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。

五、过渡与动画

  1. Vue封装的动画与过渡的作用:在插入、更新、移除DOM元素时,在合适的时候给元素添加样式类名。
  2. 图示:
    Vue封装的动画与过渡
  3. 写法:
    • 准备好啊样式
      • 元素进入样式:
        • v-enter: 进入的起点
        • v-enter-active: 进入的过程 (若使用@keyframes编写动画,只需要这个样式设置)
        • v-enter-to: 进入的终点
      • 元素离开的样式:
        • v-leave: 离开的起点
        • v-leave-avtive: 离开的过程 (若使用@keyframes编写动画,只需要这个样式设置)
        • v-enter-to: 离开的终点
    • 使用<transition><transition/>包裹要过度的元素,并配置name属性
      1
      2
      3
      <transition name="hello">
      <h1 v-show="isShow">你好呀</h1>
      </transition>
  4. 注: 若有多个元素需要过渡,则需要使用:<transition-group>,且每个元素都需要指定的key

六、Vue脚手架配置代理

  1. 方法一
    • vue.config.js中添加如下配置
      1
      2
      3
      devServer:{
      proxy:"http://loaclhost:3000" //将本地的8080端口请求代理到3000端口来解决跨域
      }
    • 优点:配置简单,请求资源时直接发送给前端8080即可
    • 缺点:不能配置多个代理,不能灵活控制请求是否走代理
    • 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转给服务器(优先匹配前端资源)
  2. 方式二
    • vue.config.js中配置具体代理规则
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      module.exports={
      devServer:{
      proxy:{
      '/api1':{ //匹配所有以 'api1' 开头的请求路径
      target:"http://loaclhost:5000", //代理目标的基本路径
      changeOrigion:true,
      pathRewrite:{'^/api1':''}

      },
      '/api2':{ //匹配所有以 'api2' 开头的请求路径
      target:"http://loaclhost:5001", //代理目标的基本路径
      changeOrigion:true,
      pathRewrite:{'^/api2':''}
      }
      }
      }
      }
      /*
      changeOrigion设置为true时,服务器收到的请求头中的host为:localhost:5000
      changeOrigion设置为false时,服务器收到的请求头中的host为:localhost:8080
      changeOrigion默认值为true
      */
    • 优点:可以配置多个代理,且可以灵活控制请求是否走代理
    • 缺点:配置略显繁琐,请求资源时必须加前缀

      七、Vue中的两个Ajax酷

  3. axios 通用的ajax请求库,官方推荐,使用广泛
  4. vue-resource vue插件库,vue1.x广泛使用,官方已经不再维护

八、slot插槽

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

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

  3. 使用方式:

    • 默认插槽:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <!-- 父组件中: -->
      <Category>
      <div>html结构1<div/>
      <Category/>

      <!-- 子组件中 -->
      <template>
      <div>
      <!-- 定义插槽 -->
      <slot>插槽默认内容,在外部未使用时显示<slot/>
      <div/>
      <template/>
    • 具名插槽:

       <!-- 父组件中: -->
       <Category>
           <template slot="center">
            <div>html结构1<div/>
           <template/>
      
           <template v-slot:footer>
            <div>html结构1<div/>
           <template/>
        <Category/>
      
        <!-- 子组件中 -->
        <template>
           <div>
              <!-- 定义插槽 -->
              <slot name="center">插槽默认内容,在外部未使用时显示<slot/>
              <slot name="footer">插槽默认内容,在外部未使用时显示<slot/>
           <div/>
        <template/>
      
    • 作用域插槽:

       <!-- 父组件中: -->
       <Category>
           <template scope="scopeDate">
            <!-- 生成无序列表i -->
            <ul>
               <li v-for="g in scopeDate.games" :kye="g">{{g}}<li/>
            <ul/>
           <template/>
        <Category/>
        <Category>
           <template scope="scopeDate">
            <!-- 生成h4标题 -->
             <h4 v-for="g in scopeDate.games" :key="g">{{g}}<h4/>
           <template/>
        <Category/>
      
        <!-- 子组件中 -->
        <template>
           <div>
              <!-- 定义插槽,设置传递参数 -->
              <slot :games="games">插槽默认内容,在外部未使用时显示<slot/>
           <div/>
        <template/>
      
        <script>
          export default {
            name:"Category",
              data() {
                    return {
                      games:['游戏名称1','游戏名称2','游戏名称3']
                  }
              },
        <script/>
      
      • 理解:数据在组件自身,但根据数据生成的结构需要组件的使用者来进行定义。