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

JesseLuo

图片描述

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

项目地址:https://github.com/luosijie/vue-manager
预览地址: https://luosijie.github.io/vue-manager/#/imagelist

实现功能

  1. 图片展示

  2. 关键词搜索

  3. 分页功能

  4. 删除功能

功能分析

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

属性

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

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

阅读 15.4k

前端随笔
[链接]

前端工程师

1.7k 声望
139 粉丝
0 条评论
你知道吗?

前端工程师

1.7k 声望
139 粉丝
文章目录
宣传栏