Vue ElementUI 实现二级复选框列表思路是否可行?

功能描述:从下拉框"Service(服务)","ServiceInstances (服务实例)","Endpoints(端点)"三个数据源获取数据,然后在下面的二级复选框列表展示,最终获得用户选取的数据.

(1).ServiceInstances (服务实例)和 Endpoints(端点)是用 Service(服务)key查出来的.

(2).所以Service(服务)只有一级数据,ServiceInstances (服务实例)和 Endpoints(端点)有二级数据.

问题:
1.拼接dataEndPoints数据格式是否合理
2.如何实现2级动态绑定取值

在线demo:
https://codesandbox.io/s/kind...

一.数据描述:

1.Service(服务)返回数据:

{
    "data": {
        "services": [
            {
                "key": "aXN0aW86OmlzdGlvZA==.1",
                "label": "istio::istiod",
                "group": "istio"
            },
            {
                "key": "aXN0aW86OmlzdGlvLWVncmVzc2dhdGV3YXk=.1",
                "label": "istio::istio-egressgateway",
                "group": "istio"
            }]
           }
}

2.ServiceInstances (服务实例)返回数据,[查询参数需要Service(服务)的key]:

{
    "data": {
        "getServiceInstances": [
            {
                "key": "aXN0aW8tZHA6OmN1cnJlbmN5c2VydmljZQ==.1_Y3VycmVuY3lzZXJ2aWNlLTVkNWQ0OTY5ODQtdGQ1YzI=",
                "label": "currencyservice-5d5d496984-td5c2",
                "language": "UNKNOWN",
                "attributes": []
            }
        ]
    }
}

3.Endpoints(端点)返回数据[查询参数需要Service(服务)的key]:

{
    "data": {
        "getEndpoints": [
            {
                "key": "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL1NoaXBPcmRlcg==",
                "label": "POST:/hipstershop.ShippingService/ShipOrder"
            },
            {
                "key": "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL0dldFF1b3Rl",
                "label": "POST:/hipstershop.ShippingService/GetQuote"
            }
        ]
    }
}

二.HTML代码部分:

  <el-container>
    <el-main>
      <el-form ref="form" label-width="100px" style="margin: 0 0 100px 0">
      </el-form>
      <el-row>
        <el-col :span="3">
          <el-button type="success" @click="dialogFormIndividualRulesVisible = true">新增单独配置</el-button>
        </el-col>
        <!-- 新增单独配置弹出Form -->
        <el-dialog
          title="新增单独配置"
          :visible.sync="dialogFormIndividualRulesVisible"
          width="80%"
          class="titleH1"
        >
          <el-form
            :model="formIndividualData"
            ref="formIndividualData"
            :rules="formIndividualRules"
          >
            <label for class="titleH2">关联资源</label>
            <el-form-item label="资源项" prop="resources" :label-width="formLabelWidth">
              <el-select
                v-model="formIndividualData.resources.label"
                @change="getSkywalkingResourcesData"
                placeholder="请选择资源项"
              >
                <el-option
                  v-for="item in formIndividualData.resources"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>


            <label for class="titleH2">告警对象</label>
            <el-form-item label="选择服务" :label-width="formLabelWidth">
              <div style="display: flex;">
                <el-table
                  ref="multipleTable"
                  :data="tableDataAlarmObject"
                  tooltip-effect="dark"
                  style="width: 40%"
                  border
                  height="200"
                  :header-cell-style="{
                                        'background-color': '#add5fd',
                                        'color': 'rgb(255, 255, 255)',
                                    }"
                  @selection-change="handleSelectionChange1"
                >
                  <el-table-column type="selection" width="55"></el-table-column>
                  <el-table-column prop="label" label="服务名称">
                    <template slot="header" slot-scope="scope">
                      <el-input
                        @input="searchChange1"
                        v-model="search"
                        size="mini"
                        placeholder="输入关键字搜索"
                      />
                    </template>
                  </el-table-column>
                </el-table>

                <el-table
                  ref="multipleTable2"
                  :data="tableDataChildAlarmObject"
                  tooltip-effect="dark"
                  style="width: 40%"
                  border
                  height="200"
                  :header-cell-style="{
                                        'background-color': '#add5fd',
                                        'color': 'rgb(255, 255, 255)',
                                    }"
                >
                  <el-table-column type="selection" width="55"></el-table-column>
                  <el-table-column prop="label" label="服务名称"></el-table-column>
                </el-table>
              </div>
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="dialogFormIndividualRulesVisible = false">取 消</el-button>
            <el-button type="primary" @click="dialogIndividualRules(formIndividualData)">确 定</el-button>
          </div>
        </el-dialog>
      </el-row>

    </el-main>
  </el-container>

三.TS部分:

<script lang="ts">

import { Component, Vue } from "vue-property-decorator";

type AlarmObjectForm = {
  checked?: boolean;
};

@Component({
  components: {

  }
})
export default class ConfigurationList extends Vue {

  private dialogFormIndividualRulesVisible: boolean = false;
  private dialogFormCompositeRulesVisible: boolean = false;
  private formIndividualData: any = {
    resources: [
      { label: "服务", value: "graphql/1" },
      { label: "服务实例", value: "/graphql/2" },
      { label: "端点", value: "/graphql/3" }
    ],
    ruleName: "",
    norm: [
      { label: "p95", value: "p95" },
      { label: "p75", value: "p75" },
      { label: "p55", value: "p55" }
    ],
    rule: "",
    operation: "",
    num1: 0,
    checked: false,
    num2: 0,
    num3: 0
  };

  private formLabelWidth: string = "120px";
  private num: number = 1;
  private checked: boolean = false;
  private search: string = "";
  private searchFlag: boolean = false;
  private tableDataAlarmObject: Array<AlarmObjectForm> = [];
  private tableDataChildAlarmObject: Array<AlarmObjectForm> = [];
  // Service 下的 EndPoints 合并数据(格式是否合理?)
  private dataEndPoints: Array<any> = [
    {
      key: "aXN0aW86OmNhcnRzZXJ2aWNl.1",
      label: "istio::cartservice",
      group: "istio",
      getEndpoints: [
        {
          key:
            "aXN0aW86OmNhcnRzZXJ2aWNl.1_UE9TVDovaGlwc3RlcnNob3AuQ2FydFNlcnZpY2UvR2V0Q2FydA==",
          label: "POST:/hipstershop.CartService/GetCart"
        },
        {
          key:
            "aXN0aW86OmNhcnRzZXJ2aWNl.1_UE9TVDovaGlwc3RlcnNob3AuQ2FydFNlcnZpY2UvRW1wdHlDYXJ0",
          label: "POST:/hipstershop.CartService/EmptyCart"
        }
      ]
    },
    {
      key: "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1",
      label: "istio-dp::ratings",
      group: "istio-dp",
      getEndpoints: [
        {
          key:
            "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL1NoaXBPcmRlcg==",
          label: "POST:/hipstershop.ShippingService/ShipOrder"
        },
        {
          key:
            "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL0dldFF1b3Rl",
          label: "POST:/hipstershop.ShippingService/GetQuote"
        }
      ]
    },
    {
      key: "aXN0aW8tZHA6OnJlY29tbWVuZGF0aW9uc2VydmljZQ==.1",
      label: "istio-dp::recommendationservice",
      group: "istio-dp",
      getEndpoints: [
        {
          key:
            "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL1NoaXBPcmRlcg==",
          label: "POST:/hipstershop.ShippingService/ShipOrder"
        },
        {
          key:
            "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL0dldFF1b3Rl",
          label: "POST:/hipstershop.ShippingService/GetQuote"
        }
      ]
    },
    {
      key: "aXN0aW8tZHA6OnByb2R1Y3RwYWdl.1",
      label: "istio-dp::productpage",
      group: "istio-dp",
      getEndpoints: [
        {
          key:
            "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL1NoaXBPcmRlcg==",
          label: "POST:/hipstershop.ShippingService/ShipOrder"
        },
        {
          key:
            "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL0dldFF1b3Rl",
          label: "POST:/hipstershop.ShippingService/GetQuote"
        }
      ]
    }
  ];
  // Service 下的 ServiceInstances 合并数据
  private dataServiceInstances: Array<any> = [];
  private multipleSelection: Array<any> = [];
  private skyWalkingUrl: string = "";

  private temEndPoints: Array<any> = [];

  private addButtonHide: boolean = true;

  handleChange(value: any) {
    console.log(value);
  }

  created() {
    this.tableDataAlarmObject = [...this.dataEndPoints]; // 保持源数组的独立性,
    console.log(this.tableDataAlarmObject);
  }

  /**
   * 新建告警配置-选择服务复选框
   */
  handleSelectionChange1(val: any) {
    if (this.searchFlag) {
      // 手动选中过程中不予响应
      return;
    }
    this.tableDataAlarmObject.forEach(item => {
      item.checked = false;
    });
    val.forEach((row: any) => {
      row.checked = true;
    });
    console.log("val-->", val);


    let arr: Array<any> = [];
    for (let i in val) {
      const getEndpoints = (val[i] as any).getEndpoints.map((item: any) => {
        item.p_key = (val[i] as any).key;
        return item;
      });
      this.tableDataChildAlarmObject = arr.concat(getEndpoints);
    }
  }

  /**
   * 新建告警配置-选择服务-复选框搜索
   */
  searchChange1() {
    var arr = this.dataEndPoints.filter(
      data =>
        !this.search ||
        data.label.toLowerCase().includes(this.search.toLowerCase())
    );
    this.tableDataAlarmObject.splice(0, this.tableDataAlarmObject.length);
    Array.prototype.push.apply(this.tableDataAlarmObject, arr); // 不改变tableDataAlarmObject 数组的引用地址。保持其响应式。

    this.$nextTick(() => {
      this.searchFlag = true; // 手动选中前 禁止多选事件响应
      this.tableDataAlarmObject.forEach(item => {
        if (item.checked)
          (this.$refs.multipleTable as any).toggleRowSelection(item, true);
      });
      this.searchFlag = false; // 放开多选事件响应
    });
  }

  /**
   * 获取新增单独规则关联资源项的数据
   */
  getSkywalkingResourcesData(url: string) {
    console.log(url);
  }

  dialogIndividualRules(formIndividualData: any) {
    let individualData: any = this.$refs.formIndividualData;
    individualData.validate((valid: any) => {
      if (valid) {
        alert("submit!");
        this.dialogFormIndividualRulesVisible = false;
      } else {
        console.log("error submit!!");
        return false;
      }
    });
  }

}
</script>
阅读 1.3k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题