vue2组件封装示例

组件封装注意事项:

1、props:属性。是父容器给子组件参数传递的桥梁

2、this.$emit:事件。子组件通知父容器事件发生,并给父容器传递数据和参数

3、子组件中经常要用watch监控数据变化

思考题:如果父容器要调用子组件的方法实现一些操作,怎么办?让父容器直接调用方法吗?

(父组件中ref="player"     然后执行this.$refs.player.resetStatus()),虽然可以这样用,但是不建议这样做,

因为如果页面和组件之间可以随意调用属性和方法,如果组件比较多和复杂,页面调用逻辑将会变的非常混乱,代码会变的不可维护。

 

下面示例:一个播放器组件

<template>
        <div style="display: flex;align-items:center;">
          <div class="play" id="playpause" data-context="f"  @click="handlplay">
            <span>
              <a-icon :type="iconfig?'pause':'caret-right'" class="icon"/>
            </span>
          </div>

          <div class="airMoniTitle" >
            <p>{{timeTitle}}</p>
          </div>
        </div>
</template>
<script>
  import {getDateYMDHMS,getDateYMDHM_CN,stringToDate,dateAdd} from '@utils/date'
export default { 
    name:'singleTime', //单时间组件,日期组件包含一个日期和一个小时,鼠标点击日期修改事件:changeEvent(time),
    props:{
      timeInterval:{
        type:Number, //秒1000等于1秒,默认2秒
        default:1500
      },
      initialDate:{//初始化日期,如果初始化不给值,则默认用当天日期,格式:yyyyMMddHHmmss
          type:String
      },
    },
    data() {
        return {
            timeStr:'',//时间字符串
            timeTitle:'',//时间标题
            iconfig:false,  //false停止,true播放
            Time:null,    // 计时器
            dataIndex:0,//播放序号
        }
    },
    created(){
        this.dataIndex=0;
        if(this.initialDate)
        { //当他要初始化日期时
            this.timeStr = this.initialDate;
            this.timeTitle=getDateYMDHM_CN(stringToDate(this.timeStr));
        }
        else
        {
            this.timeStr = getDateYMDHMS(new Date(),'');
            this.timeTitle=getDateYMDHM_CN(stringToDate(this.timeStr));
        }
    },
    watch:{
        initialDate(val){//当多次模拟的initialDate一样的时候watch不执行,这个时候要配合resetTime()一起使用
            this.timeStr = val;
            this.timeTitle=getDateYMDHM_CN(stringToDate(this.timeStr));
            this.dataIndex=0;
        },
    },
    methods: {
      resetTime(time)
      {
        this.timeStr = time;
        this.timeTitle=getDateYMDHM_CN(stringToDate(this.timeStr));
        this.dataIndex=0;
      },
      resetStatus()//让播放器的状态重置
      {
        //console.log("reset");
        clearInterval(this.Time)//清除计时器
        this.Time = null;//设置为null
        this.dataIndex=0;
        this.iconfig=false;
      },
      handlplay()//播放
      {
        this.iconfig = !this.iconfig;
        if (this.iconfig) {// 开始播放
          this.Time = setInterval(() => {
            if(this.dataIndex >= 13)
            {//播放结束,从新开始播放
              this.dataIndex=0;
              let dates=dateAdd(stringToDate(this.timeStr),'f',this.dataIndex*5);
              this.timeTitle=getDateYMDHM_CN(dates);
              let timess=getDateYMDHMS(dates,'');

              this.$emit('playerTimeChange',{xh:(this.dataIndex+ 1),timestr:timess})
            }
            else
              {//播放中
              this.dataIndex  = (this.dataIndex+ 1);
              let dates=dateAdd(stringToDate(this.timeStr),'f',this.dataIndex*5);
              this.timeTitle=getDateYMDHM_CN(dates);
              let timess=getDateYMDHMS(dates,'');

              this.$emit('playerTimeChange',{xh:(this.dataIndex+ 1),timestr:timess})
            }


          }, this.timeInterval)
        } else {
          clearInterval(this.Time)//清除计时器
          this.Time = null;//设置为null
        }
      }
    }
    
}
</script>
<style lang="less" scoped>
  #playpause{
    font-family: iconfont;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    cursor: pointer;
    font-size: 25px;
    width: 60px;
    height: 33px;
    z-index: 999;
    color: white;
    background: rgba(0, 0, 0, 0.7);
    border: 1px solid #888888;
    span{
      padding-top: 3px;
      color: #fff;
      text-align: center;
      display: block;
    }
  }
  .airMoniTitle{
    width: 210px;
    height: 33px;
    z-index: 999;
    background: rgba(0, 0, 0, 0.7);
    font-size: 16px;
    color: #fff;
    text-align: center;
    padding: 0 10px;
    border: 1px solid #888888;
    p{
      line-height: 20px;
      font-size: 16px;
      font-weight: 500;
    }
    p:nth-child(1){
      padding-top: 5px;
    }
  }
</style>

 

1、父组件中引入:
import TimePlayer from '@comp/timeLine/TimePlayer'
2、component申明:
components: {
      TimePlayer,
    },
3、标签使用:
<TimePlayer ref="player" :initialDate="selectedTime"  @playerTimeChange="playerTimeChange"
                  style="z-index: 999;position: fixed;left: 250px;top: 100px;"/>

 

注意:组件中props下的属性,是父组件给子组件的传值,子组件中只能读取,不能修改。

posted @ 2022-06-08 11:51  JackGIS  阅读(854)  评论(0编辑  收藏  举报