Vue.js 案例——商品管理

news/2024/7/8 9:10:31 标签: vue.js, 前端, javascript

一.需要做出的效果图:

二.实现的步骤

首先,先建一个项目,命名Table在Table项目中的components里新建一个MyTable.vue文件

第二步,在原有的 HelloWorld.vue中写入代码。

HelloWorld.vue代码如下:

<script setup>
import { ref } from 'vue'

defineProps({
  msg: String,
})

const count = ref(0)
</script>

<template>
  <h1>{{ msg }}</h1>

  <div class="card">
    <button type="button" @click="count++">count is {{ count }}</button>
    <p>
      Edit
      <code>components/HelloWorld.vue</code> to test HMR
    </p>
  </div>

  <p>
    Check out
    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
      >create-vue</a
    >, the official Vue + Vite starter
  </p>
  <p>
    Install
    <a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
    in your IDE for a better DX
  </p>
  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
</template>

<style scoped>
.read-the-docs {
  color: #888;
}
</style>

MyTable.vue代码如下:

<template>
  <table class="table table-striped table-bordered">
    <!-- 表格标题区域 -->
    <thead>
      <tr>
        <slot name="header"></slot>
      </tr>
    </thead>
    <!-- 表格主体区域 -->
    <tbody>
      <tr v-for="(item, index) in goodsList" :key="item.id">
        <slot name="body" :row="item" :index="index"></slot>
      </tr>
    </tbody>
  </table>
</template>
 
<script setup>
const props = defineProps({
  goodsList: {
    type: Array,
    required: true,
    default: []
  }
})
</script>

在App.vue中写入代码:

<template>
  <h4>商品管理</h4>
  <MyTable :goodsList="goodsList">
    <template v-slot:header>
      <th scope="col">#</th>
      <th scope="col">商品名称</th>
      <th scope="col">价格</th>
      <th scope="col">标签</th>
      <th scope="col">操作</th>
    </template>
    <template #body="{ row, index }">
      <td>{{ index + 1 }}</td>
      <td>{{ row.goods_name }}</td>
      <td>¥{{ row.goods_price }}</td>
      <td>
        <input type="text" v-if="row.inputVisible" class="form-control form-control-sm ipt-tag" v-focus
          v-model="row.inputValue" 
          @keyup.esc="row.inputValue = ''"
          @blur="onInputConfig(row)"
          @keyup.enter="onInputConfig(row)"
        />
        <button class="btn btn-outline-primary rounded-pill" v-else @click="row.inputVisible = true">+Tag</button>
        <span class="btn btn-outline-dark" v-for="item in row.tags" :key="item">
          {{ item }}
        </span>
      </td>
      <td>
        <button type="button" class="btn btn-outline-danger btn-sm" @click="onRemove(row.id)">删除</button>
      </td>
    </template>
  </MyTable>
</template>
 
<script setup>
import MyTable from './components/MyTable.vue'

import { ref } from 'vue'

const goodsList = ref([
  {
    id: 1,
    goods_name: '夏季专柜同款女鞋',
    goods_price: 298,
    tags: ['舒适', '透气'],
    inputVisible: false,
    inputValue: ''
  },
  {
    id: 2,
    goods_name: '冬季保暖女士休闲雪地靴 舒适加绒防水短靴 防滑棉鞋',
    goods_price: 89,
    tags: ['保暖', '防滑'],
    inputVisible: false,
    inputValue: ''
  },
  {
    id: 3,
    goods_name: '秋冬新款女士毛衣 套头宽松针织衫 简约上衣',
    goods_price: 199,
    tags: ['秋冬', '毛衣'],
    inputVisible: false,
    inputValue: ''
  },
  {
    id: 4,
    goods_name: '2023春秋装新款大码女装 衬衫 上衣',
    goods_price: 19,
    tags: ['雪纺衫', '打底'],
    inputVisible: false,
    inputValue: ''
  },
  {
    id: 5,
    goods_name: '长款长袖圆领女士毛衣 2022秋装新款假两件连衣裙',
    goods_price: 178,
    tags: ['圆领', '连衣裙'],
    inputVisible: false,
    inputValue: ''
  }
])

const onRemove = id => {
  goodsList.value = goodsList.value.filter(item => item.id != id)
}

const vFocus = el => { el.focus() }

const onInputConfig = row => {
  const val = row.inputValue
  row.inputValue = ''
  row.inputVisible = false
  if (!val || row.tags.indexOf(val) !== -1) {
    return
  }
	row.tags.push(val)
}
</script>

<style scoped>
th {
  text-align: center;
}
td {
  line-height: 30px;
}
.ipt-tag {
  width: 80px;
  display: inline;
}
input, span, button {
  margin-right: 10px;
}
</style>

最后,修改main.js的代码:

import { createApp } from 'vue'
import './bootstrap.css'
import App from './App.vue'

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

三.运行结果

ctrl+s保存,运行其结果:

点击+Tag可以添加不同的标签,例如:

点击删除也可以删除该行,删除如上第一行,如下所示:

今天就分享到此,感谢预览~


http://www.niftyadmin.cn/n/5536922.html

相关文章

【Java】CompletableFuture+Mockito单元测试不通过 Unnecessary stubbings detected

文章目录 问题描述问题分析解决Thread.sleepget()Mockito.lenient() 问题描述 有个接口使用CompletableFuture实现的异步调用&#xff0c;现在要用Mockito写单元测试 Testpublic void updateNumAsync() {Integer newNum 600;// updateRoleCountAsync用CompletableFuture异步调…

【免费资料】IEEE33节点系统参数及拓扑图visio

主要内容 对于初学配电网的同学&#xff0c;最经典的系统即是33节点配电网系统&#xff0c;在各个研究文献中出现频次最高的也是这个系统&#xff0c;为了让大家更好了解33节点系统参数&#xff0c;本次整理了系统节点、支路参数excel以及33节点网络拓扑图visio&#xff0c…

二维舵机颜色追踪,使用树莓派+opencv+usb摄像头+两个舵机实现颜色追踪,采用pid调控

效果演示 二维云台颜色追踪 使用树莓派opencvusb摄像头两个舵机实现颜色追踪&#xff0c;采用pid调控 import cv2 import time import numpy as np from threading import Thread from servo import Servo from pid import PID# 初始化伺服电机 pan Servo(pin19) tilt Serv…

累积分布函数的一些性质证明

性质1&#xff1a; E [ X ] ∫ 0 ∞ ( 1 − F ( x ) ) d x − ∫ − ∞ 0 F ( x ) d x ( 1 ) E[X]\int_0^{\infty}(1-F(x))dx - \int_{-\infty}^0F(x)dx\quad (1) E[X]∫0∞​(1−F(x))dx−∫−∞0​F(x)dx(1) 证明&#xff1a; E [ X ] ∫ − ∞ ∞ x p ( x ) d x E[X] …

达梦数据库小技巧

达梦数据库小技巧 一&#xff1a; 时间类型TIMESTAMP使用1.1 建表1.2 插入1.3按时间戳查询&#xff0c;返回某一列不重复的值 二&#xff1a;存储过程创建和调用2.1建表2.2 创建存储过程&#xff0c;循环100插入拼接字符串2.3调用存储过程 一&#xff1a; 时间类型TIMESTAMP使用…

process.env 管理 Vue 项目的环境变量(Vue项目中环境变量的配置及调用)

简述&#xff1a;在构建 Vue 应用时&#xff0c;管理配置是开发中的一个重要部分。不同的环境&#xff08;如开发、测试和生产&#xff09;往往需要不同的配置&#xff0c;例如 API、 基础 URL、第三方服务的密钥等。使用环境变量可以帮助我们更好地管理这些配置。这里将介绍如…

【Leetcode 566】【Easy】重塑矩阵

目录 题目描述 整体思路 具体代码 题目描述&#xff1a; 原题链接 整体思路 首先要确保重塑后的矩阵内元素个数和原矩阵元素个数要相同&#xff0c;如果不同则原样返回原矩阵。 按行遍历顺序遍历原矩阵&#xff0c;设一个临时vector<int>存放新矩阵的每一行的元素…

数字人大赋能未来治理新篇章,正宇软件助力人大建设新实践

在全面贯彻落实党的二十大精神的开局之年&#xff0c;数字中国战略的深入实施如同一股强劲的东风&#xff0c;吹遍了神州大地的每一个角落。作为数字中国建设的重要组成部分&#xff0c;数字人大作为现代信息技术与人大工作深度融合的产物&#xff0c;正以其独特的魅力和深远的…