本文將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查看