Vue2 加 element级联组件 实现 动态添加删除 列表

DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Documenttitle>
   <link
      rel="stylesheet"
      href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
    />
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.13/vue.js">script>
    <script src="https://cdn.jsdelivr.net/npm/@unocss/runtime">script>
    <script src="https://unpkg.com/element-ui/lib/index.js">script>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      .del_box:hover .del {
        display: block;
      }
      .del {
        display: none;
      }
    style>
  head>
  <body>
    <div id="app" class="h-100vh flex justify-center items-center">
      <div>
        <div class="flex flex-wrap gap-20px mb-20px">
          <div
            v-for="attr in attrs"
            @click="changeAttr(attr)"
            :class="[
             attr.id == bind_ids ? 'leading-40px !bg-#0fa3ff !border-none !text-#ffffff' : 'leading-40px text-14px text-#000000 bg-#F2F3F5',
           ]"
            class="px-15px rounded-4px w-max h-40px text-14px cursor-pointer relative del_box"
          >
            <span>{{attr.attr}}span>
            <i
              class="el-icon-close absolute top-1px right-2px cursor-pointer del"
              @click.stop="delAttr(attr.id)"
            >i>
          div>
        div>
        <div class="flex flex-wrap gap-20px rounded-5px">
          <div
            v-for="item in getMaterialList"
            class="w-max h-32px border-#E9E9E9 border-1px border-solid flex items-center text-#303133 rounded-4px"
          >
            <div class="w-90px text-center line-clamp-1 px-5px">
              {{item.name}}
            div>
            <el-input
              v-model="item.num"
              class="material_inp !w-80px"
              size="small"
              placeholder="编码"
            >el-input>
          div>

          <el-cascader
            v-if="isAddShow"
            class="!w-300px"
            size="small"
            v-model="bindVal"
            collapse-tags
            :options="options"
            clearable
            :props="{ expandTrigger: 'hover', multiple: true ,emitPath:false }"
            @change="changeVal"
            @visible-change="visibleChange"
          >el-cascader>
          <div
            v-else
            @click="isAddShow = !isAddShow"
            class="h-32px w-60px text-#0FA3FF rounded-4px cursor-pointer border-#0FA3FF border-1px border-dashed leading-30px text-center"
          >
            +
          div>
        div>
      div>
    div>
    <script>
      new Vue({
        el: '#app',
        data() {
          return {
            bindVal: [],
            list: [],
            bind_ids: 100,
            isAddShow: false,
            attrs: [
              {
                attr: '校园',
                id: 100,
              },
              {
                attr: '异世界',
                id: 200,
              },
            ],
            options: [
              {
                value: 1,
                label: '青春猪头',
                children: [
                  {
                    value: 11,
                    label: '麻衣',
                  },
                  {
                    value: 12,
                    label: '咲太',
                  },
                ],
              },
              {
                value: 2,
                label: '无职转生',
                children: [
                  {
                    value: 21,
                    label: '卢迪',
                  },
                  {
                    value: 22,
                    label: '艾丽斯',
                  },
                ],
              },
            ],
          };
        },
        computed: {
          getMaterialList() {
            let arr = [];
            arr = this.list.filter((e) => e.attr_id == this.bind_ids);

            if (arr && arr != 0) {
              return arr;
            } else {
              return [];
            }
          },
        },
        methods: {
          visibleChange(e) {
            if (!e) {
              this.isAddShow = false;
            }
          },
          changeAttr(item) {
            this.bind_ids = item.id;
            if (this.getMaterialList == 0) {
              this.bindVal = [];
            } else {
              this.bindVal = this.getMaterialList.map((e) =>
                Number(e.stock_id)
              );
            }
          },
          delAttr(id) {
            this.list = this.list.filter((e) => e.attr_id != id);
            if (id == this.bind_ids) {
              this.bindVal = [];
            }
          },
          changeVal(val) {
            if (val == 0) {
              this.list = this.list.filter((e) => e.attr_id != this.bind_ids);
            } else {
              let list = [];
              this.options.map((v) => {
                v.children.forEach((child) => {
                  if (val.find((e) => e == child.value)) {
                    list.push(child);
                  }
                });
              });
              let newList = list.map((e) => {
                let item = {
                  stock_id: e.value,
                  name: e.label,
                  num: 1,
                  attr_id: this.bind_ids,
                };
                return item;
              });

              let jieguo = this.updateArray(this.getMaterialList, newList);

              this.list = this.list.filter((e) => e.attr_id != this.bind_ids);
              this.list.push(...jieguo);
            }
          },

          updateArray(arr, newValue) {
            const ids = arr.map((item) => item.stock_id);
            let newArr = newValue.map((e) => {
              if (ids.includes(e.stock_id)) {
                let num = arr.find((v) => v.stock_id == e.stock_id).num;
                e.num = num;
              }
              return {
                ...e,
              };
            });
            return newArr;
          },
        },
      });
    script>
  body>
html>

你可能感兴趣的:(vue,unocss)