taro、uniapp、微信小程序导航栏双向联动
Taro双向联动(跨版导航)效果图功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出不懂Promise.all()用法,可以去
·
效果图
大概思路
1、导航栏用ScrollView写,不过样式得加上white-space: nowrap;文本不换行,
2、在导航栏上定义id用来**Promise.all()**获取元素属性,
Promise.all()可以将多个Promise实例包装成一个新的Promise实例,
3、 再用Taro.createSelectorQuery()获取每一个DOM节点属性,
视图
<View className='tab_index_wrapp'>
<ScrollView scrollWithAnimation className='tab_scroll_view'
scrollX id='tabList' scrollLeft={offsetLeft}
>
<View className='tab_view'>
{
list.map((item, index) => {
return (
<View
key={index} className='tab' id={`item-${index}`}
onClick={this.setLineItem.bind(this, index)}
>{item.title}</View>
)
})
}
<View className='tab_line' style={lineStyle}></View>
</View>
</ScrollView>
<View className='tab_swiper_wrapp'>
<Swiper className='tab_swiper' current={actvieIndex} onChange={this.swiperBindchange.bind(this)}>
{
listItem.map((item, index) => {
return (
<SwiperItem key={index} className='tab_swiper'>
<View>{item.id}</View>
</SwiperItem>
)
})
}
</Swiper>
</View>
</View>
视图的样式
.tab_index_wrapp{
height: 100vh;
background-color: #f5f5f5;
overflow: hidden;
.tab_scroll_view{
position: relative;
width: 100%;
font-size: 28px;
background-color: #fff;
margin-bottom: 20px;
.tab_view{
white-space: nowrap;
position: relative;
.tab{
height: 70px;
line-height: 70px;
display: inline-block;
margin-left: 45px;
margin-right: 65px;
color: #5f5f5f;
box-sizing: border-box;
&:last-child{
margin-right: 45px;
}
}
.tab_line{
height: 2PX;
border-radius: 20%;
background-color: aqua;
position: absolute;
bottom: 0;
transition: all .3s linear;
}
}
}
.tab_swiper_wrapp{
width: 100%;
height: 100%;
.tab_swiper{
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}
}
逻辑
constructor() {
super(...arguments)
this.state = {
list: [
{title: '理想', id: 0},
{title: '梦想', id: 1},
{title: '搬砖', id: 2},
{title: '给予', id: 3},
{title: '爱情', id: 4},
{title: '赚钱', id: 5},
{title: '疯子', id: 6},
{title: '信念', id: 7},
{title: '信仰', id: 8},
{title: '谢谢', id: 9},
],
listItem: [
{title: '理想', id: 0},
{title: '梦想', id: 1},
{title: '搬砖', id: 2},
{title: '给予', id: 3},
{title: '爱情', id: 4},
{title: '赚钱', id: 5},
{title: '疯子', id: 6},
{title: '信念', id: 7},
{title: '信仰', id: 8},
{title: '谢谢', id: 9},
],
actvieIndex: 0, // 标签下标
offsetLeft: "", // scroll-left位置
viewWidth: "", // scroll-view视图宽度
lineStyle: "", // 下划线样式
}
}
componentWillMount () {
let that = this
// Promise.all可以将多个Promise实例包装成一个新的Promise实例
Promise.all([that.getList('#tabList'), that.lineItem(that.state.list, '#item-')])
.then(([nav, list]) => {
/**
* nav: 是指获取that.getList('#tabList')导航栏的元素属性,
* list:是指获取that.lineItem(that.state.list, '#item-')
* that.state.list下的每一个对象的元素属性,
*
* that.state.viewWidth / 2:为什么除以2,因为小程序是 rpx 单位
*/
that.state.viewWidth = nav.width
that.state.list = list
that.state.lineStyle = `width: ${list[that.state.actvieIndex].itemWidth}px;
transform: translateX(${list[that.state.actvieIndex].offsetLeft}px);`
that.setState({
offsetLeft: list[that.state.actvieIndex].offsetLeft - that.state.viewWidth / 2 + list[that.state.actvieIndex].itemWidth / 2,
lineStyle: that.state.lineStyle,
})
})
}
// 获取元素属性,DOM节点
getList(e) {
return new Promise(function(resolve, reject) {
query = Taro.createSelectorQuery().select(e).boundingClientRect(res => {
resolve(res)
}).exec()
})
}
// 初始化项目
lineItem(e, selector) {
let that = this
return new Promise(function(resolve, reject) {
e.forEach((item, index) => {
// that.getList(selector + index) 去 that.state.list 中获取每一个对象元素属性,
that.getList(selector + index).then(res => {
console.log('%c res', 'color:green', res)
// res.left 是左边的距离, res.width 是每个对象元素的宽度
item.offsetLeft = res.left
item.itemWidth = res.width
})
});
resolve(e)
})
}
// 点击切换
setLineItem(e) {
let index = e
this.setState({
actvieIndex: index,
offsetLeft: this.state.list[index].offsetLeft - this.state.viewWidth / 2 + this.state.list[index].itemWidth / 2,
lineStyle: `width: ${this.state.list[index].itemWidth}px;
transform: translateX(${this.state.list[index].offsetLeft}px)`,
})
}
// 滑动切换
swiperBindchange(e) {
let index = e.detail.current
this.setState({
actvieIndex: index,
offsetLeft: this.state.list[index].offsetLeft - this.state.viewWidth / 2 + this.state.list[index].itemWidth / 2,
lineStyle: `width: ${this.state.list[index].itemWidth}px;
transform: translateX(${this.state.list[index].offsetLeft}px)`,
})
}
用到的API和方法
1、不懂Promise.all()用法,可以去官网看看:
点击链接
2、获取DOM节点Taro官网:
点击链接
第一次写这个,以上有什么不对的,欢迎各位大佬来指出,谢谢
更多推荐
已为社区贡献5条内容
所有评论(0)