Elementコンポーネントライブラリの各コンポーネントに関する詳細な知識の要約----コンポーネント開発の問題の90%を解決

1.テーブル(el-table)。
1.複数のテーブルのデータが連結され、互いに混同されます。
  • 注:タブとv-if / v-showを切り替えるために同じコンポーネントに複数のテーブルがある場合、複数のテーブルのデータが互いに混同されてつなぎ合わされ、バグが発生します。

  • 解決策各テーブルに対応する一意のキー属性を指定します。

  • コアコード:

 <div class="crud__table" v-if="receiverType!=3">
    <el-table ref="table"
          key="table"
          header-row-class-name="crud-table-header"
          cell-class-name="crud-table-cell"
          row-key="id"
          border
          stripe
          highlight-current-row
          height="100%"
          style="min-height:405px"
          v-loading="loading"
          :data="tableData"
    >
       <el-table-column type="selection" width="45" v-if="receiverType==1"/>
       <el-table-column type="index" fixed :index="indexMethod" label="序号" width="50" align='center'/>
       <el-table-column label="名称" prop="name" show-overflow-tooltip
                                            :render-header="setTableColumnWidth"/>
       <el-table-column label="邮箱" prop="email" :render-header="setTableColumnWidth"/>
       <el-table-column label="手机" prop="phoneNo" :render-header="setTableColumnWidth"/>
       <el-table-column label="状态" prop="userStateName" :render-header="setTableColumnWidth"/>
    </el-table>
 </div>

 <div class="crud__table" v-if="receiverType==3">
    <el-table ref="groupTable"
      key="groupTable"
      header-row-class-name="crud-table-header"
      cell-class-name="crud-table-cell"
      border
      stripe
      highlight-current-row
      height="100%"
      :max-height="tabelHeight"
      style="min-height:405px"
      v-loading="loading"
      :data="groupTableData">
       <el-table-column type="selection" width="45"/>
       <el-table-column type="index" fixed :index="indexMethod" label="序号" width="50" align='center'/>
       <el-table-column label="名称" prop="name" show-overflow-tooltip :render-header="setTableColumnWidth"/>
       <el-table-column label="创建时间" prop="createTime" :render-header="setTableColumnWidth"/>
       <el-table-column label="操作" width="290">
              <template slot-scope="{row}">
                     <el-button type="text" @click="openUser(row)">查看用户</el-button>
              </template>
       </el-table-column>
    </el-table>
 </div>

复制代码
  • 例:図1はキーなしの効果を示し、図2は一意のキーがある場合の効果を示しています。

GIF.gif

GIF2.gif

2.テーブルの各行の操作ボタンに独立したロード状態を設定します。
  • 注:テーブルの操作バーの操作ボタン(承認、削除など)がインターフェースのリンクを要求している場合、各行の操作に比較的独立したロード状態を追加することは、非常にユーザーフレンドリーでユーザーフレンドリーです。デザイン。

  • 解決策:インターフェースがテーブルデータをプルして割り当てた後、this。$ set(item、'xxLoading'、false);を介してテーブルデータの各アイテムにそれぞれのロード状態コントロールを設定します。

  • コアコード:

html:

<el-table-column label="操作" width="100">
          <template slot-scope="{ row }">
            <el-button
              v-if="row.status !== 1"
              v-loading="row.disposeLoading"
              type="primary"
              size="small"
              @click="dispose(row)"
              >处理</el-button
            >
          </template>
        </el-table-column>
        

js:

//获取列表数据
    getList(currentPage = this.currentPage) {
      let data = new URLSearchParams();
      for (let k in this.search) {
          if (this.search[k]) {
            data.append(k, this.search[k]);
          }
        }
      }
      data.append("current", currentPage);
      data.append("size", this.pageSize);
      this.loading = true;
      API.getList(data)
        .then((res) => {
          this.loading = false;
          if (res.code == 200) {
            this.tableData = res.data;
            this.total = res.total;
            this.currentPage = currentPage;
            if(this.tableData && this.tableData.length > 0){
              this.tableData.map(i => {
                this.$set(i,'disposeLoading',false)
              })
            }
          }
        })
        .catch((err) => {
          this.loading = false;
        });
    },
    
    //处理
    dispose(row) {
      let data = new URLSearchParams();
      data.append("sn", row.sn);
      row.disposeLoading = true;
      API.refreshPay(data)
        .then((res) => {
          row.disposeLoading = false;
          if (res.code == 200) {
            this.$message({
              message: "处理成功!",
              type: "success",
              showClose: true,
            });
            this.getList();
          } else {
            this.getList();
          }
        })
        .catch((err) => {
          row.disposeLoading = false;
          this.getList();
        });
    },

复制代码
  • 例:レンダリングは参照用であり、コード例ではありません。

image.png

3.ページングと組み合わせたテーブルテーブルの複数選択は、選択された行のメモリ機能を実現し、テーブルデータと選択されたデータの動的同期更新を実現します。
  • 注:実際のビジネス開発シナリオでは、el-tableは、ページめくりの前後に、選択した行のメモリー機能を保持する必要があることがよくあります。以下に、この要件の解決策のアイデアと方法を示します。

  • 解決策:ページングコンポーネントと組み合わせた要素コンポーネントのテーブルテーブルの選択変更方法を使用して、現在のページのチェック済みデータを保存するための方法と、すべてのチェック済みデータを保存するための方法を定義します(つまり、チェック済みデータは右側に表示されます。データを選択)、および達成するフラグビット。

  • コアコードと説明リンクポータル

2.入力ボックス(el-input)。
1.el-input的change、input事件中传递额外参数的实现。
  • 说明:el-input的change、input事件都是默认传递了一个参数 -- (value: string | number)。但是很多业务场景,我们都是需要在change、input事件中传递自己定义的额外参数。

  • 解决办法:在change、input原有事件中多加一层箭头函数传参即可实现 ---- @change="((val)=>{changeStatus(val, xxx)})"。 (其中,xxx即为所传的自定义参数)。

  • 核心代码:

<template>
  <div class="about">
    <h1>input测试</h1>
    <el-input
      style="width: 300px; margin-top: 50px"
      v-model="value"
      clearable
      placeholder="请输入内容"
      @change="val => changeVal(val,'params')"
    ></el-input>


  </div>
</template>

<script>
export default {
  name: "About",
  data() {
    return {
      value: "",
    };
  },
  methods: {
    changeVal(val,params){
      console.log(val,params);
    }
  },
};
</script>
复制代码
  • 实例:图一为默认效果;图二为加了一层箭头函数的效果。

image.png

image.png

三.选择器(el-select)。
1.el-select的change事件中传递额外参数的实现。
  • 说明:el-select的change事件都是默认传递了一个参数 -- (目前的选中值)。但是很多业务场景,我们都是需要在change事件中传递自己定义的额外参数。

  • 解决办法:在change原有事件中多加一层箭头函数传参即可实现 ---- @change="((val)=>{changeStatus(val, xxx)})"。 (其中,xxx即为所传的自定义参数)。

2.el-select组件的选择项options数据量过大导致页面卡顿时的处理方法。
  • 说明:el-table组件在实际开发中,其内的options选项多为后端接口提供,此时若是数据量庞大(譬如:上万条),那么在用户点开el-select选择器时,会异常卡顿,用户体验感巨差。以下就本需求提供一种解决思路和方法。

  • 解决办法:从总options中取出固定条目的小option(renderOption)用于页面渲染,利用el-select提供的

filter-method方法进行搜索过滤,在搜索时用过滤结果更新renderOption。

四.日期选择器(el-date-picker)。
1.禁用当前日期之前的日期(只能选择今日到今日之后)。
  • 解决:利用el-date-picker的picker-options属性筛选日期。

  • 核心代码:

<el-date-picker
  type="date"
  placeholder="请选择时间"
  :picker-options="pickerOptions"
  v-model="ruleForm.date"
  :clearable="false"
></el-date-picker>
 
pickerOptions: {
    // 限制预约时间
    disabledDate(time) {
      return time.getTime() < Date.now() - 24 * 60 * 60 * 1000
    }
 },
复制代码
2.只能选择今日到未来某时间段的日期范围(此处以3个月90天为例)。
  • 解决:利用el-date-picker的picker-options属性筛选日期。

  • 核心代码:

<el-date-picker
  type="date"
  v-model="ruleForm.date2"
  :picker-options="pickerOptions2"
  placeholder="请选择完成日期"
  :clearable="false"
></el-date-picker>
 
pickerOptions2: {
    // 限制预约时间
    disabledDate(time) {
      return (time.getTime() < Date.now() - 24 * 60 * 60 * 1000) || (time.getTime() > Date.now() + 90 * 24 * 60 * 60 * 1000)
    }
 },
复制代码
五.表单(el-from)。
1.处理el-from组件在v-if、v-show和自增、自减表单项的时候,会出现表单校验异常或者串项的异常。
  • 说明:这里以动态表单为例,处理表单校验异常的情况。

  • 解决办法:为每个el-form-item指定对应且唯一的key属性。

  • 核心代码:

html:

<el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="120px"
      v-loading="loading"
      class="g-form-drawer-main"
    >
      <template v-for="(item, index) in ruleForm.itemList">
        <el-form-item
          label="运营商:"
          :prop="'itemList.' + index + '.carrier'"
          :key="item.key"
          :rules="{
            required: true,
            message: '请选择运营商',
            trigger: ['blur', 'change'],
          }"
        >
          <div class="p-form-content">
            <el-select
              class="w-300 umar-r10"
              v-model="item.carrier"
              placeholder="请选择运营商"
              filterable
              clearable
            >
              <el-option
                v-for="i in comList"
                :key="i.value"
                :label="i.label"
                :value="i.value"
              >
              </el-option>
            </el-select>
          </div>
        </el-form-item>
        <el-form-item
          label="计划套餐:"
          :prop="'itemList.' + index + '.packageId'"
          :key="item.key"
          :rules="{
            required: true,
            message: '请选择计划套餐',
            trigger: ['blur', 'change'],
          }"
        >
          <div class="p-form-content">
            <el-select
              class="w-300 umar-r10"
              v-model="item.packageId"
              placeholder="请先选择运营商后再选择计划套餐"
              filterable
              clearable
            >
              <el-option
                v-for="i in item.packageList"
                :key="i.packageId"
                :label="i.name"
                :value="i.packageId"
              >
              </el-option>
            </el-select>
          </div>
        </el-form-item>
        <div class="p-form-content bottom-box">
            <el-input
              type="textarea"
              style="width: 300px"
              v-model="item.scene"
              placeholder="请输入业务类型"
            ></el-input>
            <el-button
              v-show="index === 0"
              class="p-el-button addbtn"
              type="success"
              icon="el-icon-plus"
              circle
              @click="addProcess"
            ></el-button>
            <el-button
              v-show="ruleForm.itemList && ruleForm.itemList.length > 1"
              class="p-el-button delbtn"
              type="danger"
              icon="el-icon-delete"
              circle
              @click="delProcess(index)"
            ></el-button>
          </div>
       </template>
     </el-form>
     
     
js:

data() {
    return {
      ruleForm: {
        itemList: [
          {
            carrier: "",
            packageId: "",
            packageList: [], 
            key: Date.now()    //确保唯一性
          },
        ],
      },
      comList: [],
      rules: {},
    };
  },
  methods: {
    //新增
    addProcess() {
      const process = {
        carrier: "",
        packageId: "",
        packageList: [],
        key: Date.now()   //确保唯一性
      };
      this.ruleForm.itemList.unshift(process);
    },
    //删除
    delProcess(index) {
      if (this.ruleForm.itemList && this.ruleForm.itemList.length > 1) {
        this.ruleForm.itemList.splice(index, 1);
      } else {
        this.$message({
          message: "至少需保留一个",
          type: "error",
          showClose: true,
        });
      }
    },  
复制代码
  • 实例:图一为未加key值时的效果(校验失常);图二为加了唯一key的效果(正常)。

image.png image.png

  • 体会:el-form动态表单,官方的案例是给每一项el-form-item绑定了key值(:key="domain.key"),不过这里有个问题就是domain对象下的key如果是不存在或者是不唯一的,那么就容易造成动态表单各种翻车,所以解决办法就是改写其中的key绑定的值,必须是要存在且唯一性的。
六.分页(el-pagination)。
1.纯前端分页的实现。
  • 说明:后台不处理分页,只会在请求的时候一下将所有数据一起返回,这时候就需要前端同学自己处理分页了,这里简述为纯前端分页

  • 解决办法:前端发送请求拿到所有数据 → 对该数据进行处理 → 操作分页组件完成效果。

  • 核心代码及讲解链接传送门

おすすめ

転載: juejin.im/post/7079949328143351845