# 内容管理-素材管理

熟悉素材管理整体业务:这些图片主要用于发布文章使用

  • 图片列表展示
  • 支持分页
  • 收藏图片
  • 删除图片
  • 上传图片

# 组件与路由配置

目标:配置素材管理组件和路由映射

  • 配置组件链接
<el-menu-item index="/home/image">素材管理</el-menu-item>
  • 配置路由映射
// 素材管理
import ImageList from '@/views/image/index.vue'
{ path: 'image', component: ImageList },

# 基本页面布局

目标:实现素材管理组件基本布局

<div class="image">
  <el-card>
    <div slot="header">
      <div>素材管理</div>
    </div>
    <!-- Tab菜单 -->
    <div class="btns-wrapper">
      <el-radio-group size="small" >
        <el-radio-button :label="false">全部</el-radio-button>
        <el-radio-button :label="true">收藏</el-radio-button>
      </el-radio-group>
      <el-button style="float:right" type="primary" size="small">添加素材</el-button>
    </div>
  </el-card>
  <!-- 图片列表 -->
  <div class="img-list"></div>
</div>

# 图片数据渲染

目标:动态渲染图片列表数据

  • 获取接口数据
import request from '@/utils/request.js'

// 加载图片列表数据
export const loadImageList = (params) => {
  return request({
    method: 'get',
    url: '/user/images',
    params: params
  })
}
//----------------------------------------
methods: {
  async loadImageList () {
    try {
      const ret = await loadImageList()
      this.list = ret.data.results
      this.total = ret.data.total_count
    } catch (e) {
      console.log(e)
      this.$message.error('获取图片列表数据失败')
    }
  }
},
created () {
  this.loadImageList()
}
  • 渲染图片列表数据
<div class="img-list">
  <div :key='item.id' v-for='item in list' class="img-item">
    <el-image :src="item.url">
      <div slot="error">
        <img src="../../assets/imgs/error.gif"  />
      </div>
    </el-image>
    <div class="option">
      <span class="el-icon-star-off"></span>
      <span class="el-icon-delete"></span>
    </div>
  </div>
</div>
  • 列表样式
.img-list {
  padding-top: 30px;
  .img-item {
    width: 180px;
    height: 180px;
    border: 1px dashed #ddd;
    position: relative;
    display: inline-block;
    margin: 0 30px 20px;
    img {
      width: 100%;
      height: 100%;
      display: block;
    }
    .option {
      height: 30px;
      width: 100%;
      background: rgba(0, 0, 0, 0.3);
      position: absolute;
      left: 0;
      bottom: 0;
      text-align: center;
      line-height: 30px;
      span {
        color: #fff;
        margin: 0 20px;
      }
      .red {
        color: red;
      }
    }
  }
}

# 分页功能

目标:实现图片列表的分页功能

  • 分页基本布局
    • hide-on-single-page如果只有一页数据是否隐藏分页条
<!-- 分页区域 -->
<el-pagination
  background
  layout="prev, pager, next"
  :total="total"
  :current-page="filterParams.page"
  :page-size="filterParams.per_page"
  @current-change="changePager"
  :hide-on-single-page="false"
></el-pagination>
  • 页码切换
changePager (page) {
    // 修改当前页码
    this.filterParams.page = page
    // 加载新的页码数据
    this.loaderImageList()
},

# 全部与收藏切换

目标:控制全部与收藏标签的切换

  • 事件绑定
<el-radio-group @change="handeChange" v-model="filterParams.collect" size="small">
  • 功能实现
handeChange () {
    // 控制全选和收藏按钮的切换
    this.filterParams.page = 1
    this.loadImageList()
}

# 收藏素材

目标:实现收藏和取消素材功能(点击收藏和取消收藏)

1、绑定收藏按钮的点击事件

2、调用接口实现收藏功能

3、按钮图标的样式发生变化

  • 绑定按钮事件
<span
  @click="toggleStatus(item)"
  class="el-icon-star-off"
  :class="{red: item.is_collected}"
></span>
  • 实现收藏与取消收藏功能
// 控制收藏功能
async toggleCollect (item) {
  // 调用接口实现收藏功能
  try {
    await toggleCollect({
      id: item.id,
      collect: !item.is_collected
    })
    // 修改页面的图标的状态
    item.is_collected = !item.is_collected
  } catch (e) {
    console.log(e)
    this.$message.error('收藏或者取消收藏失败')
  }
},

# 删除素材

目标:实现删除素材功能

1、绑定删除按钮的点击事件

2、调用接口进行删除

3、刷新页面(把页面中的指定数据删除)

  • 绑定按钮事件
<span @click="deleteImage(item)" class="el-icon-delete"></span>
  • 实现删除素材功能
// 删除图片
deleteImage (item) {
  this.$confirm('确定要删除吗?')
    .then(async () => {
      // 调用接口删除后端数据
      await deleteImage(item.id)
      // 查看要删除的图片的数据的索引
      const index = this.list.findIndex(img => {
        return img === item
      })
      // 根据索引删除
      this.list.splice(index, 1)
      // this.loadImageList()
    })
    .catch(e => {
      if (e === 'cancel') {
        console.log('取消删除')
      } else {
        this.$message.error('删除图片失败')
      }
    })
},

# 上传素材

# 需求介绍

  • 点击【上传图片】按钮进行弹窗
  • 点击【点击选择图片】按钮,打开选择图片对话框
  • 点击【开始上传】按钮,进行上传,上面显示预览效果

# 对话框效果

目标:实现对话框显示和隐藏控制

  • 对话框布局
<el-dialog
  title="提示"
  :visible.sync="dialogVisible"
  width="30%"
  center>
  <span>需要注意的是内容是默认不居中的</span>
  <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  </span>
</el-dialog>
  • 点击显示对话框
<el-button @click='dialogVisible=true' style="float:right" type="primary" size="small">添加素材</el-button>

# 准备上传组件

目标:实现上传组件的基本布局

  1. action 上传图片的请求地址
  2. headers 上传图片的请求头
  3. name 后端更加该名称得到图片
  4. show-file-list 控制是否显示图片列表
  5. on-success 上传成功的回调函数
<el-dialog
  title="上传图片"
  :visible.sync="dialogVisible"
  width="400px">
  <!-- action表示上传图片的地址 -->
  <!-- headers表示接口调用的请求头 -->
  <!-- name 上传文件的参数名称 -->
  <!-- on-success表示上传成功的回调函数 -->
  <!-- show-file-list 表示是否显示文件列表 -->
  <el-upload
    :headers='headers'
    :show-file-list="false"
    :on-success="uploadSuccess"
    name="image"
    :action="uploadURL">
    <i class="el-icon-upload"></i>
  </el-upload>
</el-dialog>

# 实现上传功能

目标:实现文件上传功能

// 上传成功的回调函数
uploadSuccess (ret) {
  // 如果上传成功,ret表示接口返回的结果
  // 1、预览图片;2、1秒后隐藏窗口;3、刷新列表
  this.previewImg = ret.data.url
  setTimeout(() => {
    this.dialogVisible = false
    this.loadImageList()
  }, 1000)
},