国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

vue自定義表格列的實(shí)現過(guò)程記錄

發(fā)布時(shí)間:2021-08-17 12:16 來(lái)源: 閱讀:0 作者:滄海的雨季 欄目: JavaScript 歡迎投稿:712375056

目錄

前言

在我們開(kāi)發(fā)PC端的項目使用表單時(shí),尤其是crm系統,應該經(jīng)常會(huì )遇到這樣的需求, 用戶(hù)需要根據設置來(lái)自定義顯示列。 查了element的官方文檔, 并沒(méi)有此類(lèi)組件, 所以手動(dòng)封裝了一個(gè)簡(jiǎn)單的組件, 希望能在大家開(kāi)發(fā)此類(lèi)需求時(shí)能夠有所幫助。

效果圖

具體效果圖如下:

自定義顯示列  (可實(shí)現拖拽進(jìn)行排序,點(diǎn)擊選中,再次點(diǎn)擊取消選中)

按照用戶(hù)已設置好的字段排序/顯示/隱藏每一列

setTable組件

首先實(shí)現拖拽排序的話(huà)我們需要借助一個(gè)插件:

npm install vuedraggable -S

具體的組件代碼如下, 代碼內已寫(xiě)有詳細的注釋?zhuān)谶@里就不過(guò)多贅述了。。

  setTable.vue

<template>
  <div>
    <el-dialog title="自定義顯示列" :visible.sync="dialogVisible" width="50%">
      <div class="select-menus menus-box">
        <p class="menus-title">拖動(dòng)區塊調整顯示順序</p>
        <div class="menus-content">
          <draggable v-model="selected" @update="datadragEnd" :options="{animation:500}">
            <transition-group>
              <div v-for="menu in selected" :key="menu.field" class="drag-item item">{{menu.name}}</div>
            </transition-group>
          </draggable>
        </div>
      </div>
      <div class="menus-container menus-box" v-if="fields.length">
        <p class="menus-title">選擇顯示列</p>
        <div class="menus-content">
          <div
            class="item"
            :class="{active:menu.active}"
            v-for="menu of fields"
            :key="menu.field"
            @click="onSelect(menu)"
          >{{menu.name}}</div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="onSave">確 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import draggable from "vuedraggable";
import { getFields, setFields, getFieldControl } from "@/api/user";
export default {
  name: "setTable",
  inject: ["reload"],
  props: {
    types: String,
  },
  components: {
    draggable,
  },
  data() {
    return {
      dialogVisible: false,
      fields: [],//全部菜單
      selected: [],//已選中菜單
    };
  },
  watch: {
    selected: {
      handler(oldVal, newVal) {
        if (this.fields.length === 0) {
          return;
        }
        newVal.map((i) => {
          this.fields.map((j) => {
            if (i.field === j.field) {
              // 如果已選中數組內已有相同字段, 則active為true。active主要用來(lái)控制全部菜單選中/未選中的樣式
              j.active = true;
            }
          });
        });
      },
    },
  },
  mounted() {
    //為了防止火狐瀏覽器拖拽的時(shí)候以新標簽打開(kāi)
    document.body.ondrop = function (event) {
      event.preventDefault();
      event.stopPropagation();
    };
  },
  methods: {
    async getData() {
      // 獲取全部菜單數據
      const { data: fields } = await getFields({
        types: this.types,
      });
      fields.map((item) => {
        // 由于服務(wù)器并沒(méi)有返回active字段, 為此需要每一條數據增加active字段, 來(lái)控制選中的樣式
        item.active = false;
      });
      this.fields = fields;
    },
    async getFields() {
      // 獲取用戶(hù)已選中的菜單, 為了再次打開(kāi)設置時(shí)能夠把上次選中菜單回顯到頁(yè)面,方便用戶(hù)再次修改
      let fields = await getFieldControl({
        account_id: this.$store.state.user.token.account_id,
        userid: this.$store.state.user.token.userid,
        types: this.types,
      });
      this.$nextTick(() => {
        this.selected.push(...fields.data);
      });
    },
    async onSave() {
      // 保存已選中菜單
      await setFields({
        account_id: this.$store.state.user.token.account_id,
        userid: this.$store.state.user.token.userid,
        types: this.types,
        content: this.selected,
      });
      this.reload(); //刷新頁(yè)面
    },
    async open() {
      // 打開(kāi)設置窗口時(shí)清空數據,并再次請求獲取最新數據
      this.fields = [];
      this.selected = [];
      this.dialogVisible = true;
      await this.getData();
      await this.getFields();
    },
    onSelect(item) {
      // 判斷已選中菜單內是否已有點(diǎn)擊選擇的菜單
      let findex = this.selected.findIndex((i) => {
        return item.field === i.field;
      });
      if (findex === -1) {
        // 如果已選中菜單內沒(méi)有, 則添加到最后一條
        this.selected.push(item);
      } else {
        // 如果已選中已有,則點(diǎn)擊時(shí)應該對其移除,并把active設置為false, 改變其選中的樣式
        item.active = false;
        this.selected.splice(findex, 1);
      }
    },
    datadragEnd(evt) {
      // 拖動(dòng)排序
      evt.preventDefault();
    },
  },
};
</script>
<style lang="scss" scoped>
/* 全部菜單 */
.menus-container {
  margin-top: 20px;
  .menus-content {
    .item {
      color: #575757;
      background: rgba(238, 238, 238, 1);
      border: 1px solid rgba(220, 220, 220, 1);
      border-radius: 2px 0px 0px 2px;
    }
  }
}
/* 菜單通用樣式 */
.menus-box {
  .menus-title {
    margin-top: 10px;
    line-height: 32px;
  }
  .menus-content {
    display: flex;
    flex-wrap: wrap;
    .item {
      cursor: pointer;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 8px;
      margin: 10px;
      border-radius: 3px;
    }
    .active {
      color: #fff;
      background: rgba(72, 153, 229, 1);
      border-radius: 2px 0px 0px 2px;
    }
  }
}

/* 已選菜單 */
.select-menus {
  .menus-content {
    .item {
      margin: 0px;
      border-radius: 0;
      background: rgba(255, 255, 255, 1);
      border: 1px solid rgba(220, 220, 220, 1);
    }
  }
}
</style>

使用

具體使用如下, 在這里已經(jīng)隱去不必要的業(yè)務(wù)代碼, 只把最核心實(shí)現的代碼貼了出來(lái), 以免對大家產(chǎn)生誤導..

<template>
  <div>
    <el-table
      ref="multipleTable"
      :data="tableData"
      height="60vh"
      :row-class-name="tableRowClassName"
      @selection-change="handleSelectionChange"
      @row-click="handleRead"
    >
      <el-table-column type="selection" min-width="55px;"></el-table-column>
      <template v-for="(item,index) of fields">
        <el-table-column
          v-if="item.field==='name'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='gender'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="8%;"
          show-overflow-tooltip
        >
          <template slot-scope="scope">{{scope.row.gender===1?'男':'女'}}</template>
        </el-table-column>
        <el-table-column
          v-if="item.field==='corp_full_name'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="14%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='corp_name'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="12%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='up_date'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="14%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='position'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='remark_mobiles'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="14%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='source_name'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='address'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='detail_address'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='description'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='remark'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='recordContent'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="14%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='owner_name'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          v-if="item.field==='follow_time'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="8%;"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <div v-if="scope.row.follow_time===scope.row.createtime">暫無(wú)</div>
            <div v-else>{{scope.row.follow_time | formatDate}}</div>
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.field==='next_follow_time'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="8%;"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <div v-if="scope.row.next_follow_time===0">暫無(wú)</div>
            <div v-else>{{scope.row.next_follow_time | formatDate}}</div>
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.field==='createtime'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="8%;"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <div>{{scope.row.createtime | formatDate}}</div>
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.field==='updatetime'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="8%;"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <div>{{scope.row.updatetime | formatDate}}</div>
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.field==='is_record'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <div>{{scope.row.is_record === 0 ? '未跟進(jìn)' : '已跟進(jìn)' }}</div>
          </template>
        </el-table-column>
        <el-table-column
          v-if="item.field==='if_record'"
          :key="index"
          :prop="item.field"
          :label="item.name"
          min-width="10%;"
          show-overflow-tooltip
        ></el-table-column>
      </template>
      <el-table-column label="操作" min-width="8%;">
        <template slot-scope="scope">
          <el-button @click="handleRead(scope.row)" type="text">詳情</el-button>
        </template>
      </el-table-column>
      <el-table-column align="right" min-width="4%;">
        <template slot="header">
          <i class="iconfont icongengduo" @click="onMore"></i>
        </template>
      </el-table-column>
    </el-table>
    <set-table ref="setting" types="leads"></set-table>
  </div>
</template>

<script>
import setTable from "@/components/setTable";
import { getFieldControl } from "@/api/user";
export default {
  name: "clues",
  components: {
    setTable,
  },
  data() {
    return {
      fields: [],
    };
  },
  async mounted() {
    await this.getFields();
    this.clues();
  },
  methods: {
    async getFields() {
      let fields = await getFieldControl({
        account_id: this.$store.state.user.token.account_id,
        userid: this.$store.state.user.token.userid,
        types: "leads",
      });
      this.fields = fields.data;
    },
    onMore() {
      this.$refs.setting.open();
    },
  },
};
</script>

在這里其實(shí)也可以設置成固定的列寬或者通過(guò)服務(wù)器返回具體的尺寸, 這樣的話(huà)就不用寫(xiě)這么多的if語(yǔ)句了, 會(huì )更加方便簡(jiǎn)潔..

結束語(yǔ)

其實(shí)剛接到這個(gè)需求時(shí),感覺(jué)挺復雜的, 尤其是需要進(jìn)行拖動(dòng), 還要根據服務(wù)器返回不同的字段來(lái)進(jìn)行表單列的排序。  但整體做下來(lái)并沒(méi)有我想象的那么麻煩。 大家在遇到需求時(shí), 也一定不要一直想的太多, 一定要先去嘗試, 說(shuō)不定它并沒(méi)有你想的那么難..

到此這篇關(guān)于vue自定義表格列的文章就介紹到這了,更多相關(guān)vue自定義表格列內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

国产免费无遮挡吸乳视频在线观看| 在线 | 国产精品99传媒A| 欧美在线 | 亚洲| 欧美老熟妇乱子伦视频| 亚洲午夜精品久久久久久人妖 | 国产精品久久久久久影视|