Element-UI的开发经验总结

397 阅读1分钟

El-Slider滑块

自定义滑块的样式:

image.png

// 设置进度的颜色
/deep/.el-slider__bar{
    background-color: #FFA319;
}
// 设置默认的颜色
/deep/.el-slider__runway{
    background-color: #FFEDD1;
}
// 设置圆圈的颜色
/deep/.el-slider__button {
    border-color: #FFA319;
}

自定义滑块的 input框的内容 加上%

其实思路很简单,和滑块的内容无关,就是直接在这个滑块下面加一个 i标签,再设置这个i标签绝对定位就好了。

<el-slider
    v-model="stage.ctrVolatilityThreshold"
    :min="5"
    :max="95"
    :show-input-controls="false"
    input-size="mini"
    :disabled="isView"
    show-input
    label="%"
    @change="onChangeCtrPercent(index)"
    />
<i class="percent-text">%</i>

El-Pagination的封装

在业务系统中,尤其是针对管理端的系统,经常会存在表格、列表等,因此会需要pagination组件进行数据的翻页,因此这里对 pagination 进行封装。

<!-- 封装的组件 -->
<template>
  <div
    v-show="totalCount > 0"
    class="pagination-container"
  >
    <el-pagination
      background
      layout="prev, pager, next"
      :current-page="pageNo"
      :page-size="pageSize"
      :total="totalCount"
      @current-change="onCurrentChange"
    />
    <input
      v-model.trim="jumperInput"
      type="text"
      class="input-page"
    >
    <span
      class="btn-page"
      @click="onJumperClick"
    >跳转</span>
  </div>
</template>
<script>
export default {
  props: {
    pageSize: {
      type: Number,
      default: 10,
    },
  },
  data() {
    return {
      pageNo: 1,
      totalCount: 0,
      jumperInput: '',
    };
  },
  watch: {
    // 监听当前页的改变 发生改变 向父组件发起事件
    pageNo(val) {
      this.$emit('pageChage', val);
    },
  },
  methods: {
    // 当点击时
    onCurrentChange(val) {
      this.pageNo = val;
    },
    onJumperClick() {
      const jumperNum = Number(this.jumperInput);
      if (Number.isInteger(jumperNum) && jumperNum > 0) {
        // 取所有页的最小值
        const maxNum = Math.min(
          jumperNum,
          Math.ceil(this.totalCount / this.pageSize),
        );
        this.jumperInput = maxNum;
        if (maxNum !== this.pageNo) {
          this.pageNo = maxNum;
        }
      } else {
        this.jumperInput = '';
      }
    },
  },
};
</script>
<style lang="scss" scoped>
@import '~assets/scss/base.scss';
.pagination-container {
  width: 100%;
  background-color: #fff;
  text-align: center;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 0 0 6px 6px;
}
/* pageInput pageBtn */
.input-page {
  display: inline-block;
  width: 50px;
  height: 26px;
  border: 1px solid #dcdfe6;
  text-indent: 4px;
  border-radius: 4px;
}
.btn-page {
  color: $mainColor;
  margin-left: 10px;
  cursor: pointer;
}
</style>
<!-- 父组件中的使用 -->
<a-pagination
    ref="pagination"
    @pageChage="queryAuditAds"
/>
export default {
    component: {
        'a-pagination': pagination
    }
    computed: {
        // 分页组件
        pagination() {
          return this.$refs.pagination || { pageNo: 1, pageSize: 10 };
        },
    }
    method: {
        // 查询数据: 在页面初始化、点击查询、点击不同页码的时候去发起请求
        queryData() {
            const { pageNo, pageSize } = this.pagination; 
            // 请求成功后 从请求的数据中获取数据的总条数
            const { totalCount, auditAds } = res;
            this.pagination.totalCount = totalCount;
        },
        // 点击查询事件
        onQueryClick() {
            this.pagination.pageNo = 1;
            this.queryData()
        }
    }
}

El-Upload的封装

<template>
  <div>
    <el-upload
      :action="action"
      :list-type="listType"
      :auto-upload="false"
      :file-list="fileListUpload"
      :before-remove="onFileRemove"
      :on-change="onFileChange"
      :on-exceed="onFileExceed"
      :limit="limit"
      style="width: 60%;margin-right: 5px;"
    >
      <el-button
        size="small"
        type="primary"
      >
        点击上传
      </el-button>
      <span
        slot="tip"
        style="margin-left: 20px;"
      >{{ typeText }}</span>
    </el-upload>
  </div>
</template>
<script>
import axios from 'axios';
import { getBase64 } from '../assets/utils/index';
export default {
  props: {
    action: {
      type: String,
      default: '',
    },
    listType: {
      type: String,
      default: 'picture',
    },
    fileList: {
      type: Array,
      default: () => [],
    },
    // 文件格式类型
    typeArr: {
      type: Array,
      default: () => [],
    },
    typeText: {
      type: String,
      default: '',
    },
    limit: {
      type: Number,
      default: 1,
    },
    // 标志位-标志哪里使用了该组件
    flag: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      fileListUpload: [],
      urlImg: '',
      fileUrlList: [],
    };
  },
  created() {
    this.fileListUpload = this.fileList;
  },
  methods: {
    async onFileChange(file, fileList) {
      const fileChecked = fileList.find(item => item.uid === file.uid);
      const fileType = file.name.split('.')[1];
      if (this.typeArr.includes(fileType)) {
        this.fileListUpload = fileList;
        try {
          const fileData = await getBase64(fileChecked.raw);
          const opt = {
          // 要上传的接口
            url: UPLOAD_URL,
            method: 'post',
            data: { data: fileData },
          };
          axios(opt).then((res) => {
            if (res.data && res.data.ret_code === 0) {
            // 获取到返回的url
              this.urlImg = res.data.url;
              this.fileUrlList.push({ url: this.urlImg, uid: file.uid });
              this.$emit('upload', this.urlImg, this.flag);
              return;
            }
            fileChecked.status = 'fail';
            this.fileListUpload = this.fileListUpload.filter(item => item.uid !== file.uid);
            this.$message.error(res.data?.err_msg || '图片上传失败');
          });
        } catch (err) {
          this.fileListUpload = this.fileListUpload.filter(item => item.uid !== file.uid);
          this.$message.error(err);
        }
        return;
      }
      this.fileListUpload = fileList.filter(item => item.uid !== file.uid);
      this.$message.warning(this.typeText);
    },
    onFileRemove(file) {
      this.fileListUpload = this.fileListUpload.filter(item => item.uid !== file.uid);
      this.fileUrlList = this.fileUrlList.filter(item => item.uid !== file.uid);
      this.$emit('remove', this.fileUrlList, this.flag);
    },
    onFileExceed() {
      this.$message.warning(`只能上传${this.limit}个文件`);
    },
  },
};
</script>
// 图片转化为base64
export const getBase64 = file => new Promise((resolve, reject) => {
  const reader = new FileReader();
  let imgResult = '';
  reader.readAsDataURL(file);
  reader.onload = function () {
    imgResult = reader.result;
  };
  reader.onerror = function (error) {
    reject(error);
  };
  reader.onloadend = function () {
    resolve(imgResult);
  };
});

El-Upload读取数据,实现txt文件的写入 && 点击文件实现下载功能

// 获取数据 并写入txt文件中去
const a = [1, 2];
const txt = a.map(item => `${item}\n`);
// 写入txt文件
const fileName = `${dayjs().format('YYYY-MM-DD')}-${songName}.txt`;
const file = new File(txt, fileName, { type: 'text/plain' });
this.fileListTxt = [file];
return true;
// 点击文件 下载到本地
onFilePreview(file) {
    const url = URL.createObjectURL(file);
    const link = document.createElement('a');
    link.style.display = 'none';
    link.href = url;
    link.setAttribute('download', file.name);
    document.body.appendChild(link);
    link.click();
    URL.revokeObjectURL(url);
    document.body.removeChild(link);
 },

ElMessageBox的使用

用于在弹窗出现的时候 对于简单的确认或是只有一个输入框的时候 则可以不使用el-dialog的组件 而是使用简单的 ElMessageBox

const closeOrder = async (orderId: string, orderType: number): Promise<any> => {
  const result = await ElMessageBox.confirm(
    '请确认是否需要关闭订单',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    },
  ).catch(() => false);
  if (result === 'confirm') {
    const res = await closeOrderAPI({ orderId, orderType });
    if (res.ret === 0 && res.data) {
      ElMessage.success('成功关闭订单');
      return true;
    }
    ElMessage({
      message: MESSAGE.OPERATE_ERROR,
      type: 'error',
    });
    return false;
  }
};

---未完待续,持续更新