element-ui使用过程遇到的坑(2)—— table组件中的表格嵌套Select组件

在使用Table组件的时候,我想在表格的每一行的对应列都添加一个下拉框Select,如图所示。

但是这样会出现一个问题,我们先看一下代码


很显然,如果我们在某一个下拉框里面选择了其中的某个选项,那么其他下拉框也会被自动选上,因为此时所有的下拉框的
v-model绑定的都是同一个value。
 

实际上,我们想要的效果是每个下拉框都能够独立的去选择,而不会影响到其他的下拉框。

因此,在table组件中,有一个<template slot-scope="scope"></template>,这个模板有一个slot-scope属性,这个属性的作用,等同于我们在给每个组件写CSS的时候,都会加上scoped的作用是一样的。也就是说,使用这样的一个模板,就能够让每一个下拉框都是独立的互不干扰的,但是我们需要做一些相应的改变。我们来看修改后的代码

注意,这里我们将v-model="value"改成了v-model="scope.row.value",我们知道下拉框的v-model绑定的值是我们选中的那一个选项,而这个scope.row,表示的意思是当前被选择的这一行的下拉框的选项,由于我们加了scope,就会让这个被选择的选项,也就是这个value它是唯一的,并不会影响到其他的下拉框。

所以最后,我们通过给下拉框塞进<template slot-scope="scope"></template>中,将v-model修改一下,就能够实现我们想要的效果了。

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
ElementUItable 组件提供了非常丰富的功能和接口,但是在实际项目,我们经常需要对其进行二次封装,以满足自己的业务需求。下面是一个简单的 ElementUI table 的二次封装示例: ```vue <template> <el-table :data="tableData" :height="height" :max-height="maxHeight" :stripe="stripe" :border="border" :fit="fit" :show-header="showHeader" :highlight-current-row="highlightCurrentRow" :row-class-name="rowClassName" :row-style="rowStyle" :cell-class-name="cellClassName" :cell-style="cellStyle" :header-row-class-name="headerRowClassName" :header-row-style="headerRowStyle" :header-cell-class-name="headerCellClassName" :header-cell-style="headerCellStyle" :row-key="rowKey" @select="handleSelect" @select-all="handleSelectAll" @selection-change="handleSelectionChange" @cell-mouse-enter="handleCellMouseEnter" @cell-mouse-leave="handleCellMouseLeave" @cell-click="handleCellClick" @cell-dblclick="handleCellDblClick" @row-click="handleRowClick" @row-contextmenu="handleRowContextMenu" @row-dblclick="handleRowDblClick" @header-click="handleHeaderClick" @header-contextmenu="handleHeaderContextMenu" @sort-change="handleSortChange" @filter-change="handleFilterChange" > <slot></slot> </el-table> </template> <script> export default { name: "MyTable", props: { tableData: { type: Array, default: () => [] }, height: { type: [Number, String], default: "" }, maxHeight: { type: [Number, String], default: "" }, stripe: { type: Boolean, default: true }, border: { type: Boolean, default: true }, fit: { type: Boolean, default: true }, showHeader: { type: Boolean, default: true }, highlightCurrentRow: { type: Boolean, default: true }, rowClassName: { type: Function, default: () => undefined }, rowStyle: { type: Function, default: () => undefined }, cellClassName: { type: Function, default: () => undefined }, cellStyle: { type: Function, default: () => undefined }, headerRowClassName: { type: Function, default: () => undefined }, headerRowStyle: { type: Function, default: () => undefined }, headerCellClassName: { type: Function, default: () => undefined }, headerCellStyle: { type: Function, default: () => undefined }, rowKey: { type: [String, Function], default: "" } }, methods: { handleSelect(selection, row) { this.$emit("select", selection, row); }, handleSelectAll(selection) { this.$emit("select-all", selection); }, handleSelectionChange(selection) { this.$emit("selection-change", selection); }, handleCellMouseEnter(row, column, cell, event) { this.$emit("cell-mouse-enter", row, column, cell, event); }, handleCellMouseLeave(row, column, cell, event) { this.$emit("cell-mouse-leave", row, column, cell, event); }, handleCellClick(row, column, cell, event) { this.$emit("cell-click", row, column, cell, event); }, handleCellDblClick(row, column, cell, event) { this.$emit("cell-dblclick", row, column, cell, event); }, handleRowClick(row, event, column) { this.$emit("row-click", row, event, column); }, handleRowContextMenu(row, event) { this.$emit("row-contextmenu", row, event); }, handleRowDblClick(row, event) { this.$emit("row-dblclick", row, event); }, handleHeaderClick(column, event) { this.$emit("header-click", column, event); }, handleHeaderContextMenu(column, event) { this.$emit("header-contextmenu", column, event); }, handleSortChange({ column, prop, order }) { this.$emit("sort-change", { column, prop, order }); }, handleFilterChange(filters) { this.$emit("filter-change", filters); } } }; </script> ``` 这里我们定义了一个名为 `MyTable` 的组件,并将其 props 与 ElementUI table 组件的 props 一一对应。在组件的模板,我们使用了 `<slot></slot>`,表示组件的插槽,这样可以让用户在使用组件时自定义表格的列和内容。在组件的方法,我们将 ElementUI table 的事件通过 `$emit` 的方式向上传递,这样可以使得组件使用更加灵活。 使用这个组件时,我们只需要在父组件引入 `MyTable` 组件,并将需要的 props 和插槽传入即可: ```vue <template> <my-table :table-data="tableData" :stripe="false" :highlight-current-row="false" @row-click="handleRowClick" > <el-table-column label="姓名" prop="name"></el-table-column> <el-table-column label="年龄" prop="age"></el-table-column> <el-table-column label="地址" prop="address"></el-table-column> </my-table> </template> <script> import MyTable from "@/components/MyTable"; export default { name: "MyPage", components: { MyTable }, data() { return { tableData: [ { name: "张三", age: 18, address: "北京市" }, { name: "李四", age: 20, address: "上海市" }, { name: "王五", age: 22, address: "广州市" } ] }; }, methods: { handleRowClick(row) { console.log(row); } } }; </script> ``` 这样,我们就完成了一个简单的 ElementUI table 的二次封装,并且可以在父组件灵活使用
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值