Vue学习笔记:一个图片轮播预览的手机网站,模仿手机上的相机图片预览功能,实现手机内图片预览

实验内容:

  • 使用Vue-CLI脚手架工具搭建一个Web项目vue-photo,实现一个图片轮播预览的手机网页。
  • 使用Vue组件编程方法完成主要功能,具体使用的编程技术不限。
  • 模仿手机上的相机图片预览功能,实现手机内图片预览。

先上效果图:

初始界面

上传后图片会被添加到相册底部:

点击上传按钮后会打开本地文件夹:

选中上传后:

可以通过上端的放大预览查看:

主要代码及实现方法简介:

首先在 index.js 文件里加一个路由,在主界面中通过点击 photo 进入界面,代码如下:

import Photo from '../views/Photo.vue'
{
    path: '/photo',
    name: 'Photo',
    component: Photo
  },

在component文件夹下新建一个VueGallery1.vue,作为组件完成轮播预览图片的部分,先写好页面布局,代码如下:

<template>
    <div class="vueGallery">
    <div class="activePhoto" :style="'background-image: url('+photos[activePhoto]+')'">
      <button type="button" aria-label="Previous Photo" class="previous" @click="previousPhoto()">
        <svg t="1620980045907" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1759" width="25" height="25"><path d="M514 114.3c-219.9 0-398.8 178.9-398.8 398.8S294.1 912 514 912s398.9-178.9 398.9-398.8-179-398.9-398.9-398.9z m95.6 518.3c22.9 22.9 22.9 60.2 0 83.1-22.9 22.9-60.2 22.9-83.1 0L362.4 551.6c-22.9-22.9-22.9-60.2 0-83.1l164.1-164.1c22.9-22.9 60.2-22.9 83.1 0 11.5 11.5 17.2 26.5 17.2 41.5s-5.7 30.1-17.2 41.5L487.1 510l122.5 122.6z" p-id="1760" fill="#ffffff"></path></svg>
      </button>
      <button type="button" aria-label="Next Photo" class="next" @click="nextPhoto()">
        <svg t="1620980191292" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1938" width="25" height="25"><path d="M514 114.3c-219.9 0-398.8 178.9-398.8 398.8 0 220 178.9 398.9 398.8 398.9s398.8-178.9 398.8-398.9c0-219.8-178.9-398.8-398.8-398.8z m152.9 440.4L502.8 718.8c-22.9 22.9-60.2 22.9-83.1 0-11.5-11.5-17.2-26.5-17.2-41.5s5.7-30.1 17.2-41.5l122.6-122.6-122.6-122.6c-22.9-22.9-22.9-60.2 0-83.1 22.9-22.9 60.2-22.9 83.1 0l164.1 164.1c23 23 23 60.2 0 83.1z" p-id="1939" fill="#ffffff"></path></svg>
      </button>
    </div>

    <div class="thumbnails">
      <img
           v-for="(photo, index) in photos"
           :src="photo"
           :key="index"
           @click="changePhoto(index)"
           :class="{'active': activePhoto == index}">
    </div>
  </div>
</template>

为轮播绑定点击事件后实现选择切换图片,用v-for遍历photos数组使其中的图片显示出来,Props 用来接收父组件传递的数据,在此接收父组件传来的图片数组,在钩子函数中加入键盘左右按键切换图片的功能,通过监听事件,接下来在 methods中写一些方法逻辑,包括点击列表切换图片,点击上一张下一张切换图片显示,代码如下:

props: {photos:{        
      type :Array,
      default:()=>[]      
    }
  },
  data: function () {
    return {
      activePhoto: null
    }
  },
  mounted () {
    this.changePhoto(0)
    document.addEventListener("keydown", (event) => {
      if (event.which == 37)
        this.previousPhoto()
      if (event.which == 39)
        this.nextPhoto()
    })
  },
  methods: {
    changePhoto (index) {
      this.activePhoto = index
    },
    nextPhoto () {
      this.changePhoto( this.activePhoto+1 < this.photos.length ? this.activePhoto+1 : 0 )
    },
    previousPhoto () {
      this.changePhoto( this.activePhoto-1 >= 0 ? this.activePhoto-1 : this.photos.length-1 )
    }
  }

然后新建一个Photo.vue将组件引入,同时在data中设置好以后图片的数组,代码如下:

<vue-gallery :photos="photos"></vue-gallery>

import VueGallery from "@/components/VueGallery1.vue";
components: {
    VueGallery,
  },

data: function () {
      return {
      photos: [
        require("../assets/img/lordea-home-01-min.jpg"), 
        require("../assets/img/lordea-home-02-min.jpg"),
        require("../assets/img/lordea-home-03-min.jpg"),
        require("../assets/img/lordea-home-04-min.jpg"),
      ],
    };
  },

然后是访问相册上传图片的部分,在Photo.vue中写好大概页面布局,代码如下:

<div style="width: 330px">
    <div>
        <div class="vue-uploader">
          <div class="file-list">
            <section
              v-for="(file, index) of files"
              class="file-item draggable-item"
            >
              <img :src="file.src" alt="" ondragstart="return false;" />
              <p class="file-name">{{ file.name }}</p>
              <span class="file-remove" @click="remove(index)">+</span>
            </section>
            <section v-if="status == 'ready'" class="file-item">
              <div @click="add" class="add">
                <span>+</span>
              </div>
            </section>
          </div>
          <section v-if="files.length != 0" class="upload-func">
            <div class="progress-bar">
              <section v-if="uploading" :width="percent * 100 + '%'">
                {{ percent * 100 + "%" }}
              </section>
            </div>
            <div class="operation-box">
              <button v-if="status == 'ready'" @click="submit">上传</button>
            </div>
          </section>
          <input type="file" accept="image/*" @change="fileChanged" ref="file" multiple="multiple" />
      </div>
</div>

为这些布局在methods中编写事件,首先是点击加号的add事件,调用file的click事件,代码如下:

add() {
      this.$refs.file.click(); 
 },

然后是点击提交按钮后的事件,当点击上传按钮时,将会遍历所有选中的文件,并添加到自定义的FormData中,可以方便我们对待上传的图片进行操作。在遍历file的时候,将转码为base64格式的图片push进photo的数组,前端就会刷新出刚上传的图片可以进行预览,代码如下:

submit() {
      if (this.files.length === 0) {
        console.warn("no file!");
        return;
      }
      const formData = new FormData();
      this.files.forEach((item) => {
        formData.append(item.name, item.file);
        this.photos.push(item.src);
        console.log(item.src)
      });

      setTimeout(() => {
        this.files = [];
        this.status = "ready";
      }, 1000);
},

点击待上传图片右上角的x号可以将其删除,实际上就是从file里面删除掉对应得记录,代码如下:

remove(index) {
      this.files.splice(index, 1);
    },

实现待上传队列中图片预览,就是遍历上传的file,将其添加到数组中,再通过把图片转化成base64的格式进行输出展示,代码如下:

fileChanged() {
      const list = this.$refs.file.files;
      for (let i = 0; i < list.length; i++) {
        if (!this.isContain(list[i])) {
          const item = {
            name: list[i].name,
            size: list[i].size,
            file: list[i],
          };
          this.html5Reader(list[i], item);
          this.files.push(item);
        }
      }
      this.$refs.file.value = "";
    }, 
    html5Reader(file, item) {
      const reader = new FileReader();
      reader.onload = (e) => {
        this.$set(item, "src", e.target.result);
      };
      reader.readAsDataURL(file);
},
isContain(file) {
      return this.files.find(
        (item) => item.name === file.name && item.size === file.size
      );
    },

对于已上传的图片可以在前端通过点击查看预览。

项目源码:https://gitee.com/huahua_2021/vue-photo

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值