vue table的多选(简单购物车)

本文介绍了一个基于Vue.js的简易购物车应用实现过程。通过前端Vue技术实现商品展示、选择及购买流程,配合后端MyBatis操作MySQL数据库完成订单处理。文章详细展示了前端Vue组件配置与交互逻辑、后端接口设计及数据库操作。

做一个简单购物车的小例子。

数据库使用mysql。其中有三个表

product(商品表)

orders(订单表)

 orderitem(订单详情表)

在前台我们使用vue来实现页面的展示。

直接上代码

在vue中table的多选只需要加type即可。

<el-table-column
          label="购买"
          type="selection"
      >

在el-table中定义一个@selection-change的方法

<el-table
        :data="tableData"
        @selection-change="handleSelectionChange"
    >

 在方法中拿到的值val便是这一行的对象

 handleSelectionChange (val) {
      this.list = val;
    }

 给了list后拿到,其中数组每一个存储的便是对象,因此我们应该循环取出,其中的id,送到后台

 for (let i = 0; i<this.list.length; i++){
          this.objList[i] = this.list[i].id;
        }

 整体代码如下:

<template>
  <div>
    <h2>{{msg}}</h2>
    <el-table
        :data="tableData"
        @selection-change="handleSelectionChange"
    >
      <el-table-column
          prop="id"
          label="编号"
          width="180">
      </el-table-column>
      <el-table-column
          prop="name"
          label="商品"
          width="180">
      </el-table-column>
      <el-table-column
          prop="price"
          label="价格"
          width="180">
      </el-table-column>
      <el-table-column
          prop="pdescs"
          label="描述">
      </el-table-column>

      <el-table-column
          label="购买"
          type="selection"
      >
      </el-table-column>
    </el-table>
    <el-button @click="selectAll">购买</el-button>
  </div>
</template>

<script>
export default {
  name: "shop",
  data(){
    return{
      msg: '商店页面',
      tableData: [],
      list:[
        {id:''}
      ],
      objList:[],
    }
  },
  methods:{
    findAll(){
      this.$http.get("/list")
          .then(resp=>{
            this.tableData = resp.data.data;
          })
          .catch((e) => {});
    },
    selectAll(){
      if (this.list.length==0){
        alert("请选择要购买的商品")
      }else{
        for (let i = 0; i<this.list.length; i++){
          this.objList[i] = this.list[i].id;
        }
        this.$http.get("/buy/"+this.objList)
            .then(resp=>{
              console.log(resp.data.flag);
              if (resp.data.flag){
                this.$router.push('/orderList');
              }
            })
            .catch((e) => {});
      }
    },
    handleSelectionChange (val) {
      this.list = val;
    }
  },
  created() {
    this.findAll();
  }

}
</script>

后台代码

利用mybatisX插件反向生成后,创建controller其中如此写。

简单购物车便做好了。

@RestController
@CrossOrigin
public class ShopController {

    @Resource
    private ProductService productService;
    @Resource
    private OrderitemService orderitemService;
    @Resource
    private OrdersService ordersService;


    /**
     * 返回商品list
     * @return
     */
    @GetMapping("/list")
    public Result findAll(){
        return new Result(200,true,"查询商品成功",this.productService.list());
    }
    /**
     * buy
     */
    @GetMapping("/buy/{list}")
    public Result findJ(@PathVariable String list){
        if (list.length()==0){
            return new Result(200,false);
        }else{
            System.out.println("得到的id------>"+list);
            //时间戳
            String time =  String.valueOf(System.currentTimeMillis());
            System.out.println(time);
            //总金额
            Integer money = 0;


            // 根据,(逗号)进行分割
            String[] its = list.split(",");
            for(int i = 0; i < its.length; i++) {
                Integer it = Integer.valueOf(its[i]);
                Orderitem orderitem = new Orderitem();
                orderitem.setOldernumber(time);
                orderitem.setPid(it);
                this.orderitemService.save(orderitem);

                //拿到每一个价格
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("id",it);
                Product one = this.productService.getOne(queryWrapper);
                money+=one.getPrice();
            }
            Orders orders = new Orders();
            orders.setOrdernumber(time);
            orders.setTotalprice(money);
            //存入订单表
            this.ordersService.save(orders);
            return new Result(200,true);
        }

    }

}

<think> 我们面对的问题是:在Vue项目中,当table组件支持时,如何通过ref获取当前点击行的行号(索引)? 根据之前的讨论,我们知道在Element UI的表格中,通常有两种方式获取行号: 1. 使用slot-scope="scope"的方式,通过scope.$index直接获取(推荐)。 2. 通过ref获取表格实例,然后结合行数据匹配索引。 但是,现在用户特别强调“通过ref获取当前点击行的行号”,并且是在支持的表格中(即表格有selection列)。 考虑以下情况: - 用户可能点击了表格行的任意位置(包括框所在列),而我们想要知道点击的是哪一行。 - 注意:在表格中,用户点击框时,会触发择事件,但同时我们可能也需要知道点击的行号。 然而,Element UI的表格并没有直接提供通过ref获取当前点击行号的方法。因此,我们需要结合事件处理。 解决方案: 1. 我们可以给表格行添加点击事件(row-click事件),在事件处理函数中获取行号。 2. 或者,在操作按钮的点击事件中获取(此时需要将行号传递出来)。 但是,用户要求通过ref获取,那么我们可以考虑: - 在row-click事件中记录当前点击的行号,然后通过ref暴露出去?或者直接使用ref来访问表格的某个属性?这需要自定义。 然而,Element UI的表格ref本身并不存储当前点击行的行号。 因此,我们可以这样实现: - 在表格上监听row-click事件,将点击的行数据以及行索引存储到组件的data中(例如currentRowIndex)。 - 然后,我们可以通过ref访问该组件,进而访问currentRowIndex。 但是,这样只能记录最后一次点击的行号。而且,如果用户同时点击了个行(比如),那么我们需要的是个行号?这里题目要求是“当前点击行”,所以应该是单次点击的行。 另外,用户可能点击的是操作列中的按钮,而不是行本身。所以我们需要明确需求:是点击行任意位置都算,还是特指操作按钮? 鉴于用户上一次的问题中提到的“当前点击行”,以及引用[2]中提到的操作按钮获取当前行元素,我们可以推断用户可能在操作按钮上需要行号。 因此,我们分两种情况讨论: 情况一:用户点击的是操作按钮(例如删除、编辑按钮) - 这种情况下,我们可以在按钮的点击事件中传递scope.$index(如方法1),这样就不需要通过ref去获取。 情况二:用户要求通过ref获取任意点击的行(包括点击行任意位置) - 我们可以使用row-click事件来记录当前点击的行索引。 但是,用户明确要求“通过ref获取”,所以我们需要设计一个方案,使得外部可以通过ref访问到当前点击的行号。 示例代码: ```vue <template> <el-table ref="myTable" :data="tableData" @row-click="handleRowClick" > <el-table-column type="selection" width="55"></el-table-column> <el-table-column prop="date" label="日期"></el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <el-button @click="handleButtonClick(scope.$index, scope.row)">按钮</el-button> </template> </el-table-column> </el-table> </template> <script> export default { data() { return { tableData: [/* 数据 */], currentRowIndex: null, // 记录当前点击的行索引 }; }, methods: { handleRowClick(row, column, event) { // 当点击行时,记录行索引(注意:这里的索引是当前页的索引) const index = this.tableData.indexOf(row); this.currentRowIndex = index; }, handleButtonClick(index, row) { // 点击按钮时,记录行索引 this.currentRowIndex = index; // 同时执行其他操作 }, }, // 通过ref暴露currentRowIndex // 注意:在Vue2中,我们无法直接通过ref访问组件的data属性,除非使用this.$refs.myTable.$data,但这样并不推荐。 // 所以,我们可以提供一个方法通过ref来获取当前行索引。 // 但通常,我们直接通过组件的data属性即可,而使用ref访问方法可能更符合要求。 // 因此,我们可以在组件中定义一个方法,用于返回当前行索引。 methods: { getCurrentRowIndex() { return this.currentRowIndex; } } }; </script> ``` 然后在外部使用: ```javascript // 在父组件中 this.$refs.myTable.getCurrentRowIndex(); ``` 但是,这样只能获取到最后一次点击的行索引。 然而,我们注意到用户的问题是在“表格”中,并且他们可能同时需要获取中的行(通过引用[1]和[3])和当前点击的行。 考虑到表格中,用户可能通过点击框来择行,那么row-click事件也会触发。但是,如果用户点击的是框,那么除了row-click事件,还会触发select事件(择状态改变)和select-all事件(全)。 因此,我们需要明确:获取当前点击行号的需求是否包括点击框的情况?如果包括,那么row-click事件同样会触发,所以我们的方法同样适用。 但是,注意:在row-click事件中,我们无法区分点击的是行内的哪个单元格(比如框所在的列还是其他列)。不过,这并不影响我们记录行索引。 所以,总结方案: 1. 在表格上监听row-click事件(或者同时监听行内按钮点击事件,将索引记录下来)。 2. 在组件内部维护一个currentRowIndex(当前点击行索引)。 3. 通过ref暴露一个方法(如getCurrentRowIndex)来获取这个索引。 但是,请注意:在表格中,用户可能更关心的是中的行,而不是最后一次点击的行。所以,我们需要确认用户的需求。 根据用户的问题:“获取当前点击行的行号”,我们按照上述方案。 另外,如果用户希望同时获取中的行,可以使用引用[1]中的方法: ```javascript this.$refs.myTable.selection; // 获取中的行数据数组 ``` 因此,完整示例: ```vue <template> <div> <el-table ref="myTable" :data="tableData" @row-click="handleRowClick" @select="handleSelect" <!-- 如果需要处理择事件 --> > <el-table-column type="selection" width="55"></el-table-column> <!-- 其他列 --> <el-table-column label="操作"> <template slot-scope="scope"> <el-button @click="handleButtonClick(scope.$index)">操作</el-button> </template> </el-table-column> </el-table> <el-button @click="getCurrentRowIndex">获取当前点击行号</el-button> </div> </template> <script> export default { data() { return { tableData: [], // 表格数据 currentRowIndex: null, // 当前点击的行索引 }; }, methods: { // 行点击事件 handleRowClick(row, column, event) { // 获取行索引 this.currentRowIndex = this.tableData.indexOf(row); }, // 操作按钮点击事件 handleButtonClick(index) { this.currentRowIndex = index; // 其他操作 }, // 通过ref暴露的方法:获取当前点击行号 getCurrentRowIndex() { return this.currentRowIndex; }, // 如果需要,还可以暴露获取中行的方法(实际上Element已经提供了) getSelectedRows() { return this.$refs.myTable.selection; } } }; </script> ``` 在外部组件中,我们可以这样使用: ```javascript // 获取当前点击行号 const currentIndex = this.$refs.myTable.getCurrentRowIndex(); // 获取中的行 const selectedRows = this.$refs.myTable.selection; ``` 注意:在row-click事件中,我们使用`this.tableData.indexOf(row)`来获取索引,这要求row是tableData中的对象(并且是同一个引用)。如果表格数据有重复对象,则可能出错,但通常不会。 另外,如果表格数据有分页、排序、过滤等操作,那么tableData中的数据顺序可能和显示的行顺序不一致。此时,我们应该使用scope.$index(在操作列中)或者row-click事件中Element UI传递给我们的row对象实际上是tableData中的对象,所以indexOf得到的索引是数据源中的索引,而不是当前显示的索引。但是,row-click事件中的row就是tableData中的对象,所以indexOf得到的是数据源中的索引。 但是,注意:在分页情况下,这个索引是数据在整个数组(tableData)中的索引,而不是当前页的索引。如果用户需要当前页的索引,怎么办? 在row-click事件中,Element UI没有直接提供当前页的索引。但是,我们可以通过scope.row来获取当前行的数据,然后计算它在当前页的索引(即tableData中的索引就是当前页的索引?不对,因为tableData是当前页的数据)。是的,tableData是当前页的数据,所以indexOf(row)得到的是当前页的索引(从0开始)。 因此,上述方法得到的是当前页的行索引。 如果用户需要全局索引(整个数据集的索引),则需要知道当前页的页码和每页条数,然后计算: 全局索引 = 当前页索引 + (当前页码 - 1) * 每页条数 但是,用户的问题并没有明确要求,所以我们可以根据需求调整。 结论: 1. 使用row-click事件和操作按钮事件更新currentRowIndex(记录的是当前页的索引)。 2. 通过ref提供getCurrentRowIndex方法返回这个索引。 这样,我们就实现了在支持的表格中,通过ref获取当前点击行的行号。 注意:在Vue3中,我们可以使用组合式API,但思路类似。 最后,生成相关问题: §§相关问题§§ 1. 如何在Element UI表格中获取中行的行号(索引)? 2. Vue2和Vue3在通过ref获取表格行索引时有何不同? 3. Element UI表格分页时如何计算点击行在整个数据中的索引? 4. 如何同时获取Element UI表格当前点击行和中行的数据? </think> ### Vue表格时通过ref获取当前点击行行号的方法 在支持Vue表格中(特别是Element UI),可通过以下两种方案获取当前点击行的行号(索引): --- #### 方案一:通过`row-click`事件获取(推荐) 在表格上绑定`row-click`事件直接获取行索引: ```vue <template> <!-- 支持的表格 --> <el-table ref="myTable" :data="tableData" @row-click="handleRowClick" <!-- 关键:行点击事件 --> > <el-table-column type="selection" width="55"></el-table-column> <el-table-column prop="name" label="名称"></el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <!-- 操作按钮也可获取索引 --> <el-button @click="handleButton(scope.$index)">操作</el-button> </template> </el-table-column> </el-table> </template> <script> export default { methods: { // 行点击事件处理器 handleRowClick(row, column, event) { // 获取当前点击行的索引 const rowIndex = this.tableData.findIndex(item => item === row); console.log('当前行号(通过事件):', rowIndex); // [^1] // 需要时通过ref暴露行号 this.$refs.myTable.currentRowIndex = rowIndex; }, // 外部通过ref获取行号的方法 getClickedRowIndex() { return this.$refs.myTable.currentRowIndex; } } } </script> ``` **原理说明**: 1. `@row-click`捕获整个行的点击事件 2. 通过数据匹配`findIndex`获取行索引 3. 将索引存储在表格ref的属性中(如`currentRowIndex`) 4. 外部通过`this.$refs.myTable.getClickedRowIndex?()`访问 --- #### 方案二:通过ref遍历DOM结构获取 当必须完全依赖ref且无法修改事件时: ```vue <script> export default { methods: { getClickedRowIndex(event) { const table = this.$refs.myTable.$el; // 1. 获取所有行元素 const rows = table.querySelectorAll('.el-table__row'); // 2. 查找点击行在列表中的位置 let clickedIndex = -1; rows.forEach((row, index) => { if (row.contains(event.target)) { clickedIndex = index; } }); return clickedIndex; // 返回行索引(0-based) } } } </script> ``` **使用场景**: ```javascript // 在任意事件处理器中调用 handleClick(event) { const rowIndex = this.getClickedRowIndex(event); console.log('当前行号(DOM查询):', rowIndex); } ``` --- ### 两种方案对比 | **特性** | 方案一(事件绑定) | 方案二(DOM查询) | |------------------------|----------------------------------------|--------------------------------| | 精度 | ⭐⭐⭐⭐⭐(精确匹配数据) | ⭐⭐⭐⭐(依赖DOM结构) | | 性能 | ⭐⭐⭐⭐(直接访问数据) | ⭐⭐(需要遍历DOM节点) | | 兼容性 | ⭐⭐⭐⭐⭐(完美支持) | ⭐⭐⭐⭐(支持) | | 分页/过滤场景 | ⭐⭐⭐(需处理数据映射) | ⭐⭐⭐⭐(自动适配渲染) | | 代码简洁度 | ⭐⭐⭐⭐ | ⭐⭐ | | 适用场景 | 推荐常规使用 | 无法修改事件绑定时使用 | --- ### 关键细节说明 1. **行号定义**: - 索引始终从0开始 - 对应`tableData`数组中的位置 - 在页表格中反映当前页的索引 2. **表格特性**: - 通过`this.$refs.myTable.selection`获取**所有中行数据**[^1] - 中行的索引可通过数据匹配计算: ```javascript const selectedIndexes = this.$refs.myTable.selection.map( row => this.tableData.indexOf(row) ); ``` 3. **分页处理**: ```javascript // 获取全局索引(考虑分页) getGlobalIndex(pageIndex, pageSize, currentRowIndex) { return (pageIndex - 1) * pageSize + currentRowIndex; } ``` > 提示:优先使用方案一,它更符合Vue的数据驱动理念。方案二应在无法修改事件绑定的特殊场景使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值