最近一個vue
項目需要瀑布流布局亿乳,最終結(jié)合自己的需求使用了vue
的v-for
實現(xiàn)了汇荐,整理了一下狂丝。
結(jié)構(gòu)示意圖
(用 Process 在線畫圖工具畫的)
說明
- 外層容器的box高度不固定
- 每列col的寬度可自定義
- 列數(shù)可自定義管嬉,取決于有幾個數(shù)據(jù)
dataList
地技,每個列的數(shù)據(jù)對應(yīng)一個``dataList` - 頁面布局結(jié)構(gòu)代碼
<div class="box">
<div class="col" ref="col1">
<transition-group name="list">
<div class="item" v-for="item in dataList1" :key="item.id">{{item.text}}</div>
</transition-group>
</div>
<div class="col" ref="col2">
<transition-group name="list">
<div class="item" v-for="item in dataList2" :key="item.id">{{item.text}}</div>
</transition-group>
</div>
<div class="col" ref="col3">
<transition-group name="list">
<div class="item" v-for="item in dataList3" :key="item.id">{{item.text}}</div>
</transition-group>
</div>
<div class="col" ref="col4">
<transition-group name="list">
<div class="item" v-for="item in dataList4" :key="item.id">{{item.text}}</div>
</transition-group>
</div>
</div>
加載數(shù)據(jù)
- 使用
axios
/** main.js*/
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
Vue.prototype.$http = axios
new Vue({
el: '#app',
render: h => h(App)
})
- 當(dāng)組件
mounted
時獲取數(shù)據(jù),獲取到數(shù)據(jù)后執(zhí)行mountMenu()
方法柴底,mountMenu()
方法將會通過selectCol()
選擇當(dāng)前高度最小的列婿脸,并把數(shù)據(jù)push
到對應(yīng)的dataList
中,``mountMenu()`會在每次執(zhí)行時遞歸調(diào)用柄驻,直到遍歷完所有的數(shù)據(jù)
/** 數(shù)據(jù)實例*/
[
{
id:1002,
text:"mountMenu()中調(diào)用了this.$nextTick()目的是等待當(dāng)前DOM渲染完成后在繼續(xù)執(zhí)行狐树,否則在獲取最小高度的列時,每次獲取到的高度都為0(vm.nextTick()vue官方文檔)"
}
]
- <span style='color:red;font-weight:bold'>重要信息</span>:
mountMenu()
中調(diào)用了this.$nextTick()
目的是等待當(dāng)前DOM渲染完成后在繼續(xù)執(zhí)行凿歼,否則在獲取最小高度的列時褪迟,每次獲取到的高度都為0(<a href="https://cn.vuejs.org/v2/api/#vm-nextTick" target="_blank">vm.nextTick()
vue官方文檔</a>)
export default {
data() {
return {
mainMenuList: [],
dataList1: [],
dataList2: [],
dataList3: [],
dataList4: [],
}
},
mounted() {
this.$http({ url: 'http://localhost:6060/paragraph', method: 'get' }).then(res => {
this.mainMenuList = res.data
this.mountMenu()
})
},
methods: {
mountMenu(arg) {
var temp = this.mainMenuList
var index = arg || 0
var refName = this.selectCol()
if (temp.length > index) {
this[refName].push(this.mainMenuList[index])
this.$nextTick(() => {
this.mountMenu(index + 1)
})
}
},
selectCol() {
var getHeight = (ref) => {
return this.$refs[ref].offsetHeight
}
var height1 = getHeight('col1')
var height2 = getHeight('col2')
var height3 = getHeight('col3')
var height4 = getHeight('col4')
switch (Math.min(height1, height2, height3, height4)) {
case height1:
return 'dataList1'
break
case height2:
return 'dataList2'
break
case height3:
return 'dataList3'
case height4:
return 'dataList4'
break
}
},
}
}
-
ie瀏覽器的BUG:上述代碼在ie瀏覽器(
ie 9/10/11
)中會遇到動畫的bug,目前我的解決方案就是js判斷瀏覽器答憔,在ie中禁用過渡動畫(
computed: {
isIe() {
var tmp = window.navigator.userAgent.indexOf("MSIE") >= 1
|| !!window.ActiveXObject
|| "ActiveXObject" in window
return tmp ? "" : "list"
}
}
<transition-group :name="isIe">
<div class="item" v-for="item in dataList1" :key="item.id">{{item.text}}</div>
</transition-group>