本文将vue-cli的使用和图片瀑布流放在一块儿来说,主要是我本身作着两方面的练习。其实若是只是写个单页面的图片瀑布流效果也不用专门搭建一个vue-cli项目。须要看代码的小伙伴能够在个人github中自行查看。css
一、首先检查你的node版本,vue-cli须要node8.9以上的版本,若是版本不够请自行升级vue
二、安装vue-cli
npm install -g @vue/cli复制代码
注意:若是之前安装过全局的旧版vue-cli的话,你须要先卸载而后再安装新版本node
npm uninstall vue-cli -g
npm install -g @vue/cli
复制代码
三、搭建项目c++
vue create xxx(这里的xxx是你的项目名称)复制代码
四、选择配置方式git
default 是使用默认配置 Manually select features 是自定义配置
es6
若是选择默认配置的话就一路回车,若是是自定义配置的话后面会陆续弹出一些选项github
五、自定义配置选项ajax
Babel:支持es6语法转换vue-cli
TypeScript:微软提供的js超集npm
Progressive Web App (PWA) Support:渐进式的网页应用程序。
Router:路由
Vuex:Vuex是Vue.js应用程序的状态管理模式+库
CSS Pre-processors:Sass/Less预处理器
Linter / Formatter:代码风格检查
Unit Testing:支持单元测试
E2E Testing:支持E2E测试
注意:空格是选中/取消,选择完以后enter就好了
六、配置完毕,等待下载
七、启动项目
cd project-name // 进入项目根目录
npm run serve // 运行项目复制代码
八、项目目录分析
在src里面
什么是图片瀑布流呢,简单来讲就是将不少大小不一的图片尽可能整齐的排列起来了,本文采用的是等宽布局,固定列宽,而后每次往最短的列里面填充图片。
基本思路:
一、根据窗口宽度和列数计算每列的宽度
二、找到最短的列
三、根据列号,图片宽度,高度等计算位置
四、往里面添加图片
五、优化,自适应窗口宽度(监听窗口的resize事件)
如今来看一下代码,我会在相应的地方放上注释:
<template>
<div class="v-waterfall-content" id="v-waterfall">
<div v-for="(img,index) in waterfallList"
:key="index"
class="v-waterfall-item"
:style="{top:img.top+'px',left:img.left+'px',width:ImgWidth+'px',height:img.height}">
<img :src="img.src" alt="">
</div>
</div>
</template>
<script>
export default {
name: "pic-waterfall",
data(){
return {
waterfallList:[],
imgArr:[
require('./assets/images/1 (13).jpeg'),
require('./assets/images/1 (12).jpeg'),
require('./assets/images/1 (11).jpeg'),
require('./assets/images/1 (10).jpeg'),
require('./assets/images/1 (9).jpeg'),
require('./assets/images/1 (8).jpeg'),
require('./assets/images/1 (7).jpeg'),
require('./assets/images/1 (6).jpeg'),
require('./assets/images/1 (5).jpeg'),
require('./assets/images/1 (4).jpeg'),
require('./assets/images/1 (3).jpeg'),
require('./assets/images/1 (2).jpeg'),
require('./assets/images/1 (1).jpeg'),
require('./assets/images/1 (1).gif'),
require('./assets/images/1.jpg'),
require('./assets/images/2.jpg'),
require('./assets/images/3.jpg'),
require('./assets/images/4.jpg'),
require('./assets/images/5.jpg'),
require('./assets/images/6.jpg'),
require('./assets/images/7.jpg'),
require('./assets/images/8.jpg'),
require('./assets/images/9.jpg'),
require('./assets/images/10.jpg'),
require('./assets/images/11.jpg'),
require('./assets/images/12.jpg'),
require('./assets/images/13.jpg'),
require('./assets/images/14.jpg'),
require('./assets/images/15.jpg'),
require('./assets/images/16.jpg'),
require('./assets/images/17.jpg'),
require('./assets/images/18.jpg'),
require('./assets/images/19.jpg'),
require('./assets/images/20.jpg'),
],
ImgWidth:'',
ImgCol:5,
ImgRight:10,
ImgBottom:10,
deviationHeight:[],
imgList:[],
screenWidth:document.body.clientWidth,
}
},
created() {
for (let i = 0;i < this.imgArr.length;i++){
this.imgList.push(this.imgArr[i]);
}
},
mounted(){
this.calculationWidth();
const that = this;
//挂载window的resize事件
window.onresize = () => {
return (() => {
window.screenWidth = document.body.clientWidth
that.screenWidth = window.screenWidth
})()
}
},
watch:{
//使用vue的watch来处理窗口的变化
screenWidth(val){
// 为了不频繁触发resize函数致使页面卡顿,使用定时器
if(!this.timer){
// 一旦监听到的screenWidth值改变,就将其从新赋给data里的screenWidth
this.screenWidth = val
this.timer = true
let that = this
setTimeout(function(){
that.calculationWidth(); //从新计算图片宽度
that.timer = false
},400)
}
},
},
methods:{
//计算每一个图片的宽度
calculationWidth(){
this.ImgWidth = (this.screenWidth-this.ImgRight*this.ImgCol)/this.ImgCol;
//初始化偏移高度数组
this.deviationHeight = new Array(this.ImgCol);
for (let i = 0;i < this.deviationHeight.length;i++){
this.deviationHeight[i] = 0;
}
this.imgPreloading()
},
//图片预加载
imgPreloading(){
this.waterfallList=[];
for (let i = 0;i < this.imgList.length;i++){
let aImg = new Image();
aImg.src = this.imgList[i];
aImg.onload = aImg.onerror = ()=>{
let imgData = {};
imgData.height = this.ImgWidth/aImg.width*aImg.height; //按比例计算图片高度
imgData.src = this.imgList[i];
this.waterfallList.push(imgData);
this.rankImg(imgData); //渲染页面
}
}
},
//瀑布流布局
rankImg(imgData){
let {ImgWidth,ImgRight,ImgBottom,deviationHeight} = this;
let minIndex = this.filterMin();//得到高度最小的一列的下标
imgData.top = deviationHeight[minIndex];//插入图片的top值
imgData.left = minIndex*(ImgRight+ImgWidth);//插入图片的left值
deviationHeight[minIndex] += imgData.height + ImgBottom;//更新当前列的高度
},
//找到最短的列并返回下标
filterMin(){
const min = Math.min.apply(null, this.deviationHeight);
return this.deviationHeight.indexOf(min);
},
}
}
</script>复制代码
css代码:
.v-waterfall-content{
width: 100%;
height: 100%;
position: relative;
}
.v-waterfall-item{
position: absolute;
}
.v-waterfall-item img{
width: 100%;
height: 100%;
}复制代码
这样就完成了图片瀑布流的布局啦,来看一下效果图
若是须要看项目的完整代码请移步github查看