vue-cli3.0搭建項目+圖片瀑布流佈局

前言

本文將vue-cli的使用和圖片瀑布流放在一塊兒來說,主要是我本身作着兩方面的練習。其實若是隻是寫個單頁面的圖片瀑布流效果也不用專門搭建一個vue-cli項目。須要看代碼的小夥伴能夠在個人github中自行查看。css

vue-cli搭建項目

一、首先檢查你的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查看

相關文章
相關標籤/搜索