Vue写一个图片列表分页组件

3,014 阅读5分钟

首页

这是给vue manager写的一个图片列表组件, 使用了iView组件, 目前只实现比较简单的分页、搜索和删除功能 编辑功能只是给一个链接,目的是为了跳转到其他页面进行编辑

项目地址: github.com/luosijie/vu…

预览地址: luosijie.github.io/vue-manager…

实现功能

  1. 图片展示
  2. 关键词搜索
  3. 分页功能
  4. 删除功能

功能分析

这个组件 vm-image-list 基本上分为两部分。 顶部操作区:可以关键词搜索,设置每页显示数目和分页。 底部展示区:循环使用另一个 vm-card 组件,并可以实现删除功能

属性

属性名 说明 例子
title 自定义标题 <VmImageList title="Image List">
data 列表数据 <VmImageList :data="dataImageList">
delete-ok 删除事件 <VmImageList @delete-ok="deletefn">

html结构

<template>
  <div class="vm-image-list">
    <Row class="image-list-heading vm-panel">
      <div class="panel-heading">
        //标题
        ...
      </div>
      <Row type="flex" align="middle" justify="space-between" class="panel-body">
        //操作区
        ...
      </Row>
    </Row>
    <Row class="image-list" :gutter="16">
      //图片列表展示区
      <Col :lg="6" :sm="12" class="vm-margin" v-for="item in dataShow" :key="item.id">
        //引入vm-card组件展示图片信息
        <VmCard :editable="true" :title="item.title" :img="item.img" :desc="item.desc" :detailUrl="item.detailUrl" :editUrl="item.editUrl" @delete-ok=" deleteOk(item) "></VmCard>
      </Col>
    </Row>
  </div>
</template>

操作区域

操作区域

<template>
  <div class="vm-image-list">
    <Row class="image-list-heading vm-panel">
      //标题
      <div class="panel-heading">
        {{ title }}
      </div>
      //操作区
      <Row type="flex" align="middle" justify="space-between" class="panel-body">
       //搜索
       <div class="search-bar">
          <Input placeholder="Please enter ..." v-model="keyword" style="width: 300px"></Input>
          <Button type="ghost" @click="search"><i class="fa fa-search"></i></Button>
        </div>
        //分页
        <Row type="flex" align="middle" class="page">
          //每页显示数目
          <span>Show</span>
          <Input :max="40" :min="1" :number="true" v-model="showNum" class="input-number" @on-change=" updateDataShow "></Input>
          <span class="margin-end">/ Page</span>
          //分页操作
          <span class="total">Total {{ data.length }}</span>
          <Page :total="data.length" :current="currentPage" :page-size="showNum" @on-change="pageChange"></Page>
        </Row>
      </Row>
    </Row>
    <Row class="image-list" :gutter="16">
      ...
    </Row>
  </div>
</template>

搜索功能

...
methods: {
  search: function () {
    let that = this
    let tempData = that.data
    // dataShow 用来储存需要显示的列表项目
    that.dataShow = []
    tempData.forEach(function (elem) {
      for (let i in elem) {
        if (elem[i].toString().indexOf(that.keyword) > -1) {
          that.dataShow.push(elem)
            return
          }
        }
     })
  },
}
...

分页功能

methods: {
      // 从data数据中筛选出符合分页条件的数据
      updateDataShow: function () {
        // 分页开始的项目索引
        let startPage = (this.currentPage - 1) * this.showNum
        // 分页结束的项目索引
        let endPage = startPage + this.showNum
        this.dataShow = this.data.slice(startPage, endPage)
      },
      // 点击分页组件会返回页码, 根据页码更新dataShow数据(显示的项目)
      pageChange: function (page) {
        this.currentPage = page
        this.updateDataShow()
      }

展示区域

展示区域

<template>
  <div class="vm-image-list">
    <Row class="image-list-heading vm-panel">
      ...
    </Row>
    <Row class="image-list" :gutter="16">
      // v-for循环v-card组件
      <Col :lg="6" :sm="12" class="vm-margin" v-for="item in dataShow" :key="item.id">
        <VmCard :editable="true" :title="item.title" :img="item.img" :desc="item.desc" :detailUrl="item.detailUrl" :editUrl="item.editUrl" @delete-ok=" deleteOk(item) "></VmCard>
      </Col>
    </Row>
  </div>
</template>

展示区域由独立的组件 vm-card 组成

属性
属性名 说明
type vertical 或 horizantal 图片显示在上面或显示在左边
editable Boolean 是否可编辑,可编辑显示编辑删除按钮
title String 自定义标题
img 路径 图片
desc Sring 描述:最多显示3行
detailUrl 链接 跳转到详情页
editUrl 链接 跳转到编辑页
delete-ok 事件 点击删除后的事件逻辑

<template>
  <div :class="[type === 'horizantal' ? 'vm-card-horizantal' : 'vm-card-vertical' , 'vm-panel']">
    // 图片区域
    <div class="card-img">
      <img :src="img" alt="">
      // 编辑与删除按钮区域
      <div v-if="editable && type == 'vertical'" class="control">
        <span class="edit">
          <a :href="editUrl">
            <i class="fa fa-pencil"></i>
          </a>     
        </span>
        <span class="delete">
          <i class="fa fa-trash" @click="modalDelete=true"></i>
        </span>
      </div>
    </div>
    // 内容区域
    <div class="card-desc panel-body">
      // 标题
      <h2>{{ title }}</h2>
      // 描述
      <p>{{ desc }}</p>
      <a :href="detailUrl">
        more >
      </a>
    </div>
    // 删除弹窗
    <Modal
        v-model="modalDelete"
        title="Delete"
        ok-text="OK"
        cancel-text="Cancel"
        v-on:on-ok="deleteOk">
        Are you sure to delete this data?
    </Modal>
  </div>
</template>
<script>
  export default {
    name: 'VmCard',
    props: {
      type: {
        type: String,
        default: 'vertical'
      },
      editable: {
        type: Boolean,
        default: false
      },
      title: {
        type: String,
        default: 'Title'
      },
      img: {
        type: String,
        default: require('@/assets/img/img-1.jpg')
      },
      desc: {
        type: String,
        default: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry,Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s'
      },
      detailUrl: {
        type: String,
        default: '#'
      },
      editUrl: {
        type: String,
        default: '#'
      }
    },
    data: function () {
      return {
        modalDelete: false
      }
    },
    methods: {
      deleteOk: function () {
        this.$emit('delete-ok')
      }
    }
  }
</script>

Demo数据

<template>
  <VmImageList title="ImageList" data="dataImageList"></ImageList>
</template>
<script>
  import VmImageList from '@/components/vm-image-list'
  export default {
    name: 'ImageList',
    components: {
      VmImageList
    },
    //图片删除的逻辑,删除数据后, **VmImageList** 会更新列表
    methods: {
      deletefn: function (data) {
        for (let i = 0; i < this.dataImageList.length; i++) {
          if (this.dataImageList[i].id === data.id) {
            this.dataImageList.splice(i, 1)
          }
        }
      }
    },
    //Demo模拟数据
    data: function () {
      return {
        dataImageList: [
          {
            id: '201707101552',
            title: 'Title1',
            img: require('@/assets/img/img-1.jpg'),
            desc: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry,Lorem Ipsum has been the industry\'s standard dummy text ever sincc the 1500s ly dummy tly dummy tly dummy tly dummy tly dummy tly dummy t',
            detailUrl: '#',
            editUrl: '#'
          },
          
          ...
          
          {
            id: '201707101513',
            title: 'Title12',
            img: require('@/assets/img/img-4.jpg'),
            desc: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry,Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s',
            detailUrl: '#',
            editUrl: '#'
          }
        ]
      }
    }
  }
</script>

先这样了,欢迎star