
/**表格组件列表 */
Vue.component('temTable', {
props: ['data_table'],
computed: {
// tableCellWidth: function () {
// return
// }
tableWidth: function () {
if (this.$refs.tableBody) {
return this.$refs.tableBody.offsetWidth
} else {
return 0
}
},
targetBrandListText() {
let res = publicText[this.data_table.language]['had-filtered-brand-text']
if (this.targetBrandList.length > 0) {
res += ":"
this.targetBrandList.forEach((item, index) => {
if (index === 0) {
res += item
} else {
res += '、' + item
}
})
}
return res
}
},
methods: {
unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
let array = [];
for (let i = 0; i < arr.length; i++) {
if (array.indexOf(arr[i]) === -1) {
array.push(arr[i])
}
}
return array;
},
// 设置表格和表头的宽度
setTableWidth() {
console.log('setTableWidth')
// let fullTableDom = document.querySelectorAll("")
let headers = document.getElementsByClassName('hzs-table-header')
let tableRows = document.getElementsByClassName('hzs-table-content-tr')
console.log('setTableWidth')
// 表格头的
this.$root.tableWidthList.forEach((item, index) => {
console.log(item)
// console.log(headers)
let tdItem = this.data_table.theadList[index]
headers[index].style.width = tdItem.width ? item + 'px' : 'auto'
// console.log("tdItem", tdItem);
})
// 表格内容的
// let h = "hzs-table-content-tr"
this.$root.tableWidthList.forEach((item, index) => {
// [td, td, td, td]
for (let i = 0; i < tableRows.length; i++) {
let tds = tableRows[i].getElementsByTagName('td')
let tdItem = this.data_table.theadList[index]
tds[index].style.width = tdItem.width ? item + 'px' : 'auto'
}
})
},
// 获取所有的品牌列表
getAllBrandList() {
// let res = new Set()
// this.data_table.tbodyList.forEach(item => {
// res.add(item[0].name)
// })
let res = []
this.data_table.tbodyList.forEach(item => {
res.push(item[0].name)
})
this.brandList = this.unique(res)
},
// 筛选功能 筛选出一个brand下的所有item 并返回列表
filterBrand(brandList) {
let res = []
// console.log(res.length);
// if (brand && brand !== '') {
// res = this.data_table.tbodyList.filter(item => {
// return item[0].name == brand
// })
// }
if (brandList.length > 0) {
res = this.data_table.tbodyList.filter(item => {
return brandList.indexOf(item[0].name) != -1
})
}
return res
},
// 更新选中框
changeList(itemList) {
// 重新筛选
if (itemList.length < 1) {
this.tbodyList = this.data_table.tbodyList
return
}
let res = []
// itemList.forEach(item => {
// res = res.concat(this.filterBrand(item))
// })
// this.tbodyList = res
res = this.filterBrand(itemList)
this.tbodyList = res
},
openFilterCard() {
console.log(this.tableWidth)
this.isShowFilterCard = true
},
closeCard() {
this.isShowFilterCard = false
},
confirmBrandList(targetBrandList) {
this.targetBrandList = targetBrandList
},
resize() {
this.$refs.hzsConfirmBrandList.style.width = document.getElementById("table-header").offsetWidth + 'px'
}
},
watch: {
targetBrandList(newVal) {
this.changeList(newVal)
// 当显示筛选结果时,给table加一个上边距
},
// 监听 data_table 如果传入了 数据,才渲染表格
data_table: {
deep: true,
immediate: true,
handler(newVal, oldVal) {
let that = this
setTimeout(() => {
try {
that.tbodyList = newVal.tbodyList
// 将筛选框的高度与表格高度一致
let box = document.getElementsByClassName('hzs-filter-box')[0]
let hzsCard = document.getElementsByClassName('hzs-card')[0]
let hzsLetterList = document.getElementsByClassName('hzs-letter-list')[0]
let tHeight = document.getElementById('tableBody').offsetHeight
let containerHeight = document.getElementsByClassName('container')[0].offsetHeight
// 动态绑定height
if (!!containerHeight) {
box.style.height = containerHeight - 56 + 'px';
box.style.maxHeight = containerHeight - 56 + 'px';
hzsCard.style.height = containerHeight - 56 - 58 + 'px';
hzsLetterList.style.height = containerHeight - 56 - 58 - 77 + 'px';
} else if (!!tHeight) {
box.style.height = tHeight + 'px';
box.style.maxHeight = tHeight + 'px';
hzsCard.style.height = tHeight - 58 + 'px';
hzsLetterList.style.height = containerHeight - 58 - 77 + 'px';
}
that.$forceUpdate()
} catch (err) {
console.log(err.message);
}
}, 300);
},
},
},
data() {
return {
brandList: [],
currentBrand: [],
tbodyList: [],
isShowFilterCard: false,
targetBrandList: [],
}
},
created() {
this.getAllBrandList()
this.tbodyList = this.data_table.tbodyList
},
mounted() {
// console.log('temTable');
// setTimeout(() => {
// // console.log(this.$root.tableWidthList);
//
// // this.setTableWidth()
// })
// console.log(this.brandList)
// this.filterTableBody()
// console.log(this.tbodyList)
// console.log(this.$refs.hzsConfirmBrandList)
this.resize()
window.addEventListener('resize', this.resize)
},
template: `
{{ tdItem.name }}
{{ targetBrandListText }}
{{ tdItem.name }}
`
})
Vue.component('temFilterCard', {
// watch: {
// tableWidth(newVal) {
// console.log("调整width")
// console.log(newVal)
// this.$refs.filterCard.style.width = `${newVal}px`
// }
// },
props: {
allBrandList: {
type: Array,
default: () => []
},
isShow: {
type: Boolean,
default: false
},
tableWidth: {
type: Number,
},
lang: {
type: String,
}
},
computed: {
// 按照首字母进行筛选 然后分组
sortBrandDict: function () {
let res = {}
this.allBrandList.forEach(item => {
let firstLetter = item[0].toUpperCase()
if (!res.hasOwnProperty(firstLetter)) {
res[firstLetter] = []
}
res[firstLetter].push(item)
})
// 返回排序好的
return this.objKeySort(res)
},
targetBrandSet: function () {
if (!Array.isArray(this.targetBrandList)) {
console.log('type error!')
return
}
let array = [];
for (let i = 0; i < this.targetBrandList.length; i++) {
if (array.indexOf(this.targetBrandList[i]) === -1) {
array.push(this.targetBrandList[i])
}
}
return array;
// return new Set(this.targetBrandList)
}
},
watch: {
// targetBrandSet: {
// handler: function(newVal, oldVal){
// console.log("targetBrandSet")
// console.log(newVal)
// console.log(oldVal)
// },
// deep: true
// }
targetBrandList: {
handler: function (newVal, oldVal) {
this.textIsShow = !newVal.length
// if (newVal.length > 4) {
// this.showCaution = true
// setTimeout(() => {
// this.showCaution = false
// }, 3000);
// }
this.$forceUpdate()
}
},
lang(newVal) {
// alert('筛选框是否显示:' + newVal)
this.publicText = publicText
}
// width(newVal) {
// console.log("宽度改变")
// console.log(newVal)
// this.$refs.filterCard.style.width = `${newVal}px`
// }
},
data() {
return {
// 目标brandList
targetBrandList: [],
currentLetter: 'A',
// targetBrandSet: new Set(),
textIsShow: true,
showCaution: false,
filterBoxHeight: 0,
publicText: publicText
}
},
methods: {
unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
let array = [];
for (let i = 0; i < arr.length; i++) {
if (array.indexOf(arr[i]) === -1) {
array.push(arr[i])
}
}
return array;
},
objKeySort(obj) {
//排序的函数
let newKey = Object.keys(obj).sort()
// 先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
let newObj = {} //创建一个新的对象,用于存放排好序的键值对
for (let i = 0; i < newKey.length; i++) {
// 遍历newkey数组
newObj[newKey[i]] = obj[newKey[i]] //向新创建的对象中按照排好的顺序依次增加键值对
}
return newObj //返回排好序的新对象
},
addFilterBrand(item) {
let tmpList = this.unique(this.targetBrandList)
if (tmpList.indexOf(item) !== -1) {
// console.log(tmpList.indexOf(item));
tmpList.splice(tmpList.indexOf(item), 1)
} else {
tmpList.push(item)
}
this.targetBrandList = tmpList
// 如果筛选多于四个,进行限制
if (this.targetBrandList.length > 4) {
this.showCaution = true
setTimeout(() => {
this.showCaution = false
}, 3000);
tmpList.splice(tmpList.indexOf(item), 1)
this.targetBrandList = tmpList
}
// this.targetBrandSet.add(item)
// console.log(item)
// console.log(this.targetBrandSet)
// console.log(Array.from(this.targetBrandSet))
// console.log(this.targetBrandList)
},
removeBrand(item) {
let tmpList = this.unique(this.targetBrandList)
tmpList.splice(tmpList.indexOf(item), 1)
this.targetBrandList = tmpList
// let tmpList = new Set(this.targetBrandList)
// tmpList.delete(item)
// this.targetBrandList = Array.from(tmpList)
},
confirm() {
this.$emit('confirmBrandList', this.targetBrandList)
this.$emit("closeCard")
},
reset() {
this.targetBrandList = []
this.$emit('confirmBrandList', this.targetBrandList)
},
cancel() {
this.reset()
this.$emit("closeCard")
},
resize() {
// console.log("调整size")
let width = document.getElementById('table-header').offsetWidth
this.$refs.filterCard.style.width = `${width}px`
},
isSelected(item) {
// console.log(this.targetBrandSet.has(item));
return this.targetBrandSet.indexOf(item) !== -1
},
closeCard() {
this.$emit("closeCard")
},
// 滚动到目标字母的位置
scrollToLetter(letter) {
let name = 'letter' + letter
let targetLetter = this.$refs[name][0]
let targetScrollTop = targetLetter.offsetTop + this.$refs.topCard.offsetHeight
// this.$refs.filterCard.scrollTop = targetScrollTop
// 判断一下能否滑到
// console.log(targetScrollTop)
// console.log(this.$refs.filterCard.offsetHeight)
// console.log(this.$refs.filterCard.scrollHeight)
// console.log(this.$refs.filterCard.scrollHeight - this.$refs.filterCard.offsetHeight)
let maxScrollTop = this.$refs.filterCard.scrollHeight - this.$refs.filterCard.offsetHeight
if (targetScrollTop < maxScrollTop) {
// console.log("能滑到")
} else {
// console.log("不能滑到")
targetScrollTop = maxScrollTop
}
this.slideAnimate(this.$refs.filterCard, targetScrollTop)
},
// 滚动时判断滑到哪个字母了
handleScroll() {
// 判断现在是哪个字母
// console.log("正在滚动")
let letters = Object.keys(this.sortBrandDict)
// 所有已经翻到的字母列表
let allList = []
letters.forEach((letter, index) => {
let name = 'letter' + letter
let targetLetter = this.$refs[name][0]
// 判断
if (this.$refs.filterCard.scrollTop > targetLetter.offsetTop + this.$refs.topCard.offsetHeight - 1) {
allList.push(letter)
}
})
// console.log("所有已经翻到的字母列表")
// console.log(allList)
if (allList.length > 0) {
this.currentLetter = allList[allList.length - 1]
} else {
this.currentLetter = letters[0]
}
// console.log(this.currentLetter )
// console.log(allList)
},
// 先快后慢 滑动动画封装
slideAnimate(element, targetScrollTop) {
clearInterval(element.timer); //清楚历史定时器
element.timer = setInterval(function () {
//获取步长 确定移动方向(正负值) 步长应该是越来越小的,缓动的算法。
let step = (targetScrollTop - element.scrollTop) / 5;
//对步长进行二次加工(大于0向上取整,小于0项下取整)
step = step > 0 ? Math.ceil(step) : Math.floor(step);
//动画原理: 目标位置 = 当前位置 + 步长
element.scrollTop += step
//检测缓动动画有没有停止
if (Math.abs(targetScrollTop - element.scrollTop) <= Math.abs(step)) {
element.scrollTop = targetScrollTop //直接移动指定位置
clearInterval(element.timer);
}
}, 20);
}
},
// 生命周期
mounted() {
// console.log("sortBrandDict")
// console.log(this.sortBrandDict)
// this.$set(this.targetBrandSet, new Set())
// 调整宽度
// let width = document.getElementById('table-header').offsetWidth
// this.$refs.filterCard.style.width = `${width}px`
this.resize()
// 调整位置
// this.$refs.hzsFilterBox
window.addEventListener('resize', this.resize)
console.log(this.lang);
// getBoundingClientRect()
// this.$refs.filterCard.addEventListener('scroll', this.handleScroll)
},
// updated() {
// },
template: `
{{publicText[lang]['had-filtered-brand-text']}}
{{brand}}
|
{{publicText[lang]['hzs-please-choose']}}
{{publicText[lang]['hzs-all-brand-text']}}
{{ key }}
{{ item }}
{{key}}
{{publicText[lang]['hzs-caution-text']}}
`
})
css部分
/* 筛选card 部分 */
.hzs-filter-box {
position: absolute;
top: 0;
overflow: hidden;
/*opacity: 1;*/
/* height: 85vh; */
padding-bottom: 58px;
/* max-height: 85vh; */
/*left: 0;*/
}
.hzs-filter-icon {
margin-left: 10px;
cursor: pointer;
}
.hzs-card {
position: relative;
/*border: 1px solid black;*/
background: #ffffff;
box-shadow: 0 5px 5px rgba(0, 0, 0, 0.3);
font-family: Roboto-Medium;
/*height: 400px;*/
/* height: 100%; */
overflow: auto;
z-index: 999; /* 这个必须要加 */
/*transition: height 2s;*/
}
.brand-tag {
display: inline-block;
border-radius: 4px;
border: 1px solid #ebebeb;
}
.hzs-button-group {
width: 100%;
position: absolute;
bottom: 0;
/*left: 0;*/
display: flex;
padding: 10px;
justify-content: space-between;
/*background: url('../img/grey60.png');*/
border-top: 1px solid #C7C7C7;
background: linear-gradient(180deg, #F3F3F3, #C7C7C7);
z-index: 9999;
}
.hzs-button-group .greyButton {
padding-left: 20px;
padding-right: 20px;
font-weight: 600;
font-size: 16px;
}
.hzs-confirm {
padding: 10px 25px;
z-index: 1;
display: inline-flex;
justify-content: center;
align-items: center;
height: 38px;
min-width: 60px;
font-family: SourceHanSansCN-Medium;
font-size: 16px;
font-weight: 600;
letter-spacing: 1px;
outline: none;
white-space: nowrap;
color: white;
cursor: pointer;
border-radius: 5px;
/*border-image-source: url('../img/grey60.png');*/
background-image: linear-gradient(180deg, #7BBAFF 10%, #0072EE 76%, #007AFF 100%);
/*box-shadow: 0 2px 0 0 #FFFFFF;*/
/*border-radius: 14px;*/
}
.hzs-confirm:active {
background: linear-gradient(180deg, #007AFF 100%, #0072EE 76%, #7BBAFF 10%);
}
.hzs-top-card {
padding: 10px;
}
.hzs-all-brand-card {
position: relative;
padding-right: 30px;
/*background: #EBEBEB;*/
background: white;
}
.hzs-first-letter {
background: #EBEBEB;
padding: 0 10px;
font-weight: 600;
font-size: 17px;
}
.hzs-a-brand {
background: white;
padding: 10px;
font-size: 17px;
border-bottom: 2px solid #dcdcdc;
display: flex;
justify-content: space-between;
}
.hzs-caution {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
z-index: 99999;
}
.hzs-caution-text {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 40px 40px;
max-width: 450px;
line-height: 28px;
background-color: #fff;
border-radius: 4px;
font-size: 18px;
text-align: center;
white-space: normal
}
/* 已筛选品牌 */
.had-filtered-brand-text {
font-size: 20px;
font-weight: 600;
}
.hzs-target-brand-list {
/*min-height: 100px;*/
/*display: flex;*/
/*flex-wrap: wrap;*/
/*justify-content: flex-start;*/
}
.hzs-brand-tag {
border: 1px solid gray;
display: inline-block;
padding: 5px;
border-radius: 4px;
font-size: 18px;
/*font-weight: 600;*/
margin-right: 10px;
margin-top: 10px;
}
.hzs-brand-tag span:nth-child(1) {
color: #007AFF;
padding: 0 5px;
text-transform: capitalize;
}
.hzs-brand-tag span:nth-child(2) {
color: rgba(0, 0, 0, 0.3);
}
.hzs-brand-tag .shanchu {
display: inline-block;
width: 12px;
height: 12px;
background-image: url(../img/shanchu.png);
background-size: cover;
margin-left: 5px;
margin-right: 5px;
cursor: pointer;
}
/* .hzs-brand-tag span:nth-child(3) {
font-weight: 1000;
padding: 0 5px;
font-size: 4px
font-size: 14px;
color: brown;
} */
.hzs-all-brand-text {
margin: 20px 0 0;
font-size: 20px;
font-weight: 600;
}
.hzs-please-choose {
text-align: center;
padding: 20px 0 0;
font-size: 16px;
font-weight: 600;
color: hsl(0, 2%, 50%);
}
.hzs-letter-list {
width: 24px;
position: fixed;
right: 18px;
top: 140px;
font-size: 14px;
font-weight: 500;
color: #8C8C8C;
/* border: 1px solid #000; */
overflow-y: scroll;
/*display: flex;*/
/*flex-flow: column;*/
/*justify-items: flex-start;*/
}
.hzs-letter-list::-webkit-scrollbar {
width: 3px;
height: 18px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.hzs-letter-list div {
padding: 0;
margin-bottom: 4px;
text-align: center;
}
.hzs-letter-current {
font-size: 18px;
font-weight: 700;
color: black;
}
.hzs-up {
/*position: absolute;*/
/*top: 10px;*/
/*right: 20px;*/
/*z-index: 9999;*/
font-weight: 1000;
font-size: 20px;
}
.hzs-up .xiangshang {
display: inline-block;
width: 25px;
height: 25px;
vertical-align: middle;
background-image: url(../img/xiangshang.png);
background-size: cover;
margin-left: 10px;
cursor: pointer;
}
.hzs-confirm-brand-list {
position: absolute;
padding: 10px;
font-size: 16px;
font-weight: 500;
border: 1px solid #ccc;
background: #E1E1E1;
}
.hzs-gouxuan {
color: green;
font-weight: 1000;
}
.hzs-up-and-had-filtered {
display: flex;
justify-content: space-between;
margin-right: 10px;
}
.hzs-enter, .hzs-leave-to {
/*opacity: 0; !*点击按钮页面即将被显示,此时div标签处于隐藏状态*!*/
height: 0;
}
/* .hzs-enter-active, .hzs-leave-active { */
/*transition: opacity 2s; !* 对该CSS样式进行transition的监控,有2s的过渡*!*/
/* transition: height 0.4s ease-in-out; */
/* } */