VUE 组件

180 阅读2分钟

目录

  • 自定义组件processTemp
  • residePerson.vue
  • appBtn.vue
  • componentTable

自定义组件processTemp

const processTemp = {
  template: `<div class="process">
          <span :style="{width:33.3*(currStep+1)+'%'}"></span>
        </div>`,
  props:['currStep']
}
export default {
    components: {
      processTemp
    },
}
[学习来源_vue自定义组件](https://www.cnblogs.com/xiangW/p/10994618.html)

residePerson.vue

<template>
  <div v-if="isShowCalc"
       :class="['residePerson',addClassName]"
       @click="toPersonCenter()">
    <div v-if="$tools.getStoreVal('ENTRY_APP')=='aliApplet'">
      <i class="icon icon-peo0"></i> <span>个人中心</span>
    </div>
    <div v-if="$tools.getStoreVal('ENTRY_APP')=='dingding'" class="collect">
      <i class="icon icon-folder0"></i><span>收藏</span>
    </div>
  </div>
</template>
<residePerson :isShow="isShowResidePerson"></residePerson>
<script>
  export default {
    name: 'residePerson',
    props: {
      isShow: {type: null, default: true},
    },
    data() {
      return {
        addClassName:'',
        scrollY:0,
      }
    },
    computed: {
      isShowCalc() {
        return this.isShow
          && (
            this.$tools.getStoreVal('ENTRY_APP')=='aliApplet'
            || this.$tools.getStoreVal('ENTRY_APP')=='dingding'
          )
          && this.$route.path.indexOf('personal') == -1
      }
    },
    methods: {
      toPersonCenter() {
        this.$router.push({path: '/personal'})
      },
      handleScroll() {
        this.scrollY = this.$tools.getScrolly()
      },
      hideSide() {
        this.addClassName= ''
      },
    },
    watch: {
      'scrollY': function (val) {
        this.addClassName= 'hideSide'
        this.$tools._debounce(this.hideSide, 800, null)
      },
      'isShowCalc': function (val) {
        this.isShowCalc && window.addEventListener('scroll', this.handleScroll)
      }
    },
    beforeDestroy() {
      window.removeEventListener('scroll', this.handleScroll);
    },
  }
</script>
<style lang="less" scoped>
  @import "../../../static/font/iconfont.css";
  .residePerson{
    position:fixed;.px(right,14);.px(bottom,230);z-index:@Z999 - 1;
    .px(width,100);.px(height,100);
    text-align: center;
    border-radius: 50%;
    background: @HFFFFFF;.FNBoxShadow(0px 1px 2px 0px @HE1E2E6);
    .FNTranAll();
    span{
      display: block;
      .FNFont(@F20,26,@H999999);
      transform: scale(0.8);
    }
    .icon{
      display: block;
      .px4(padding,14,0,4,0);
      .px(font-size, 36);line-height: 1.2;
      .FNGradualText(@c1:@H007DFF,@c2:@H5F00E8);
    }
    &.hideSide{
      transform: translateX(0.28rem);
      opacity: 0.6;
    }

    .collect{
      .icon{
        .FNGradualText(@c1:@HFAD357,@c2:@HFAD357);
      }
    }
  }
</style>

appBtn.vue

<template>
  <button :disabled="disabled" :class="['appBtn',type,size, styles]" @click="btnClick">
    {{text}}
    <slot></slot>
  </button>
</template>
<appBtn text="按钮txt" styles="style_150_60_24 style1 style2 ..." type="text" @FNAppBtn="invoice(el)"></appBtn>
<script>
  /**
   * @Author: ...
   * @Date: ...
   * @Param:
   *        size:按钮大小 middle:320 large:400 line:100%
   *        type:类型 btn填充 lbtn线性 text:纯文字
   *        styles:按钮样式自定义  style_宽度_高度_字体大小
   *        text:按钮文字
   *        disabled
   * **/
  export default {
    name: 'appBtn',
    props: {
      size: {type: null, default: 'middle'},
      type: {type: null, default: 'btn'},
      styles: {type: null, default: ''},
      text: {type: null, default: ''},
      disabled: {type: null, default: false},
    },
    methods: {
      btnClick() {
        this.$emit('FNAppBtn')
      }
    }
  }
</script>
<style lang="less" scoped>
  .px44(@h,@s){
    @h0:(@h - @s)/2;
    padding:(@h0 + 1) / @F * 1rem 0 (@h0 - 1) / @F * 1rem 0;
    .px(font-size, @s);line-height:1;
  }
  /*
    默认:
      height: 80  font-size:32
  */
  .appBtn{
    .comStyle();
    // button
    .px44(80, @F32);border:1px solid @HFFFFFF;.boxSizing();
    .px(letter-spacing, 0);text-align:center;
    .px(border-radius, 10);
    color:@HFFFFFF;
    .FNTranAll();
    &[disabled]{
      background:@HD8D8D8;
    }
  }
  .lbtn{ border:1px solid @H185EFA; color:@H185EFA; background:@HFFFFFF; }
  .btn{ .FNGradual(@H007DFF, @H5F00E8); }
  .text{ white-space:nowrap;color:@H999999; background:transparent; }
  .text2{ .text();border-color:@HF2F3FA; }
  /* size */
  .line{width:100%;}
  .line2{.px(width, 668);}
  .middle{ .px(width, 320); }
  .large{ .px(width, 400); }
  /* 私有样式集合 */
  .appBtn{
    // 用于文件.vue
    &.style_宽_高_字号{
      .px(width, 宽);.px44(高, @F字号);
    }
  }
</style>

componentTable

<componentTable 
    ref="componentTable"
    :request="数据请求对象"
    :fieldNames="数据对象list和page eg:data.list.data"
    :params="入参对象" // 
    :tables="表单数据 表头+对应的key {title,key,width,filter{}}" // 
    tableHeight="表单固定高度"
    className='需要添加的className'
    :submitDataHandle="提交之前数据处理fn"
    :reqDataHandle="数据请求回来之后数据处理fn"
    @reqDataFinish="数据请求结束 eg:可以this.$emit(放出全部resp.data)">
    <template slot="slotName"></template>
</componentTable>
01 componentTable
	box >
		slot
		form
			formItem (搜索条件 for)
				label + key + style
				type + rules
				v-model + placeholder + Fns
				---------
				input + select + datePicker
				submit + reset
			slot
		slot
		tableBox
			table
			loading
			page
02 Object
	search + page
03 Mounted
	this.$route.query
	dataDeal
	dataLoads
04 Other
	reset
{
            title: 'th',
            key: 'td key',
            ·······style(width/height/class),
            ·······other attr,
            search: {
              type: 'input/textarea/.',
              placeholder:'placeholder',
              key: 'value key',
              ·······style(width/height/class),
              ·······other attr,
            },
}