【Vue + Koa 前后端分离项目实战6】使用开源框架==>快速搭建后台管理系统 -- part6 前端实现期刊列表管理【增删查改】

要把努力当成一种习惯,而不是一时热血。

对应后端部分章节回顾:

【Vue + Koa 前后端分离项目实战4】使用开源框架==>快速搭建后台管理系统 -- part4 后端实现【增删改查】功能_小白Rachel的博客-CSDN博客


目录

一、前端项目准备

1.运行项目

2.项目目录介绍

3.添加路由

二、期刊列表展示

1.编写页面列表效果

2.(核心)模型层定义方法获取接口数据

3.最终页面效果展示 

三、期刊新增功能实现

1.编写前端页面逻辑

2.新增按钮逻辑

3.在model层添加方法

4.效果展示

四、期刊编辑功能实现

1.(核心)编辑按钮触发弹框

2.在model层编写方法 

3. 效果展示

五.期刊删除功能实现

1.编写前端页面逻辑

2. 在model层编写方法 

3.效果展示

本篇核心重难点:


本章效果展示:(增删改查)

一、前端项目准备

1.运行项目

npm run serve

2.项目目录介绍

前端文件写在views目录下,自定义模块的文件夹即可

路由配置文件在config下的stage文件夹下,新建模块路由,并在index.js引用

接口函数写在models下的js文件

官方文档: Layout布局 | Lin CMS

3.添加路由

在config的stage文件夹下新建content.js

const contentRouter = {
  name: null,
  title: '期刊管理',
  type: 'folder', // 类型: folder, tab, view
  icon: 'iconfont icon-tushuguanli',
  order: 3,
  inNav: true,
  children: [
    {
      title: '内容管理',
      type: 'view',
      name: 'content',
      route: '/content/list',   // 路由地址
      filePath: 'views/content/List.vue',
      inNav: true,
      icon: 'iconfont icon-tushuguanli',
    },
  ],
}

export default contentRouter

定义如下配置之后,在index.js中引入contentRouter。

 刷新页面,可以看到侧边栏添加了一个新的模块【期刊管理】

二、期刊列表展示

1.编写页面列表效果

在views目录下新建content文件夹,并添加List.vue文件。并添加如下代码(对于前端开发,这些很简单,么有什么要讲的)

<template>
  <div class="container">
    <div class="title">期刊内容列表</div>
    <div class="add-button">
      <el-button type="primary" @click="handleAdd()">新增内容</el-button>
    </div>
    <div class="table-container">
      <el-table :data="contentList">
        <el-table-column label="序号" width="60" type="index"></el-table-column>
        <el-table-column label="类型" prop="type">
          <template slot-scope="scope">
            {{type[scope.row.type]}}
          </template>
        </el-table-column>
        <el-table-column label="标题" prop="title"></el-table-column>
        <el-table-column label="期刊介绍" prop="content"></el-table-column>
        <el-table-column label="音乐外链" prop="url">
          <template slot-scope="scope">
            <audio controls v-if="scope.row.url">
              <source :src="scope.row.url">
            </audio>
          </template>
        </el-table-column>
        <el-table-column label="发布时间" prop="pubdate"></el-table-column>
        <el-table-column label="点赞数" prop="fav_nums"></el-table-column>
        <el-table-column label="是否有效" prop="status">
          <template slot-scope="scope">
           <el-tag v-if="scope.row.status === 1" type="success">有效</el-tag>
            <el-tag v-else type="info">无效</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right">
          <template slot-scope="scope">
            <el-button @click="handleEdit(scope.row)" v-permission="{ permission: '编辑内容', type:'disabled'}">编辑</el-button>
            <el-button @click="handleDelete(scope.row)" v-permission="{ permission: '删除内容', type:'disabled'}" type="danger">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script>
import { ContentModel } from '@/models/content'

export default {
  name: 'List',
  data() {
    return {
      contentList: [],
      type: {
        100: '电影',
        200: '音乐',
        300: '句子',
      }
    }
  },
  
}
</script>

<style scoped lang="scss">
.container {
  .title {
    height: 59px;
    line-height: 59px;
    color: $parent-title-color;
    font-size: 16px;
    font-weight: 500;
    text-indent: 40px;
    border-bottom: 1px solid #dae1ec;
  }
  .add-button {
    padding: 20px 40px;
  }
  .table-container {
    padding: 0 40px 20px 40px;
  }
}
</style>

2.(核心)模型层定义方法获取接口数据

这一部分对于纯前端开发来说还是比较新的。林间有风框架在前端也用到了【模型层】的概念,把页面和接口分离开来,并且使用类定义。有点类似react的model.tsx,也类似Vue的api目录。但是只是思想上类似,写法上完全不同,具体可以参考官方文档。

(1)在models的content.js文件下编写调用接口的函数

// models/content.js
import { get } from '@/lin/plugins/axios'

class Content {
  static async getContentList() {
    const res = await get('v1/content')
    return res
  }
}

export { Content as ContentModel }

(2)在页面使用该方法。前端逻辑不用说,主要是写法注意一下await ContentModel.getContentList()

// views/content/List.vue
created() {
    this.getContentList()
  },
  methods: {
    async getContentList() {
      this.contentList = await ContentModel.getContentList()
    },
  },

3.最终页面效果展示 

目前,只实现了列表接口,并完成了页面的布局,新增、编辑、修改功能待实现。

三、期刊新增功能实现

1.编写前端页面逻辑

(1)需要在页面添加dialog对话框。

(2)添加表单项的属性,添加必填项校验规则(注意:图片上传组件的使用)

<template>
  <div class="container">
    <div class="title">期刊内容列表</div>
    <div class="add-button">
      <el-button type="primary" @click="handleAdd()">新增内容</el-button>
    </div>
    <div class="table-container">...省略   
    </div>
    <el-dialog
      :title="dialogTitle"
      width="800px"
      :visible.sync="showDialog"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      @close="resetForm"
    >
      <el-form ref="form" :model="temp" label-width="90px" :rules="rules">
        <el-form-item label="内容封面" prop="image">
          <upload-imgs ref="uploadEle" :value="contentImgData" :max-num="1"></upload-imgs>
        </el-form-item>
        <el-form-item label="内容类型" prop="type">
          <el-radio v-model="temp.type" :label="100">电影</el-radio>
          <el-radio v-model="temp.type" :label="200">音乐</el-radio>
          <el-radio v-model="temp.type" :label="300">句子</el-radio>
        </el-form-item>
        <el-form-item label="内容标题" prop="title">
          <el-col :span="11">
            <el-input v-model="temp.title"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="内容介绍" prop="content">
          <el-col :span="11">
            <el-input type="textarea" :rows="2" v-model="temp.content"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="音乐外链" prop="url" v-if="temp.type===200">
          <el-col :span="11">
            <el-input v-model="temp.url"></el-input>
          </el-col>
        </el-form-item>
        <el-form-item label="发布时间" prop="pubdate">
          <el-date-picker v-model="temp.pubdate" type="date" placeholder="选择日期"></el-date-picker>
        </el-form-item>
        <el-form-item label="有效状态" prop="url">
          <el-switch v-model="temp.status" :active-value="1" :inactive-value="0"></el-switch>
        </el-form-item>
      </el-form>
      <sapn slot="footer" class="dialog-footer">
        <el-button @click="showDialog = false">取 消</el-button>
        <el-button type="primary" @click="dialogTitle == '添加内容' ? confirmAdd() : confirmEdit()">保 存</el-button>
      </sapn>
    </el-dialog>
  </div>
</template>

<script>
import { ContentModel } from '@/models/content'
import UploadImgs from '../../components/base/upload-imgs/index'

export default {
  name: 'List',
  components: { UploadImgs },
  data() {
    return {
      contentList: [],
      type: {
        100: '电影',
        200: '音乐',
        300: '句子',
      },
      dialogTitle: '',
      showDialog: false,
      temp: {
        id: null,
        image: null,
        type: null,
        title: null,
        content: null,
        url: null,
        pubdate: '',
        status: '',
      },
      rules: {
        image: [{ required: true, message: '请输入封面内容', trigger: 'blur' }],
        type: [{ required: true, message: '请选择内容类型', trigger: 'blur' }],
        title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
        content: [{ required: true, message: '请输入内容介绍', trigger: 'blur' }],
        url: [{ required: true, message: 'url格式不正确', trigger: 'blur' }],
        pubdate: [{ required: true, message: '请选择发布时间', trigger: 'blur' }],
      },
      contentImgData: [],
    }
  },
  created() {
    this.getContentList()
  },
  methods: {
    async getContentList() {
      console.log('hrehre')
      this.contentList = await ContentModel.getContentList()
    },
    handleEdit() {},
    handleDelete() {},
    handleAdd() {},
    resetForm() {},
    confirmAdd() {},
    confirmEdit() {},
  },
}
</script>

2.新增按钮逻辑

(1)点击“新增”按钮,handleAdd()方法调起对话框

handleAdd() {
      this.dialogTitle = '添加内容'
      this.showDialog = true
},

(2)编写重置表单resetForm()函数,主要负责清空表单,并重置图片列表数据 

resetForm() {
      this.contentImgData = []
      this.$refs.form.resetFields()
},

(3)编写提交操作。对话框点击“保存”按钮时,判断是新增操作或者编辑操作,如果是编辑操作,可看下一小节执行confirmEdit()方法,如果是新增操作,执行confirmAdd()方法。新增不需要id字段,需要删除。完成之后关闭对话框,刷新列表。

async confirmAdd() {
      const images = await this.$refs.uploadEle.getValue() // 获得image对象
      this.temp.image = images.length < 1 ? '' : images[0].src // 获取src
      this.$refs.form.validate(async valid => {
        if (valid) {
          delete this.temp.id
          const res = await ContentModel.addContent(this.temp)
          this.showDialog = false
          this.$message.success(res.message)  // 提示信息
          await this.getContentList()  // 刷新列表
        }
      })
},

使用框架自带的上传功能获取到images对象,其中对象属性值如下: 

判断this.temp.image的数组长度,如果有值取其src

3.在model层添加方法

类似列表功能,需要在模型层编写调用接口的方法,并在前端页面调用模型的方法。

// models/content.js
static async addContent(data) {
    const res = await post('v1/content', { ...data })
    return res
  }

4.效果展示

四、期刊编辑功能实现

1.(核心)编辑按钮触发弹框

(1)添加点击事件。新增和编辑复用相同的对话框代码

<el-button @click="handleEdit(scope.row)" v-permission="{ permission: '编辑内容', type:'disabled'}">编辑</el-button>

 差异:编辑需要回显数据、内容类型不能修改

(2)回显数据,注意修改标题、初始化图片

handleEdit(row) {
      this.dialogTitle = '编辑内容'
      this.showDialog = true
      // 表单内容初始化
      this.temp = row
      this.contentImgData.push({ display: row.image })
    },

 图片回显时需要修改【后端lin-cms-koa】代码.

首先,在model文件夹下的sentence.js movies.js music.js的image中添加get方法。

添加代码的逻辑:调用koa框架提供的方法,在调用get方法时执行方法中的逻辑,为了获取配置参数的值并和图片的相对地址进行拼接。最终实现完整的url。

image: {
      type: Sequelize.STRING(64),
      get () {
        const image = this.getDataValue('image')
        return config.getItem('localMainImgUrlPrefix') + image
      }
    },

 其次,在config文件夹下的setting.js最后添加配置项

localMainImgUrlPrefix: 'http://localhost:5000/assets/'。

当然最终部署项目只需要修改配置项即可。

 最终,项目上传的文件会保存在assets文件夹中

2.在model层编写方法 

(1)在model层的content.js 编写editContent方法 接受两个参数:id、表单参数

// 编辑
  static async editContent(id, data) {
    const res = await put(`v1/content/${id}`, { ...data })
    return res
  }

 (2)在页面调用模型方法实现提交编辑

注意:编辑时的this.temp.image需要取images[0].display

async confirmEdit() {
      const images = await this.$refs.uploadEle.getValue() // 获得image对象
      this.temp.image = images.length < 1 ? '' : images[0].display // 获取url地址
      this.$refs.form.validate(async valid => {
        if (valid) {
          const id = this.temp.id
          delete this.temp.id
          const res = await ContentModel.editContent(id, this.temp)
          this.showDialog = false
          this.$message.success(res.message)
          await this.getContentList()
        }
      })
    },

此时,需要 修改【后端lin-cms-koa】代码

修改service文件夹下的content.js中的editContent方法中的image字段。传入的url是完整路径,我们需要对url进行修改,只获取相对路径。

// 把完整的url取出,只获取相对路径
    params['image'] = params['image'].split(config.getItem('localMainImageUrlPrefix'))[1]

3. 效果展示

五.期刊删除功能实现

1.编写前端页面逻辑

(1)添加删除确认对话框,同时添加字段

<el-dialog title="提示" :visible.sync="showDeleteDialog" width="400px">
      <span>确认删除内容</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="showDeleteDialog = false">取 消</el-button>
        <el-button type="danger" @click="confirmDelete()">删 除</el-button>
      </span>
    </el-dialog>

(2)点击删除按钮,打开对话框,传id

handleDelete(row) {
      this.showDeleteDialog = true
      this.temp.id = row.id
      this.temp.type = row.type
    },

2. 在model层编写方法 

// 删除
  static async deleteContent(id, type) {
    const res = await _delete(`v1/content/${id}`, { type })
    return res
  }

在页面调用模型方法

async confirmDelete() {
      const res = await ContentModel.deleteContent(this.temp.id, this.temp.type);
      this.showDeleteDialog = false
      this.$message.success(res.message)
      this.getContentList()
    }

3.效果展示


 

本篇核心重难点: 

1.在前端编写模型层方法,实现接口调用的模型封装。

2.编辑操作时回显图片==>需要添加配置项,拼接url完整路径。同时,提交操作时,只提交url相对路径


往期回顾:

第一节:简单介绍了林间有风框架

【Vue + Koa 前后端分离项目实战】使用开源框架==>快速搭建后台管理系统 -- part1 项目搭建_小白Rachel的博客-CSDN博客_vue快速搭建管理系统

第二到第五节:展开讲解后端部分【期刊列表】【最新期刊】的增删查改功能

【Vue + Koa 前后端分离项目实战2】使用开源框架==>快速搭建后台管理系统 -- part2 后端新增期刊功能实现_小白Rachel的博客-CSDN博客_vue+koa

【Vue + Koa 前后端分离项目实战3】使用开源框架==>快速搭建后台管理系统 -- part3 权限控制+行为日志_小白Rachel的博客-CSDN博客_koa权限管理

【Vue + Koa 前后端分离项目实战4】使用开源框架==>快速搭建后台管理系统 -- part4 后端实现【增删改查】功能_小白Rachel的博客-CSDN博客_利用koa搭后台管理系统

【Vue + Koa 前后端分离项目实战5】使用开源框架==>快速搭建后台管理系统 -- part5 后端实现最新期刊列表管理【增删查改】_小白Rachel的博客-CSDN博客

第六到第七节:展开讲解前端功能实现

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白Rachel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值