el高复用性组件封装

  1. el-pagination分页组件

    // 子组件
    <template>
      <el-pagination
        :current-page="currentPage"
        :page-sizes="pageSizes"
        :page-size="pageSize"
        :layout="layout"
        :total="total"
        v-bind="$attrs"
        v-on="$listeners"
      />
    </template>
    ​
    <script>
    export default {
      name: 'MyPagination',
      props: {
        currentPage: {
          type: Number,
          default: 1
        },
        pageSizes: {
          type: Array,
          default: () => [10, 20, 30, 40, 50]
        },
        pageSize: {
          type: Number,
          default: 10
        },
        layout: {
          type: String,
          default: 'total, sizes, prev, pager, next, jumper'
        },
        total: {
          type: Number,
          required: true
        }
      },
      methods: {
        handleSizeChange(newSize) {
          this.$emit('size-change', newSize)
        },
        handleCurrentChange(newPage) {
          console.log('触发', newPage)
          this.$emit('current-change', newPage)
        }
      }
    }
    </script>
    ​
    // 父组件使用
    <template>
      <div>
        <my-pagination
          :current-page="currentPage"
          :page-sizes="[10, 20, 30, 40]"
          :page-size="pageSize"
          :total="total"
          @current-change="handleCurrentChange"
          @size-change="handleSizeChange"
        />
      </div>
    </template>
    ​
    <script>
    import MyPagination from '@/components/MyPagination/index.vue'
    import { getDataAPI } from '/api'
    export default {
      components: {
        MyPagination
      },
      data() {
        return {
          currentPage: 1,
          pageSize: 10,
          total: 100,
          list: []
        }
      },
      methods: {
        getData() {
          getDataAPI({ limit: this.pageSize, page: this.page }).then(res =>     {
            this.list = res.data
          })
        },
        handleCurrentChange(newPage) {
          this.page =newPage
          this.getData()
        },
        handleSizeChange(newSize) {
          this.pageSize =newSize
          this.getData()
        }
      }
    }
    </script>
  2. el-drawer抽屉组件

    // 子组件
    <template>
      <el-drawer :visible="visible" :modal="false" :title="title" @close="handleClose">
        <div class="drawer-content">
          <slot />
        </div>
      </el-drawer>
    </template>
    ​
    <script>
    export default {
      name: 'MyDrawer',
      props: {
        visible: {
          type: Boolean,
          required: true
        },
        title: {
          type: String,
          default: ''
        }
      },
      methods: {
        handleClose() {
          this.$emit('update:visible', false)
        }
      }
    }
    </script>
    ​
    <style scoped>
    .drawer-content {
      padding: 20px;
    }
    </style>
    ​
    //父组件
    <template>
      <div>
    ​
        <el-button type="primary" @click="showDrawer = true">Open Drawer</el-button>
        <My-drawer :visible.sync="showDrawer" :title="title">
          <p>Some content goes here...</p>
        </My-drawer>
      </div>
    </template>
    ​
    <script>
    import MyDrawer from '@/components/MyDrawer/index.vue'
    ​
    export default {
      components: {
        MyDrawer
      },
      data() {
        return {
    ​
          // 弹框数据
          showDrawer: true,
          title: 'Drawer Title'
        }
      },
      methods: {
    ​
      }
    }
    </script>
  3. el-date-picker 选择时间组件

    // 子组件
    <template>
      <el-date-picker v-model="internalValue" :type="type" :placeholder="placeholder" :clearable="clearable" />
    </template>
    ​
    <script>
    export default {
      name: 'MyDatePicker',
      props: {
        value: {
          type: [String, Date],
          required: true
        },
        type: {
          type: String,
          default: 'date'
        },
        placeholder: {
          type: String,
          default: ''
        },
        clearable: {
          type: Boolean,
          default: true
        }
      },
      computed: {
        internalValue: {
          get() {
            return this.value
          },
          set(val) {
            val ? this.$emit('input', val) : this.$emit('input', '')
          }
        }
      }
    }
    </script>
    ​
    ​
    //父组件
    <template>
      <div>
        <my-date-picker
          v-model="date"
          label="选择日期"
          placeholder="请选择日期"
        />
        <p>选择的日期:{{ date }}</p>
      </div>
    </template>
    ​
    <script>
    import MyDatePicker from '@/components/MyDatePicker/index.vue'
    export default {
      components: {
        MyDatePicker
      },
      data() {
        return {
          date: ''
        }
      }
    }
    </script>
    ​
  4. el-select组件封装

    // 子组件
    <template>
      <el-select v-model="value" :options="options" :placeholder="placeholder">
        <el-option v-for="option in options" :key="option.value" :label="option.label" :value="option.value" />
      </el-select>
    </template>
    ​
    <script>
    export default {
      name: 'MySelect',
      props: {
        value: {
          type: [String, Number, Array],
          default: ''
        },
        options: {
          type: Array,
          default: () => []
        },
        placeholder: {
          type: String,
          default: ''
        }
      }
    }
    </script>
    ​
    // 父组件
    <template>
      <div>
        <my-select v-model="selectedValue" :options="options" :placeholder="'请选择12'" />
      </div>
    </template>
    ​
    <script>
    import MySelect from '@/components/MySelect/index.vue'
    ​
    export default {
      name: 'MyComponent',
      components: {
        MySelect
      },
      data() {
        return {
          selectedValue: '',
          options: [
            {
              label: '选项1',
              value: 'option1'
            },
            {
              label: '选项2',
              value: 'option2'
            },
            {
              label: '选项3',
              value: 'option3'
            }
          ]
        }
      }
    }
    </script>
  5. el-upload文件上传组件封装

    // 子组件
    <template>
      <el-upload
        :drag="drag"
        :action="action"
        multiple
        :headers="headers"
        :name="type"
        :data="data"
        :on-success="onSuccess"
        :on-remove="onRemove"
        :before-upload="beforeUpload"
      >
        <template v-if="drag">
          <i class="el-icon-upload" />
          <div class="el-upload__text">
            将文件拖到此处,或<em>点击上传</em>
          </div>
        </template>
        <template v-else>
          <el-button size="small" type="primary">
            <i class="el-icon-upload" /> 点击上传
          </el-button>
        </template>
        <template #tip>
          <div class="el-upload__tip">
            只能上传jpg/png文件,且不超过500kb
          </div>
        </template>
      </el-upload>
    </template>
    ​
    <script>
    ​
    export default {
      name: 'MyUpload',
    ​
      props: {
        action: {
          type: String,
          required: true
        },
        type: {
          type: String,
          default: 'img'
        },
        headers: {
          type: Object,
          default: () => ({})
        },
        data: {
          type: Object,
          default: () => ({})
        },
        drag: {
          type: Boolean,
          default: false
        },
        multiple: {
          type: Boolean,
          default: false
        },
        showFileList: {
          type: Boolean,
          default: true
        },
        fileList: {
          type: Array,
          default: () => []
        },
        onRemove: {
          type: Function,
          default: () => { }
        },
        onSuccess: {
          type: Function,
          default: () => { }
        },
        beforeUpload: {
          type: Function,
          default: () => { }
        }
      }
    }
    </script>
    ​
    // 父组件
    ​
    <template>
      <div>
        <MyUpload
          :drag="true"
          :action="uploadUrl"
          :file-list="fileList"
          :on-success="handleSuccess"
          :before-upload="handleBeforeUpload"
          :on-remove="handleRemove"
          :headers="{
            token: '2c4b4ec6be48954702fc79c1e513d6fde78d8798'
          }"
          :data="data"
          :type="'img'"
        />
      </div>
    </template>
    ​
    <script>
    import MyUpload from '@/components/MyUpload/index.vue'
    ​
    export default {
      components: { MyUpload },
    ​
      data() {
        return {
          uploadUrl: 'http://ceshi13.dishait.cn/admin/image/upload',
          fileList: [],
          data: {
            // 这里添加这个是因为此接口需要添加这个属性
            image_class_id: 168
          }
        }
      },
    ​
      methods: {
        handleBeforeUpload(file) {
          // 验证文件类型和大小
          const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
          const isLt2M = file.size / 1024 / 1024 < 2
    ​
          if (!isJpgOrPng) {
            this.$message.error('上传头像图片只能是 JPG/PNG 格式!')
          }
    ​
          if (!isLt2M) {
            this.$message.error('上传头像图片大小不能超过 2MB!')
          }
    ​
          return isJpgOrPng && isLt2M
        },
    ​
        handleSuccess(response, file, fileList) {
          // 上传成功处理
          this.fileList = fileList
          this.$message.success('上传成功')
        },
    ​
        handleRemove(file, fileList) {
          // 删除文件处理
          this.fileList = fileList
        }
      }
    }
    </script>
    ​

  6. MySearch 搜索组件

    // 子组件1
    <template>
      <el-form :model="model" label-width="80px" class="mb-3" size="small">
        <el-row :gutter="20">
          <slot />
          <template v-if="showSearch">
            <slot name="show" />
          </template>
          <el-col :span="8" :offset="showSearch ? 0 : 8">
            <div class="flex items-center justify-end">
              <el-button type="primary" @click="$emit('search')">搜索</el-button>
              <el-button @click="$emit('reset')">重置</el-button>
              <el-button v-if="hasShowSearch" type="primary" text @click="showSearch = !showSearch">
                <span class="mr-1">{{ showSearch ? '收起' : '展开' }}</span>
                <el-icon>
                  <ArrowUpBold v-if="showSearch" />
                  <ArrowDownBold v-else />
                </el-icon>
              </el-button>
            </div>
          </el-col>
        </el-row>
      </el-form>
    </template>
    ​
    <script>
    export default {
      props: {
        model: {
          type: Object,
          default: () => {}
        }
      },
      data() {
        return {
          showSearch: false,
          hasShowSearch: !!this.$slots.name
        }
      },
      created() {
    ​
      },
      methods: {
    ​
      }
    }
    </script>
    ​
    <style scoped lang="scss">
    ​
    </style>
    // 子组件2
    <template>
      <el-col :span="8" :offset="0">
        <el-form-item :label="label">
          <slot />
        </el-form-item>
      </el-col>
    </template>
    ​
    <script>
    export default {
      props: {
        label: {
          type: String,
          default: ''
        }
      }
    }
    </script>
    ​
    <style scoped lang="scss">
    ​
    </style>
    ​
    // 父组件
    <template>
      <!-- 搜索 -->
      <My-search show-search :model="searchForm" @search="getData" @reset="resetSearchForm">
        <MySearchItem label="订单编号">
          <el-input v-model="searchForm.no" placeholder="订单编号" clearable @keydown.enter="getData" />
        </MySearchItem>
        <template #show>
          <MySearchItem label="收货人">
            <el-input v-model="searchForm.name" placeholder="收货人" clearable />
          </MySearchItem>
          <MySearchItem label="手机号">
            <el-input v-model="searchForm.phone" placeholder="手机号" clearable />
          </MySearchItem>
          <MySearchItem label="开始时间">
            <el-date-picker
              v-model="searchForm.starttime"
              type="date"
              placeholder="开始日期"
              style="width: 90%;"
              value-format="YYYY-MM-DD"
            />
          </MySearchItem>
          <MySearchItem label="结束时间">
            <el-date-picker
              v-model="searchForm.endtime"
              type="date"
              placeholder="结束日期"
              style="width: 90%;"
              value-format="YYYY-MM-DD"
            />
          </MySearchItem>
        </template>
      </My-search>
    </template>
    ​
    <script>
    import MySearch from '@/components/MySearch/index.vue'
    import MySearchItem from '@/components/MySearchItem/index.vue'
    export default {
      components: {
        MySearch,
        MySearchItem
      },
      data() {
        return {
          searchForm: {
            tab: 'all',
            no: '',
            starttime: '',
            endtime: '',
            name: '',
            phone: ''
          },
          initForm: {
    ​
          }
        }
      },
      created() {
        this.initForm = this.searchForm
      },
      methods: {
        getData() {
          console.log(this.searchForm, 'this.searchForm')
        },
        resetSearchForm() {
          for (const key in this.searchForm) {
            this.searchForm[key] = this.initForm[key]
          }
          this.getData()
        }
      }
    }
    </script>
    ​
    <style scoped lang="scss">
    </style>
  7. 还有一个不属于el组件的常用组件(数字动画组件)

npm install -d gsap

// 子组件
<template>
  <div>
    <!-- 数字动画组件 -->
    {{ d.num.toFixed(0) }}
  </div>
</template>
​
<script>
import gsap from 'gsap'
​
export default {
  props: {
    value: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      d: {
        num: 0
      }
    }
  },
  watch: {
    value(newValue, oldValue) {
      console.log(`message changed from ${oldValue} to ${newValue}`)
      this.AnimateToValue()
    },
    immediate: true
  },
  created() {
    this.AnimateToValue()
  },
  methods: {
    AnimateToValue() {
      gsap.to(this.d, {
        duration: 0.5,
        num: this.value
      })
    }
  }
}
</script>
​
// 父组件
​
<template>
  <div>
    <MyGsap :value="10000" />
  </div>
</template>
​
<script>
import MyGsap from '@/components/MyGsap/index.vue'
export default {
  components: {
    MyGsap
  }
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值