【vue3+ts后台管理】商品列表完成

228 阅读2分钟

数据获取和搜索

在 request/api.ts 中增加获取商品列表的接口

//商品列表
export function getGoodsList(){
    return service({
        url:'/getGoodsList',
        method:'get',
    })
}

修改 GoodsView.vue ,打印接口返回数据

<script lang="ts">
import {defineComponent} from 'vue';
import {getGoodsList} from "@/request/api";

export default defineComponent({
  name: 'HomeView',
  setup(){
    getGoodsList().then(res=>{
      console.log(res)
    })
  },
  components: {},
});
</script>

在这里插入图片描述 我们设计商品列表样式为头部为一个搜索框,搜索后在下面展示商品列表。我们根据 行内表单 的相关代码,复制过来即可完成搜索框

我们在 type 文件夹下新建 goods.ts

export interface ListInt{
    userId:number,
    id:number,
    title:string,
    introduce:string
}

interface selectIntData{
    title:string,
    introduce:string,
    page:number,//页码
    count:number,//总条数
    size:number//默认一页显示几条
}

export class InitData{
    selectData:selectIntData = {
        title:'',
        introduce:'',
        page:1,
        count:0,
        size:10
    }
    list:ListInt[] = []//展示的内容数据
}

然后修改 GoodsView.vue

<template>
  <div>
    <div class="select-box">
      <el-form :inline="true" :model="selectData" class="demo-form-inline">
        <el-form-item label="标题">
          <el-input v-model="selectData.title" placeholder="请输入关键字"/>
        </el-form-item>
        <el-form-item label="详情">
          <el-input v-model="selectData.introduce" placeholder="请输入关键字"/>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts">
import {defineComponent, reactive, toRefs} from 'vue';
import {getGoodsList} from "@/request/api";
import {InitData} from "@/type/goods";

export default defineComponent({
  name: 'HomeView',
  setup() {
    const data = reactive(new InitData())
    getGoodsList().then(res => {
      console.log(res)
    })
    return{
      ...toRefs(data)
    }
  },
  components: {},
});
</script>
......

商品列表

我们根据 表格 来展示商品列表

	<el-table :data="list" border style="width: 100%">
      <el-table-column prop="id" label="ID" width="180" />
      <el-table-column prop="title" label="标题" width="180" />
      <el-table-column prop="introduce" label="详情" />
    </el-table>

<script lang="ts">
import {defineComponent, reactive, toRefs} from 'vue';
import {getGoodsList} from "@/request/api";
import {InitData} from "@/type/goods";

export default defineComponent({
  name: 'HomeView',
  setup() {
    const data = reactive(new InitData())
    getGoodsList().then(res => {
      data.list = res.data
    })
    return{
      ...toRefs(data)
    }
  },
  components: {},
});
</script>

在这里插入图片描述

商品列表分页

根据分页,我们可以增加商品列表分页功能。同时增加事件 current-change会在 current-page 改变时触发。size-change会在 page-size 改变时触发。同时,我们需要将商品数据进行分割,点击不同页数时,展示不同页码的商品

<template>
  <div>
    ......

    <el-table :data="dataList.comList" border style="width: 100%">
      <el-table-column prop="id" label="ID" width="180"/>
      <el-table-column prop="title" label="标题" width="180"/>
      <el-table-column prop="introduce" label="详情"/>
    </el-table>
    <el-pagination @current-change="currentChange" @size-change="sizeChange" layout="prev, pager, next"
                   :total="selectData.count"/>
  </div>
</template>

<script lang="ts">
import {computed, defineComponent, reactive, toRefs} from 'vue';
import {getGoodsList} from "@/request/api";
import {InitData} from "@/type/goods";

export default defineComponent({
  name: 'HomeView',
  setup() {
    const data = reactive(new InitData())
    getGoodsList().then(res => {
      data.list = res.data
      data.selectData.count = res.data.length
    })
    const currentChange = (page: number) => {
      data.selectData.page = page
    }
    const sizeChange = (size: number) => {
      data.selectData.size = size
    }
    const dataList = reactive({
      comList: computed(() => {
        //如果每页十条数据
        //1--[1-10]
        //2--[11-20]
        //3--[21-30]
        return data.list.slice((data.selectData.page - 1) * data.selectData.size, data.selectData.page * data.selectData.size)
      })
    })
    return {
      ...toRefs(data),
      currentChange,
      sizeChange,
      dataList
    }
  },
  components: {},
});
</script>

在这里插入图片描述

商品列表查询功能

查询按钮上有事件 onSubmit,我们增加这个方法,当标题或详情输入框中有查询内容时,过滤出包含输入内容的数组,赋值给变量 arr。如果两个输入框都没查询内容,直接把原来全部列表数据赋值给变量 arr 即可

最后更新页码数据,再把 arr 赋值给展示表格数据的 data.list

const onSubmit = () => {
      //console.log(data.selectData.title,data.selectData.introduce)
      let arr: ListInt[] = []
      //查询条件是否有值
      if (data.selectData.title || data.selectData.introduce) {
        if (data.selectData.title) {
          //将过滤出来的数组赋值给arr
          arr = data.list.filter((value) => {
            return value.title.indexOf(data.selectData.title) !== -1
          })
        }
        if (data.selectData.introduce) {
          //将过滤出来的数组赋值给arr
          arr = data.list.filter((value) => {
            return value.introduce.indexOf(data.selectData.introduce) !== -1
          })
        }
      } else {
        arr = data.list
      }
      data.selectData.count = arr.length
      data.list = arr
    }

为了方便观察数据,我们把默认每页10条数据,改为每页5条数据。所以,我们修改 goods.ts

export class InitData{
    selectData:selectIntData = {
        ......
        size:5
    }
    list:ListInt[] = []//展示的内容数据
}

同时,分页组件中,size 用于设置每页显示的页码数量,所以我们修改页面中的分页组件

<el-pagination @current-change="currentChange" 
				@size-change="sizeChange" 
				layout="prev, pager, next"
                :total="selectData.count" 
                :page-size="selectData.size"/>

在这里插入图片描述 可以看到能搜索出结果了,但是还需要完善,当我们删除搜索的关键字时,列表应该恢复到为筛选之前的全部数据,所以我们进行监听,当两个搜索条件都为空时,重新获取列表数据 或者 我们可以在最开始获取完列表数据后再用一个数组存储原始数据。

//监听输入框的两个属性
    watch([()=>data.selectData.title,()=>data.selectData.introduce],()=>{
      if(data.selectData.title == '' && data.selectData.introduce == ''){
        getGoodsList().then(res => {
          data.list = res.data
          data.selectData.count = res.data.length
        })
      }
    })

在这里插入图片描述 最后完善下代码,把获取商品列表提取出来成为一个方法,然后在 onMounted 中调用,在监听输入框的两个属性时,也调用这个方法

export default defineComponent({
  name: 'HomeView',
  setup() {
    const data = reactive(new InitData())
    const getGoods = ()=>{
      getGoodsList().then(res => {
        data.list = res.data
        data.selectData.count = res.data.length
      })
    }
    onMounted(()=>{
      getGoods()
    })
    ......
    //监听输入框的两个属性
    watch([()=>data.selectData.title,()=>data.selectData.introduce],()=>{
      if(data.selectData.title == '' && data.selectData.introduce == ''){
        getGoods()
      }
    })
    return {
      ......
    }
  },
  components: {},
});