vue-admin-template 添加商品页面(含增删改查功能)

说明

页面

src/views 创建 goods 目录

goods 目录下,添加 index.vue 文件,内容如下:

<template>
  <div class="app-container">
    <div class="filter-container">
      <el-input v-model="queryInfo.name" placeholder="名称" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
      <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter" />
      <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-circle-plus-outline" @click="addDialog" />
    </div>
    <el-table
      ref="table"
      v-loading="listLoading"
      :data="tableData"
      element-loading-text="Loading"
      border
      fit
      highlight-current-row
    >
      <el-table-column align="center" label="ID" width="95">
        <template slot-scope="scope">
          {{ scope.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="缩略图" width="250">
        <template slot-scope="scope">
          <img :src="BASE_URL + scope.row.img" width="200px">
        </template>
      </el-table-column>
      <el-table-column label="名称">
        <template slot-scope="scope">
          {{ scope.row.name }}·{{ scope.row.descrip }}
        </template>
      </el-table-column>
      <el-table-column label="价格" width="110" align="center">
        <template slot-scope="scope">
          <span>{{ scope.row.price }}</span>
        </template>
      </el-table-column>
      <el-table-column label="旅游人数" width="110" align="center">
        <template slot-scope="scope">
          {{ scope.row.personNum }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="操作" width="200">
        <template slot-scope="scope">
          <el-button type="primary" size="small" @click="editDialog(scope.row.id)" icon="el-icon-edit"></el-button>
          <el-button type="danger" size="small" @click="deleteConfirm(scope.row.id)" icon="el-icon-delete" ></el-button>
      </template>
      </el-table-column>
    </el-table>

    <div class="block">
      <el-pagination
        :current-page="page.pageNum"
        :page-sizes="[10, 20, 30, 40]"
        :page-size="page.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="page.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible" width="900px">
      <el-form ref="dataForm" :rules="rules" :model="dialogData" label-position="right" label-width="100px" style="width: 800px; margin-left:20px; ">
        <el-form-item label="名称" prop="name">
          <el-input v-model="dialogData.name" />
        </el-form-item>
        <el-form-item label="价格" prop="price">
          <el-input v-model="dialogData.price" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="dialogData.descrip" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请填写描述" />
        </el-form-item>
        <el-form-item label="特色" prop="tags">
          <el-input v-model="dialogData.tags" /> 多个特色用逗号分隔
        </el-form-item>
        <el-form-item label="服务保障" prop="services">
          <el-checkbox-group v-model="dialogData.services">
            <el-checkbox label="1" name="services" >无购物</el-checkbox>
            <el-checkbox label="2" name="services" >成团保障</el-checkbox>
            <el-checkbox label="3" name="services" >安心游</el-checkbox>
            <el-checkbox label="4" name="services" >无自费</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="产品卖点" prop="selling">
          <el-input v-model="dialogData.selling1" />
          <el-input v-model="dialogData.selling2" />
          <el-input v-model="dialogData.selling3" />
        </el-form-item>
        <el-form-item label="详情">
          <el-input v-model="dialogData.content" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="请填写详情" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="dialogStatus==='create'?add():update()">
          提交
        </el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
// import { getList } from '@/api/table'
// import waves from '@/directive/waves' // waves directive
import { axios, BASE_URL } from '@/utils/request2'
import { scrollTo } from '@/utils/scroll-to'
// import axios from 'axios'

export default {
  filters: {
    statusFilter(status) {
      const statusMap = {
        published: 'success',
        draft: 'gray',
        deleted: 'danger'
      }
      return statusMap[status]
    }
  },
  data() {
    return {
      tableData: null,
      BASE_URL: BASE_URL,
      listLoading: true,
      queryInfo: {
        name: ''
      },
      page: {
        total: 0,
        pageNum: 1,
        pageSize: 10,
        pages: 0
      },
      dialogData: {
        id: undefined,
        name: '',
        price: '',
        descrip: '',
        tags: '',
        services: [],
        selling1: '',
        selling2: '',
        selling3: '',
        content: ''
      },
      dialogFormVisible: false, // 对话框是否显示
      dialogStatus: '', // 对话框状态,用于设置提交按钮事件
      dialogTitle: '', // 对话框标题
      dialogPvVisible: false,
      rules: { // 表单校验规则
        name: [{ required: true, message: '名称必须填写', trigger: 'blur' }],
        price: [{ required: true, message: '价格必须填写', trigger: 'blur' }]
      },
      downloadLoading: false
    }
  },
  created() {
    this.fetchData()
  },
  methods: {
    fetchData() {
      this.listLoading = true

      const params = new URLSearchParams()
      params.append('name', this.queryInfo.name)
      params.append('page', this.page.pageNum)
      params.append('limit', this.page.pageSize)
      params.append('status', 1)

      axios.post('/mgr/goods/list', params).then(res => {
        console.log(res.data)
        if (res.data.code === 0) {
          this.tableData = res.data.data
          this.page.total = res.data.total
          this.page.pageNum = res.data.pageNum
          this.page.pageSize = res.data.pageSize
          this.page.pages = res.data.pages
          this.listLoading = false
        } else {
          this.$message({
            message: res.data.msg,
            type: 'warning'
          })
        }
      })
    },
    queryById(id) {
      axios.get('/mgr/goods/showGoodsById?id=' + id).then(res => {
        console.log(res.data)
        if (res.data.code === 0) {
          this.dialogData.id = res.data.data.id
          this.dialogData.name = res.data.data.name
          this.dialogData.descrip = res.data.data.descrip
          this.dialogData.content = res.data.data.content
          this.dialogData.img = res.data.data.img
          this.dialogData.price = res.data.data.price
          this.dialogData.selling1 = res.data.data.selling1
          this.dialogData.selling2 = res.data.data.selling2
          this.dialogData.selling3 = res.data.data.selling3
          this.dialogData.services = res.data.data.services.split(',')
          console.log(this.dialogData.services)
          this.dialogData.tags = res.data.data.tags
          // this.listLoading = false
        } else {
          this.$message({
            message: res.data.msg,
            type: 'warning'
          })
        }
      })
    },
    handleSizeChange(val) {
      console.log(`当前页: ${this.page.pageNum}`)
      console.log(`每页 ${val} 条`)
      this.page.pageSize = val
      this.fetchData()
      scrollTo(0, 800)
      // this.$nextTick(() => {
      //   this.$refs.table.bodyWrapper.scrollTop = 0
      // })
    },
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`)
      console.log(`每页: ${this.page.pageSize} 条`)
      this.page.pageNum = val
      scrollTo(0, 800)
      this.fetchData()
      // this.$nextTick(() => {
      //   this.$refs.table.bodyWrapper.scrollTop = 0
      // })
    },
    handleFilter() {
      this.page.pageNum = 1
      this.page.pageSize = 10
      this.fetchData()
    },
    addDialog() {
      this.resetTemp()
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
      this.dialogTitle = '添加'
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    add() {
      const params = new URLSearchParams()
      for (var key in this.dialogData) {
        params.append(key, this.dialogData[key])
      }

      axios.post('/mgr/goods/add', params).then(res => {
        console.log(res.data)
        if (res.data.code === 0) {
          this.$message({
            message: res.data.msg
          })
          this.dialogFormVisible = false
          this.fetchData()
        } else {
          this.$message({
            message: res.data.msg,
            type: 'warning'
          })
        }
      })
    },
    editDialog(id) {
      // this.temp = Object.assign({}, row) // copy obj
      // this.temp.timestamp = new Date(this.temp.timestamp)
      console.log(id)
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      this.dialogTitle = '编辑'
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
      this.queryById(id)
    },
    update() {
      const params = new URLSearchParams()
      for (var key in this.dialogData) {
        params.append(key, this.dialogData[key])
      }

      axios.post('/mgr/goods/updateById', params).then(res => {
        console.log(res.data)
        if (res.data.code === 0) {
          this.$message({
            message: res.data.msg
          })
          this.dialogFormVisible = false
          this.fetchData()
        } else {
          this.$message({
            message: res.data.msg,
            type: 'warning'
          })
        }
      })
    },
    deleteConfirm(id) {
      console.log(id)
      this.$confirm('您确定要删除这条记录吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const params = new URLSearchParams()
        params.append('ids[]', id)

        axios.post('/mgr/goods/deleteByIds', params).then(res => {
          console.log(res.data)
          if (res.data.code === 0) {
            this.$message({
              message: res.data.msg
            })
            this.fetchData()
          } else {
            this.$message({
              message: res.data.msg,
              type: 'warning'
            })
          }
        })
      }).catch(() => {

      })
    },
    resetTemp() {
      this.dialogData = {
        id: undefined,
        name: '',
        price: '',
        descrip: '',
        tags: '',
        services: [],
        selling1: '',
        selling2: '',
        selling3: '',
        content: ''
      }
    }
  }
}
</script>

添加依赖文件

封装请求

src/utils 添加 request2.js 文件,内容如下:

import axios from 'axios'

const BASE_URL = 'http://localhost:8080/'

axios.defaults.withCredentials = true // 带cookie
// axios.defaults.timeout=3000;
axios.defaults.baseURL = BASE_URL

export { axios, BASE_URL }

封装分页显示

分页后,页面显示可能会变形,此文件可以处理

src/utils 添加 scroll-to.js 文件,内容如下:

Math.easeInOutQuad = function(t, b, c, d) {
  t /= d / 2
  if (t < 1) {
    return c / 2 * t * t + b
  }
  t--
  return -c / 2 * (t * (t - 2) - 1) + b
}

// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
var requestAnimFrame = (function() {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
})()

/**
 * Because it's so fucking difficult to detect the scrolling element, just move them all
 * @param {number} amount
 */
function move(amount) {
  document.documentElement.scrollTop = amount
  document.body.parentNode.scrollTop = amount
  document.body.scrollTop = amount
}

function position() {
  return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
}

/**
 * @param {number} to
 * @param {number} duration
 * @param {Function} callback
 */
export function scrollTo(to, duration, callback) {
  const start = position()
  const change = to - start
  const increment = 20
  let currentTime = 0
  duration = (typeof (duration) === 'undefined') ? 500 : duration
  var animateScroll = function() {
    // increment the time
    currentTime += increment
    // find the value with the quadratic in-out easing function
    var val = Math.easeInOutQuad(currentTime, start, change, duration)
    // move the document.body
    move(val)
    // do the animation unless its over
    if (currentTime < duration) {
      requestAnimFrame(animateScroll)
    } else {
      if (callback && typeof (callback) === 'function') {
        // the animation is done so lets callback
        callback()
      }
    }
  }
  animateScroll()
}

添加到左侧菜单

vue-admin-template 添加商品页面-添加到左侧菜单


原文出处:https://www.malaoshi.top/show_1IX2LmNRpWFZ.html