table案例

8/23/2022 vue

# table案例

# 实现步骤

① 搭建项目的基本结构

② 请求商品列表的数据

③ 封装 MyTable 组件

④ 实现删除功能

⑤ 实现添加标签的功能

# 1. 搭建项目基本结构

# 1.1 初始化项目

  1. 在终端运行如下的命令,初始化 vite 项目:
npm init vite-app table-demo
1
  1. cd 到项目根目录,安装依赖项:
npm install
1
  1. 安装 less 依赖包:
npm i less -D
1
  1. 使用 vscode 打开项目,并在 vscode 集成的终端下运行如下的命令,把项目运行起来:
npm run dev
1

5.安装 axios:

npm install axios@0.21.0 -S
1

# 1.2 梳理项目结构

在这里插入图片描述

# 2. 代码部分

main.js 代码:

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

import axios from 'axios'

import './assets/css/bootstrap.css'
import './index.css'

// 配置axios请求根路径
axios.defaults.baseURL = 'https://www.escook.cn'

const app = createApp(App)

// 将axios挂载到全局
app.config.globalProperties.$http = axios


app.mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

index.css 代码:

:root {
 font-size: 12px; 
}
body {
 padding: 8px; 
}
1
2
3
4
5
6

MyTable 组件的封装要求

  1. 用户通过名为 data 的 prop 属性,为 MyTable.vue 组件指定数据源

  2. 在 MyTable.vue 组件中,预留名称为 header 的具名插槽

  3. 在 MyTable.vue 组件中,预留名称为 body 的作用域插槽

MyTable.vue 代码:

<template>
  <div>MyTable 组件</div>
  <div>
    <table class="table table-striped">
      <thead>
        <tr>
          <slot name="header"></slot>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item , index) in data" :key="item.id">
          <!-- 为数据行的 td 预留的“作用域插槽” -->
          <slot name="body" :row="item" :index="index"></slot>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>

export default {
  name: "MyTable",
  props: {
    // 表格的数据源
    data: {
      type: Array,
      default: [],
      require: true,
    },
  },
}
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

app.vue 代码:

<template>
  <h2>app根组件</h2>
  <MyTable :data="tablelist">
    <template #header>
      <th>#</th>
      <th>商品名称</th>
      <th>价格</th>
      <th>标签</th>
      <th>操作</th>
    </template>
    <template #body="{row,index}">
      <td>{{ index + 1 }}</td>
      <td>{{ row.goods_name }}</td>
      <td>¥{{ row.goods_price }}</td>
      <td class="mytags">
        <!-- 循环渲染标签信息 -->
        <input 
        type="text" 
        class="form-control form-control-sm ipt-tag" 
        v-focus 
        v-if="row.inputVisible"
        v-model.trim="row.inputValue"
        @blur="onInputConfirm(row)"
        @keyup.enter="onInputConfirm(row)"
        @keyup.esc="row.inputValue = ''"
        >
        <button type="button" class="btn btn-primary btn-sm" v-else @click="row.inputVisible = true">+Tag</button>
        <span class="badge badge-warning ml-2" v-for="item in row.tags" :key="item">{{ item }}</span>
      </td>
      <td>
        <button type="button" class="btn btn-danger btn-sm" @click="onRemove(row.id)">删除</button>
      </td>
    </template>
  </MyTable>
</template>

<script>
import MyTable from './components/my-table/MyTable.vue'

export default {
  name:'MyApp',
  components:{
    MyTable
  },
  data(){
    return{
      tablelist:[]
    }
  },
  created(){
    this.getlist()
  },
  methods: {
    async getlist(){
      const {data:res} = await this.$http('/api/goods')
      if(res.status!==0)return console.log('获取列表数据失败!')
      this.tablelist = res.data
    },
    // 删除功能
    onRemove(id){
      this.tablelist = this.tablelist.filter(x=>x.id !== id)
    },
    onInputConfirm(row){
      // 1. 把用户在文本框中输入的值,预先转存到常量 val 中
      const vla = row.inputValue
      // 2. 清空文本框的值
      row.inputValue = ''
      // 3. 隐藏文本框
      row.inputVisible = false
      // 1.1 判断 val 的值是否为空,如果为空,则不进行添加
      // 1.2 判断 val 的值是否已存在于 tags 数组中,防止重复添加
      if(!vla || row.tags.indexOf(vla) !== -1) return
        // 2. 将用户输入的内容,作为新标签 push 到当前行的 tags 数组中
        row.tags.push(vla)
    }
  },
  directives:{
    focus(el){
      el.focus()
    }
  }
}
</script>

<style lang="less" scoped>
.mytags{
  display: flex;
}
.form-control{
  width: 80px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

# 3. 功能演示

实现删除功能,单机即可删除当前项

在这里插入图片描述

实现添加标签的功能

回车或者input输入框失去焦点都判断,vla不为空,或者不重复,就添加到标签。

在这里插入图片描述

input失去焦点,标签添加,展示+Tag按钮。

在这里插入图片描述

Last Updated: 9/7/2022, 11:32:53 PM