Vue 动态加载public图片和图片预览例子
一、vue 静态资源文件夹Vue 有两个存放静态资源的文件夹:assets和public。1、 assets文件夹使用require()方法加载静态资源,如:require('./assets/image/success.png')这里的文件经过webpack处理过的,require方法的参数不支持变量,只能存文件的路径,因此加载图片时不能动态获取。2、public文件夹(以前vue1.0版本叫s
一、vue 静态资源文件夹
Vue 有两个存放静态资源的文件夹:assets和public。
1、 assets文件夹
使用require()方法加载静态资源,如:
require('./assets/image/success.png')
这里的文件经过webpack处理过的,require方法的参数不支持变量,只能存文件的路径,因此加载图片时不能动态获取。
2、public文件夹(以前vue1.0版本叫static)
public文件夹的文件是不经过webpack处理,打包时直接把public下的文件复制到打包后的dist的目录下的。一般需要动态获取文件,或者文件很多时使用。
public的文件直接使用process.env.BASE_URL + public下文件的目录路径,如:
data () {
return {
publicPath: process.env.BASE_URL
}
}
<img :src="`${publicPath}success.png`">
3、官网assets和public文件介绍
https://cli.vuejs.org/zh/guide/html-and-static-assets.html#public-%E6%96%87%E4%BB%B6%E5%A4%B9
二、例子应用环境
1、Vue
Vue 2.6 + Router 3.2 + Vuex 3.4 + Cli 4.5
2、图片插件
vue-lazyload(图片懒加载)、v-viewer(图片预览)、vue-cool-lightbox(图片预览)
三、例子截图
1、PC
2、手机
3、v-viewer图片预览插件
4、vue-cool-lightbox图片预览插件
四、例子代码
1、
(1)public图片动态加载主要用到require.context()的方法
require.context(directory, useSubdirectories, regExp)
- directory: 要查找的文件路径
- useSubdirectories: 是否查找子目录
- regExp: 要匹配文件的正则
(2)
ImgDisplayTest.vue:
<template>
<div class="ImgDisplayTest">
<main>
<!-- 1、如果是使用 CoolLightBox图片预览插件(对手机屏幕支持还可以,但是不能缩放图片),需要使用下面CoolLightBox标签,并且删掉下面的 @click="showImg(index)" -->
<!--参数说明items:图片数组,index:图片数组下标,@close预览界面关闭后的回调,fullScreen:是否显示全屏按钮 -->
<!-- <CoolLightBox
:items="images"
:index="imageIndex"
@close="imageIndex = null"
:fullScreen="true">
</CoolLightBox> -->
<section class="img-list">
<article
@click="imageIndex = index"
v-for="(m, index) in imgList"
:key="index"
class="item"
>
<div class="img-wrapper">
<!--2、如果使用的是 v-viewer图片预览插件(对手机屏幕适应不是很好,但是能缩放图片),注释上面CoolLightBox的标签 ,@click要写 showImg(index) -->
<!-- v-lazy:图片懒加载 -->
<img @click="showImg(index)" v-lazy="m.src" />
<!-- <img v-lazy="m.src" /> -->
</div>
</article>
</section>
</main>
</div>
</template>
<script>
export default {
name: "ImgDisplayTest",
data() {
return {
//public文件夹路径
publicPath: process.env.BASE_URL,
//存储图片数组对象
imgList: [],
//存储图片数组
images: [],
//图片数组下标
imageIndex: null,
//当前设备屏幕宽度
screenWidth: 0,
};
},
methods: {
//根据参数动态获取哪个文件夹的图片文件列表
getPublicImgFiles(type){
switch(type){
case "1":
//require.context()第一个参数是“public中文件所在路径”,不能是变量;
//第二个参数“是否遍历文件的子目录”;
//第三个参数是“匹配文件的正则”,这里是匹配png、jpg的图片
return {path:"img/fantasy/", files: require.context("/public/img/fantasy", false, /.png|jpg$/)};
case "2":
return {path:"img/lanscape/",files: require.context("/public/img/lanscape", false, /.png|jpg$/)};
}
},
//获取Public文件夹的图片
getPublicImg(type) {
//存图片路径数组变量
this.imgList = new Array();
this.images = new Array();
const filesObj = this.getPublicImgFiles(type);
const files = filesObj.files;
let index = 0;
// 遍历输出匹配结果
files.keys().forEach((path) => {
//path为./的文件名
console.log(path);
//匹配path为./xx的格式,匹配./的后面的部分名称
const fileName = path.replace(/(.*\/)*([\s\S]*?)/gi, "$2");
//使用this.publicPath 拼接图片路径
const filePath = this.publicPath + filesObj.path + fileName;
console.log(filePath);
index++;
//存储图片
this.imgList.push({ id: index, title: fileName, src: filePath });
this.images.push(filePath);
});
console.log(this.imgList);
},
// v-viewer库的图片预览方法
showImg(index) {
let options = {
initialViewIndex: index //当前显示的图片下标
};
//手机屏幕
if (this.screenWidth !== undefined && this.screenWidth < 768) {
options = {
navbar: false, //不显示缩略图导航栏,手机上太卡了
title: false, //不显示缩略图片标题
rotatable: false, //去掉图片旋转按钮
scalable: false, //去掉图片翻转按钮
initialViewIndex: index //当前显示的图片下标
};
}
// v-viewer控件Api
this.$viewerApi({
images: this.images,
index: index, //当前显示的图片数组下标
options: options,
});
},
},
created: function () {
//获取当前屏幕
this.screenWidth = window.screen.width;
//根据参数动态获取哪个文件夹的图片
this.getPublicImg("1");
},
};
</script>
<style scoped>
.img-list {
display: grid;
grid-template-columns: repeat(4, 25%);
justify-items: center;
}
.img-list .item {
width: 330px;
height: 210px;
border: none;
outline: none;
cursor: pointer;
margin: 25px 25px;
}
.img-wrapper{
width: 100%;
height: 100%;
}
.img-list .item img {
width: 100%;
height: 100%;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
-moz-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.33);
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.33);
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.33);
}
/* 手机屏幕 */
@media screen and (max-width: 768px) {
.img-list {
grid-template-columns: 100%;
}
.img-list .item {
width: 100%;
margin: 10px 0;
height: 250px;
}
}
/* 平板 */
@media screen and (min-width: 768px) and (max-width: 992px) {
.img-list {
grid-template-columns: repeat(2, 50%);
}
.img-list .item {
width: auto;
margin: 15px 20px;
}
}
/* 平板/小屏幕低分辨率PC */
@media screen and (min-width:992px) and (max-width: 1200px) {
.img-list {
grid-template-columns: repeat(3, 33.33%);
}
.img-list .item {
width: 300px;
margin: 15px;
}
}
/* PC */
@media screen and (min-width: 1200px) and (max-width:1408px) {
.img-list {
grid-template-columns: repeat(3, 33.33%);
}
}
</style>
2、Router
index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path : '',
redirect : '/imgdisplaytest'//默认跳转路由
},
{
path:'/imgdisplaytest',
name:'ImgDisplayTest',
//路由懒加载
component:()=>import('../views/ImgDisplayTest')
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
3、main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* 引入VueLazyload图片懒加载库,npm安装:npm i vue-lazyload -S */
import VueLazyload from 'vue-lazyload'
/*使用VueLazyload插件*/
Vue.use(VueLazyload)
//VueLazyload配置项
Vue.use(VueLazyload, {
preLoad: 1.3,
error: require('./assets/image/err.png'),
loading: require('./assets/image/loading.gif'),
attempt: 1,
listenEvents: ['scroll']
})
/* 引入v-viewer图片预览库,npm 安装:npm install v-viewer */
import Viewer from 'v-viewer'
import 'viewerjs/dist/viewer.css'
//viewer设置
Vue.use(Viewer,{
defaultOptions: {
zIndex: 9999,
inline: true, //启用inline模式
button: true, //显示右上角关闭按钮
navbar: true,//显示缩略图导航栏
title: true, //显示当前图片标题
toolbar: true, //显示工具栏
tooltip: true, //显示缩放百分比
movable: true, //图片是否可移动
zoomable: true, //图片是否可缩放
rotatable: true, //图标是否可旋转
scalable: true, //图片是否可翻转
transition: true, //使用css3过渡
fullscreen: true, //播放是否全屏
keyboard: true, //是否支持键盘
// url: 'src'//设置大图片的url
}
});
// Viewer.setDefaults({
// Options: { inline: true, button: false, navbar: false, title: true, toolbar: false, tooltip: true, movable: true, zoomable: false, rotatable: true, scalable: true, transition: true, fullscreen: true, keyboard: true, url: 'data-source' }
// })
/* 引入vue-cool-lightbox 图片预览库,npm 安装:npm install --save vue-cool-lightbox */
import CoolLightBox from 'vue-cool-lightbox'
import 'vue-cool-lightbox/dist/vue-cool-lightbox.min.css'
Vue.use(CoolLightBox)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
4、App.vue
<template>
<div id="app">
<!-- <div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div> -->
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
body{
box-sizing: border-box;
}
@media screen and (max-width: 768px) {
html{
width: 100%;
margin: 0;
}
body{
width: 100%;
margin: 0 !important;
}
main{
padding: 0 15px;
}
}
</style>
5、store(没用到)
index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})
6、vue.config.js
const webpack = require("webpack");
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
devServer: {
port: 8081, // 端口号
},
};
7、package.json
{
"name": "vueloadimg",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e"
},
"dependencies": {
"core-js": "^3.6.5",
"img-vuer": "^0.19.3",
"plugin-photo-swiper": "^0.1.6",
"v-viewer": "^1.6.3",
"vue": "^2.6.11",
"vue-cool-lightbox": "^2.7.4",
"vue-lazyload": "^1.3.3",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-e2e-nightwatch": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-unit-jest": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/test-utils": "^1.0.3",
"chromedriver": "91",
"vue-template-compiler": "^2.6.11"
}
}
8、assets和public
demo地址:
gitee
更多推荐
所有评论(0)