【案例】根据商品的颜色进行分组,同一种颜色的商品可以对应多种尺寸、价格以及库存

效果展示

效果说明

 输入商品的颜色、尺寸后点击添加按钮,即可将对应的商品信息添加到下方的表格当中,表格中除了会显示商品的颜色和尺寸之外,还会显示商品的价格和库存,并且可以对商品的价格和库存进行修改,并且根据颜色进行分组将相同颜色值的数据都会添加在一个大行当中。

效果实现代码

第一步:创建项目

yarn create vite sku

第二步:安装项目所需要的依赖

yarn
yarn add sass sass-loader
yarn add vue-router
yarn add path
yarn add element-plus
yarn add -D unplugin-auto-import
yarn add unplugin-vue-components@0.26.0

注意:

安装 unplugin-vue-components 的时候要指导其版本为0.26.0,否则默认安装的为最新版本0.27.0,等到配置完element-plus组件的自动导入时会导致样式不生效的问题。

第三步: 配置别名@,以及配置element-plus的自动导入

vue.configchuan.js

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';

export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
});

第四步:创建Home页面并配置路由文件

src/router/index.js

import {createRouter,createWebHistory} from 'vue-router'

const routes = [
  {
    path: '/',
    component:()=>import('@/views/Home.vue')
  }
]
const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

第五步:引入路由文件

main.js

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

第六步:在创建的Home页面中编写代码

<template>
  <div>
    <div>
      <el-input v-model="color" placeholder="请输入颜色" />
      <el-input v-model="size" placeholder="行输入型号" />
      <el-button type="primary" @click="add">添加</el-button>
    </div>
    <div>
      <table width="1000" cellspacing="0">
        <!-- 表格的标题部分 -->
        <tr>
          <th
            v-for="(item, index) in showThData"
            :key="index"
            class="thStyle"
            :style="{ borderLeft: index === 0 ? '1px solid #eee' : '' }"
          >
            {{ item.title }}
          </th>
        </tr>
        <tr v-if="!tableData.length">
          <td :colspan="thData.length" class="noData">暂无数据</td>
        </tr>
        <!-- 表格的内容主题部分 -->
        <tr v-for="(obj, key) in groupData" :key="key" class="size tdbgColor">
          <!-- 颜色列 -->
          <td class="colorBorder" :style="tdStyle('color')">{{ key }}</td>
          <!-- 尺寸列 -->
          <td>
            <!-- 每种尺寸独占一行 -->
            <tr v-for="(item, index) in obj" :key="index">
              <td :style="tdStyle('size')">{{ item.size }}</td>
            </tr>
          </td>
          <!-- 价格列 -->
          <td>
            <!-- 每种尺寸的价格独占一行 -->
            <tr v-for="(item, index) in obj" :key="index">
              <td :style="tdStyle('size')">
                <!-- 
                  设置 precision 属性可以控制数值精度,接收一个 Number
                  当设置number为2的时候为保留两位小数
                 -->
                <el-input-number
                  v-model="item.price"
                  :precision="2"
                  :min="0"
                  @change="handleChange"
                />
              </td>
            </tr>
          </td>
          <!-- 库存列 -->
          <td>
            <!-- 每种尺寸的库存独占一行 -->
            <tr v-for="(item, index) in obj" :key="index">
              <td :style="tdStyle('size')">
                <!-- 
                  设置 precision 属性可以控制数值精度,接收一个 Number
                  当设置number为0的时候为保留整数【四舍五入】
                 -->
                <el-input-number
                  v-model="item.stock"
                  :precision="0"
                  :min="0"
                  @change="handleChange"
                />
              </td>
            </tr>
          </td>
        </tr>
      </table>
    </div>
    <!-- <el-button type="primary" @click="submit">提交</el-button>
    <div v-show="isShow">{{ showGroupData }}</div>  -->
  </div>
</template>

<script setup>
import { ref } from "vue";

const handleChange = (value) => {
  console.log(value);
};

const tableData = ref([]);
const thData = ref([
  { title: "颜色", text: "color" },
  { title: "尺寸", text: "size" },
  { title: "价格", text: "price" },
  { title: "库存", text: "stock" },
]);
const showThData = ref(thData);
const color = ref(""); //颜色
const size = ref(""); //尺寸
const groupData = ref({}); //将添加的数据按照颜色进行分组
const showGroupData = ref({});
// 点击添加按钮将数据添加到下方表格中
const add = () => {
  tableData.value.push({
    color: color.value,
    size: size.value,
    price: 0,
    stock: 0,
  });
  sort();
};
// 对添加的数据进行分组处理,当多个颜色的值相同时按照第一个出现的位置进行排序
const sort = () => {
  // 创建一个映射表来记录每种颜色首次出现的索引
  const colorIndices = new Map();
  tableData.value.forEach((item, index) => {
    if (!colorIndices.has(item.color)) {
      colorIndices.set(item.color, index);
    }
  });

  // 根据颜色首次出现的索引进行排序
  tableData.value.sort((a, b) => {
    // 获取a和b的颜色首次出现的索引
    const indexA = colorIndices.get(a.color);
    const indexB = colorIndices.get(b.color);

    // 如果首次出现的索引相同,则保持原始顺序(可选,取决于具体需求)
    // 这里假设原始顺序应当保持,如果不需要保持则直接返回 indexA - indexB 即可
    return indexA === indexB
      ? tableData.value.indexOf(a) - tableData.value.indexOf(b)
      : indexA - indexB;
  });
  // 使用reduce方法对数据进行分组处理
  groupData.value = tableData.value.reduce((acc, curr) => {
    const color = curr.color;
    if (!acc[color]) {
      acc[color] = [];
    }
    acc[color].push(curr);
    return acc;
  }, {});
};
// 单元格的样式设置
const tdStyle = (type) => {
  let style = { borderBottom: "1px solid #eee" };
  if (type === "color") {
    style.borderLeft = "1px solid #eee";
  } else {
    style.borderRight = "1px solid #eee";
  }
  return style;
};
const isShow = ref(false); //数据是否显示
// 点击提交按钮将数据显示在下方
const submit = () => {
  showGroupData.value = { ...groupData.value, title: thData.value };
  isShow.value = true;
};
</script>
<style lang="scss" scoped>
.el-input {
  margin: 10px;
  width: 200px;
}
table {
  margin: 10px;
  text-align: center;
  th,
  td {
    width: 250px;
    height: 50px;
  }
  th {
    color: #888;
  }
  .thStyle {
    border: 1px solid #eee;
    border-left: none;
  }
  .size {
    border: none;
  }
  // 设置样式表格隔行显示背景色
  .tdbgColor:nth-child(2n + 1) {
    background: #d1edff59;
  }
}
.colorBorder {
  border-right: 1px solid #eee;
}
.price {
  border-right: 1px solid #eee;
  border-bottom: 1px solid #eee;
}
.noData {
  border: 1px solid #eee;
  border-top: none;
  color: #ccc;
}
</style>

通过以上步骤即可实现效果图中所展示的效果

由于对于element-plus组件库中的el-table的合并单元格的方法没有写明白所以就用了原生的table书写的,如果有哪位大佬可以使用el-table实现该效果,还请不吝赐教。

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我们来看一个简单的商品查询效果案例,学习数组常用方法。 首先,我们需要一个包含商品信息的数组,包括商品名称、价格、描述等。 ```python products = [ {"name": "iPhone", "price": 8999, "description": "Apple iPhone 12 Pro Max"}, {"name": "Samsung Galaxy", "price": 6999, "description": "Samsung Galaxy S21 Ultra"}, {"name": "Huawei Mate", "price": 5999, "description": "Huawei Mate 40 Pro"}, {"name": "Xiaomi Mi", "price": 3999, "description": "Xiaomi Mi 10T Pro"} ] ``` 接下来,我们可以定义一个函数 `search_products`,用于根据价格区间和商品名称进行查询。 ```python def search_products(products, min_price=None, max_price=None, name=None): result = [] for product in products: if min_price and product["price"] < min_price: continue if max_price and product["price"] > max_price: continue if name and name.lower() not in product["name"].lower(): continue result.append(product) return result ``` 这个函数接受一个 `products` 数组作为参数,以及最小价格、最大价格商品名称作为可选参数。它会遍历数组中的每个商品,根据价格区间和商品名称进行筛选,并将符合条件的商品添加到一个新的结果数组中。 使用这个函数可以进行多种查询,例如: ```python # 查询价格在 5000 至 8000 之间的商品 result = search_products(products, min_price=5000, max_price=8000) print(result) # 查询名称中包含 "pro" 的商品 result = search_products(products, name="pro") print(result) # 查询价格在 3000 至 5000 之间,且名称中包含 "mi" 的商品 result = search_products(products, min_price=3000, max_price=5000, name="mi") print(result) ``` 这些查询都可以返回符合条件的商品。这个案例中使用了常见的数组方法,例如遍历数组、条件判断和添加元素。同时,还使用了 Python 的函数参数默认值和字符串方法 lower(),帮助我们更方便地编写代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值