一、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

Logo

前往低代码交流专区

更多推荐