小程序之index索引器品牌篇实现与步骤详述
图例

index组件
.js
// 品牌索引列表
Component({
/** 组件的属性列表 /
properties: {
/* 数据 /
data: {
type: Object,
value: {},
observer: function(newVal, oldVal) { this.resetRight(newVal); }
},
/* 配置项 */
config: {
type: Object,
value: {
animation: true, // 过渡动画是否开启
search: true, // 是否开启搜索
searchHeight: 45, // 搜索条高度
suctionTop: true // 是否开启标题吸顶
}
}
},
data: {
list: [],
rightArr: [], // 右侧字母展示
jumpNum: '', //跳转到那个字母
topGroup: [], // 内容高度数据
pos: {
isTop: false,
y: 0,
oldIndex: -1
},
listIndex: 0,
moveDistance: 0
},
ready() {},
methods: {
/** 数据重新渲染 */
resetRight(data) {
let rightArr = [];
for (let i in data) { rightArr.push(data[i].key); }
this.setData({
list: data,
rightArr
}, () => {
if (data.length != 0) {
this.queryMultipleNodes();
}
});
},
/** 右侧字母点击事件 /
jumpMt(e) {
let jumpNum = e.currentTarget.dataset.id;
this.setData({ jumpNum });
},
/* 列表点击事件 /
detailMt(e) {
let detail = e.currentTarget.dataset.detail;
let data = {type: "CLICK", data: detail};
this.triggerEvent('brand', data);
},
// 获取搜索输入内容
input(e) {
this.value = e.detail.value;
},
// 基础搜索功能
searchMt() {
let data = {type: "SEARCH", data: this.value ? this.value : ""};
this.triggerEvent('brand', data);
},
/* 监听滚动 /
scroll(e) {
let top = e.detail.scrollTop;
let index = this.currentIndex(top);
let list = this.data.topGroup;
let distance = top - list[this.data.listIndex];
let num = -(list[this.data.listIndex + 1] - top - 40);
// 渲染滚动索引
if (index !== this.data.listIndex) {
this.setData({
listIndex: index,
moveDistance: 40,
})
// 如果监听到 index 的变化 ,一定要return ,否则吸顶会先变化文字后运动,会闪烁
return;
}
if (num < 0) num = 0;
if (num !== this.data.moveDistance) { this.setData({ moveDistance: num }) }
},
/*
* 获取当前滚动索引
/
currentIndex(y) {
let listHeight = this.data.topGroup;
for (let i = 0; i < listHeight.length; i++) {
let height1 = listHeight[i];
let height2 = listHeight[i + 1];
if (!height2 || (y >= height1 && y < height2)) {
return i;
}
}
return 0;
},
/*
* 获取节点信息
*/
queryMultipleNodes() {
let self = this
const query = wx.createSelectorQuery().in(this);
query.selectAll('.fixed-title-hock').boundingClientRect((res) => {
res.forEach(function(rect) { rect.top // 节点的上边界坐标 })
}).exec((e) => {
let arr = [];
e[0].forEach((rect) => {
let num = 0;
if (rect.top !== 0) {
num = rect.top - (self.data.config.search ? self.data.config.searchHeight : 0);
}
arr.push(num);
})
this.setData({ topGroup: arr });
})
}
}
})
.json
{
"component": true,
"usingComponents": {}
}
.wxml
{{list[listIndex].key === "HOT" ? "热门品牌" : list[listIndex].key}}
{{rightArr[index]}}
.wxss
.list-warpper {
position: relative;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.list-scroll {
width: 100%;
height: 100%;
box-sizing: border-box;
}
.list-scroll.top{
padding-top: 90rpx;
}
/* 样式控制 */
.list-title {
background: #f5f5f5;
color: #666;
font-size: 36rpx;
padding-left: 30rpx;
height: 80rpx;
line-height: 80rpx;
}
.list-name {
position: relative;
font-size: 28rpx;
padding: 15rpx;
padding-left: 30rpx;
color: #999;
}
.list-name.border::after {
content: "";
position: absolute;
left: 30rpx;
right: 0;
top: 0;
height: 1px;
background: #f5f5f5;
}
.list-right-wrapper {
position: absolute;
right: 0;
top: 50%;
right: 20rpx;
padding: 20rpx 0;
z-index: 999;
transform: translateY(-50%);
background: #ddd;
border-radius: 40rpx;
box-sizing: border-box;
text-align: center;
}
.right-item {
display: flex;
justify-content: center;
align-items: center;
padding: 2rpx 10rpx;
font-size: 40rpx;
color: #666;
}
.icon48{
font-size: 56rpx;
}
.right-item.active {
color: #ff9900;
}
.list-search {
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
width: 100%;
height: 90rpx;
padding: 10rpx 30rpx;
box-sizing: border-box;
z-index: 20;
background: #FFF;
border-bottom:1px #f5f5f5 solid;
}
.search-title {
flex-shrink: 0;
font-size: 28rpx;
padding-right: 10rpx;
}
.list-search-box {
display: flex;
align-items: center;
padding: 0 30rpx;
width: 100%;
height: 70rpx;
background: #f5f5f5;
border-radius: 90rpx;
font-size: 28rpx;
box-sizing: border-box;
}
.list-search-box input {
width: 100%;
padding-left: 10rpx;
}
.search-button {
flex-shrink: 0;
height: 60rpx;
line-height: 60rpx;
font-size: 28rpx;
margin-left: 10rpx;
}
.fiexed-box {
position: absolute;
top: 90rpx;
z-index: 19;
width: 100%;
}
/* new */
.index-brand-box{
width: 100%;
background-color: #F3F3F3;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
padding-left: 30rpx;
box-sizing: border-box;
}
.index-brand-box .index-brand-card{
width: 148rpx;
height: 164rpx;
background-color: #fff;
margin: 20rpx 30rpx 20rpx 0;
}
.index-brand-box .index-brand-card:nth-child(4n) {
margin-right: 0;
}
.index-brand-box .index-brand-card .brand-img{
width: 100%;
height: 102rpx;
padding: 10rpx;
border-bottom: 2rpx solid #ededed;
box-sizing: border-box;
}
.index-brand-box .index-brand-card .brand-pic{
width: 100%;
height: 100%;
}
.index-brand-box .index-brand-card .brand-name{
width: 100%;
height: 60rpx;
line-height: 60rpx;
text-align: center;
}
.index-brand-item{
width: 100%;
height: 80rpx;
background-color: #fff;
padding: 0 30rpx;
border-bottom: 2rpx solid #f2f2f2;
box-sizing: border-box;
}
.dflex-start{
display: flex;
justify-content: flex-start;
align-items: center;
color: #000;
}
.index-brand-item .brand-img{
width: 100rpx;
height: 80rpx;
background-color: chartreuse;
margin-right: 30rpx;
}
/* 无数据 */
.nodata {
padding-top: 200rpx;
text-align: center;
font-size: 32rpx;
color: #ddd;
}
调用
.js
var _default =
{
data: function data() {
return {
indexHeight: 0,
queryBrandName: "",
brandList: [
{ key: "HOT", list: [
{ img:"/static/img/brand/geli.png", brandName:"格力" },
{ img:"/static/img/brand/meidi.png", brandName:"美的" },
{ img:"/static/img/brand/feilipu.png", brandName:"飞利浦" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/geli.png", brandName:"格力" },
{ img:"/static/img/brand/meidi.png", brandName:"美的" },
{ img:"/static/img/brand/feilipu.png", brandName:"飞利浦" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" }
]},
{ key: "M", list: [
{ img:"/static/img/brand/meidi.png", brandName:"美的" },
{ img:"/static/img/brand/meibo.png", brandName:"美博" }
]},
{
key: "G", list: [
{ img:"/static/img/brand/geli.png", brandName:"格力" },
{ img:"/static/img/brand/gelanshi.png", brandName:"格兰仕" }
]
},
{
key: "T", list: [
{ img:"/static/img/brand/tcl.png", brandName:"TCL" }
]
},
{
key: "S", list: [
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" },
{ img:"/static/img/brand/shenling.png", brandName:"申菱" }
]
},
{
key: "Z", list: [
{ img:"/static/img/brand/zhuoli.png", brandName:"卓立" }
]
},
{
key: "3", list: [
{ img:"/static/img/brand/sanling.png", brandName:"三菱" },
]
}
]
};
},
onLoad: function onLoad(option) {
const _this = this;
uni.getSystemInfo({
success:function(res){
let windowHeight = res.windowHeight;
_this.indexHeight = windowHeight > 0 ? (windowHeight - 10) * 2 : 0;
}
});
},
methods: {
toSearch: function toSearch(e){
console.log('查询品牌名称', e)
this.brandList = [
{
key: "T", list: [
{ img:"/static/img/brand/tcl.png", brandName:"TCL" }
]
}
]
},
toBrand: function toBrand(e) {
console.log('选择品牌',e.detail);
}
}
};
.json
{
"navigationBarTitleText": "选择品牌",
"navigationBarBackgroundColor": "#f1f1f1",
"onReachBottomDistance": 50,
"usingComponents": {
"index-list": "../../../components/index-brand/index"
}
}
.wxml
.wxss
@charset "UTF-8";
page { background-color: #f1f1f1; }
.wrapper{
width: 100%;
background-color: #fff;
}
浙公网安备 33010602011771号