1. 项目构建

1.1使用vist创建vue项目,导入bootstrap,axios包

npm init vite-app table-demo
cd table-demo
npm i
npm i axios bootstrap

在这里插入图片描述
然后把vue默认的样式都删干净

1.2创建后台文件

创建一个新文件夹,进入命令行初始化一下,然后在其中创建server.js

mkdir table-demo-server
cd table-demo-server
npm init -y
npm i express
node server

在这里插入图片描述
数据源自后台,我们在下面模拟了一个后台的效果,对外暴露goodData对象

const express=require('express')
//引入express
const app=express()
app.all("*", function (req, res, next) {
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin", "*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers", "content-type");
    //跨域允许的请求方式
    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
    if (req.method.toLowerCase() == 'options')
        res.send(200);  //让options尝试请求快速结束
    else
        next();
})
const goodData={"status":0,"message":"获取商品列表成功","data":[{"id":1,"goods_name":"Teenmix/天美意夏季专柜同款金色布女鞋6YF18BT6","goods_price":298,"tags":["舒适","透气"],"inputVisible":false,"inputValue":""},{"id":2,"goods_name":"奥休斯(all shoes) 冬季保暖女士休闲雪地靴 舒适加绒防水短靴 防滑棉鞋子","goods_price":89,"tags":["保暖","防滑"],"inputVisible":false,"inputValue":""},{"id":3,"goods_name":"初语秋冬新款毛衣女 套头宽松针织衫简约插肩袖上衣","goods_price":199,"tags":["秋冬","毛衣"],"inputVisible":false,"inputValue":""},{"id":4,"goods_name":"佐露絲蕾丝衫女2020春秋装新款大码女装衬衫上衣雪纺衫韩版打底衫长袖","goods_price":19,"tags":["雪纺衫","打底"],"inputVisible":false,"inputValue":""},{"id":5,"goods_name":"熙世界中长款长袖圆领毛衣女2022秋装新款假两件连衣裙女107SL170","goods_price":178,"tags":["圆领","连衣裙"],"inputVisible":false,"inputValue":""},{"id":6,"goods_name":"烟花烫2021秋季装新品女装简约修身显瘦七分袖欧根纱连衣裙 花央","goods_price":282,"tags":["秋季新品","显瘦"],"inputVisible":false,"inputValue":""},{"id":7,"goods_name":"韩都衣舍2021韩版女装秋装新宽松显瘦纯色系带长袖衬衫NG8201","goods_price":128,"tags":["韩都衣舍","长袖衬衫"],"inputVisible":false,"inputValue":""},{"id":8,"goods_name":"预售纤莉秀大码女装胖妹妹秋装2020新款圆领百搭绣花胖mm休闲套头卫衣","goods_price":128,"tags":["预售","卫衣"],"inputVisible":false,"inputValue":""},{"id":9,"goods_name":"莎密2022夏改良旗袍裙连衣裙修身复古时尚日常短款礼服旗袍","goods_price":128,"tags":["莎密","礼服"],"inputVisible":false,"inputValue":""},{"id":10,"goods_name":"南极人秋冬韩版七彩棉加绒加厚一体保暖打底裤p7011","goods_price":128,"tags":["南极人","打底裤"],"inputVisible":false,"inputValue":""}]}
app.get('/goodsData',(req,res)=>{
    res.send(goodData)
})
app.listen(4000,()=>console.log('app is running at port 4000...'))

node server运行一下看是否成功,检验的方法是在浏览器中输入http://localhost:4000/goodsData先查看效果,后面我会解析

在这里插入图片描述

2. 前台文件

直接上代码然后剖析

2.1父组件-App.vue

<template>
<!--    .container>.row>.col-md-12>h1+hr+table.table-->
    <div class="container">
        <div class="row">
            <div class="col-md-12">
                <h1>App根组件</h1>
                <hr>
                <MyTable :data="goodsList">
                    <template #theader>
                        <th>序号</th>
                        <th>商品名称</th>
                        <th>价格</th>
                        <th>标签</th>
                        <th>操作</th>
                    </template>
                    <template #tbody="{row,index}">
<!--                        接收父级传来的row和index-->
                        <td>{{index+1}}</td>
                        <td>{{row.goods_name}}</td>
                        <td>{{row.goods_price}}</td>
                        <td>
<!--                            {{row.tags}}-->
                            <span aaa class="badge btn-warning text-dark" v-for="item in row.tags" :key="item">
                                {{item}}
                            </span>
                        </td>
                        <td>
                            <button class="btn btn-danger btn-sn">删除</button>
                        </td>
                    </template>
                </MyTable>
            </div>
        </div>
    </div>
    <MyTable :data="aaa">
        <template #theader>
            <th>序号</th>
            <th>姓名</th>
            <th>年龄</th>
        </template>
        <template #tbody="{row,index}">
            <td>{{index+1}}</td>
            <td>{{row.name}}</td>
            <td>{{row.age}}</td>
        </template>
    </MyTable>

</template>

<script>
    import axios from 'axios'
    //axios跟后台要数据功能
    import MyTable from "./components/my-table/MyTable.vue";
    export default {
        name: 'App',
        components: {
            MyTable
        },
        data() {
            return {
                goodsList: [],
                aaa:[
                    {id:0,name:'小明',age:18},
                    {id:0,name:'小红',age:18},
                    {id:0,name:'小刚',age:18},
                ]
            }
        },
        created() { //生命周期函数
            this.getGoodsData()
        },
        methods:{
            async getGoodsData(){
                const result = await axios.get('http://localhost:4000/goodsdata')
                console.log(result.data.data)
                this.goodsList = result.data.data
            }
        }
    }
</script>
<style>
     .text-dark[aaa]{margin-right: 10px}
</style>

2.1.1 父组件数据的流向

59-69行:data()return出两个数据流goodlistaaa
我们会有一问,goodlist里面不是空的吗?为什么里面有数据?
我们接着往下看72-79行,我们通过getGoodsData()方法找后台要来数据并赋值给了goodlist,虽然goodlist在代码中并没有直接赋值,但其实里面是有数据的。其中
async为异步操作

51,57行:引入,注册axios

53行:引入子组件Son.vue

8行:我们将goodsList:data绑定,子组件只要使用prop引入即可获取到goodList的值,35行同理

9,16行:插入了两个插槽#header写法为语法糖,等同于v-slot:header,#header和#body分别调用子组件的插槽,在这里比较值得一提的是16行#tbody后跟了两个值{row,index},在子组件中细说

23,82行:span标签中加入了aaa这么一个特殊符号,元素多个所以循环显示一下,并给他设了css样式,让其中元素相隔一段距离。

35行:我们发现aaa也绑定了:data,goodsList也绑定了:data,这说明了父组件重复利用了一个子组件,但是为什么显示的内容最后不一样呢?因为父组件给子组件传的值虽然格式一样,但是值却不一样,相当于子组件只是躯壳,内容由父组件填入

2.2子组件-Son.vue

<template>
    <table class="table table-responsive table-striped">
        <thead>
<!--        组件的复用性-->
        <tr>
            <slot name="theader"></slot>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(item,index) in data" :key="item.id">
            <slot name="tbody" :row="item" :index="index">
            </slot>
        </tr>
        </tbody>
    </table>

</template>

<script>
    export default {
        name: "MyTable",
        props:{
            data:{
                type:Array,
                required:true,
                default:[]
            }
        }
    }
</script>

<style scoped>

</style>

2.2.1 子组件数据的流向

22-28行:props获取父组件的data数据并设置了验证格式

10行,设置循环data中的数据,v-for="(item,index) 这里有两个参数,item是数据主体,index是数据的索引

6,11行:两个服务于父组件的插槽,值得一提的是11行对应父组件的16行设置了两个参数。

3. 后台文件server.js

我再放一遍后台代码吧,看着方便一些

const express=require('express')

const app=express()

app.all("*", function (req, res, next) {
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin", "*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers", "content-type");
    //跨域允许的请求方式
    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
    if (req.method.toLowerCase() == 'options')
        res.send(200);  //让options尝试请求快速结束
    else
        next();
})


const goodData={"status":0,"message":"获取商品列表成功","data":[{"id":1,"goods_name":"Teenmix/天美意夏季专柜同款金色布女鞋6YF18BT6","goods_price":298,"tags":["舒适","透气"],"inputVisible":false,"inputValue":""},{"id":2,"goods_name":"奥休斯(all shoes) 冬季保暖女士休闲雪地靴 舒适加绒防水短靴 防滑棉鞋子","goods_price":89,"tags":["保暖","防滑"],"inputVisible":false,"inputValue":""},{"id":3,"goods_name":"初语秋冬新款毛衣女 套头宽松针织衫简约插肩袖上衣","goods_price":199,"tags":["秋冬","毛衣"],"inputVisible":false,"inputValue":""},{"id":4,"goods_name":"佐露絲蕾丝衫女2020春秋装新款大码女装衬衫上衣雪纺衫韩版打底衫长袖","goods_price":19,"tags":["雪纺衫","打底"],"inputVisible":false,"inputValue":""},{"id":5,"goods_name":"熙世界中长款长袖圆领毛衣女2022秋装新款假两件连衣裙女107SL170","goods_price":178,"tags":["圆领","连衣裙"],"inputVisible":false,"inputValue":""},{"id":6,"goods_name":"烟花烫2021秋季装新品女装简约修身显瘦七分袖欧根纱连衣裙 花央","goods_price":282,"tags":["秋季新品","显瘦"],"inputVisible":false,"inputValue":""},{"id":7,"goods_name":"韩都衣舍2021韩版女装秋装新宽松显瘦纯色系带长袖衬衫NG8201","goods_price":128,"tags":["韩都衣舍","长袖衬衫"],"inputVisible":false,"inputValue":""},{"id":8,"goods_name":"预售纤莉秀大码女装胖妹妹秋装2020新款圆领百搭绣花胖mm休闲套头卫衣","goods_price":128,"tags":["预售","卫衣"],"inputVisible":false,"inputValue":""},{"id":9,"goods_name":"莎密2022夏改良旗袍裙连衣裙修身复古时尚日常短款礼服旗袍","goods_price":128,"tags":["莎密","礼服"],"inputVisible":false,"inputValue":""},{"id":10,"goods_name":"南极人秋冬韩版七彩棉加绒加厚一体保暖打底裤p7011","goods_price":128,"tags":["南极人","打底裤"],"inputVisible":false,"inputValue":""}]}
app.get('/goodsData',(req,res)=>{
    res.send(goodData)
})

app.listen(4000,()=>console.log('app is running at port 4000...'))

3.1 后台对外开放

5-16行,解决跨域问题,十分重要
19-22行:还记得之前空的goodList[]吗?明明是空的却有值,这里就是goodList的根源所在,goodsData赋值给goodList

4.效果

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐