Skip to content
This repository was archived by the owner on Oct 27, 2021. It is now read-only.

Commit

Permalink
feat: add Indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
psaren committed May 13, 2020
1 parent 0ebf1cb commit bacd574
Show file tree
Hide file tree
Showing 5 changed files with 307 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SegmentedControl from './segmented-control/index'
import AtTabs from './tabs/index'
import AtTabsPane from './tabs-pane/index'
import AtPagination from './pagination/index'
import AtIndexes from './indexes/index'

export {
Grid,
Expand All @@ -23,5 +24,6 @@ export {
SegmentedControl,
AtTabs,
AtTabsPane,
AtPagination
AtPagination,
AtIndexes
}
261 changes: 261 additions & 0 deletions src/components/indexes/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
import classNames from 'classnames'
import Taro from '@tarojs/taro'
import mixins from '../mixins'
import { delayQuerySelector, isTest, uuid } from '../../utils/common'
import AtList from '../list/index'
import AtListItem from '../list/item/index'
import AtToast from '../toast/index'

const ENV = Taro.getEnv()

export default {
name: 'AtIndexes',
mixins: [mixins],
props: {
customStyle: {
type: [Object, String],
default: '',
},
className: {
type: [Array, String],
default: '',
},
animation: {
type: Boolean,
default: false,
},
isVibrate: {
type: Boolean,
default: true,
},
isShowToast: {
type: Boolean,
default: true,
},
list: {
type: Array,
default: () => [],
},
topKey: {
type: String,
default: 'Top',
},
onClick: {
type: Function,
default: () => () => {},
},
onScrollIntoView: {
type: Function,
default: () => () => {},
},
},
data() {
return {
// 右侧导航高度
menuHeight: 0,
// 右侧导航距离顶部高度
startTop: 0,
// 右侧导航元素高度
itemHeight: 0,
// 当前索引
currentIndex: -1,
listId: isTest() ? 'indexes-list-AOTU2018' : `list-${uuid()}`,
timeoutTimerL: null,
state: {
_scrollIntoView: '',
_scrollTop: 0,
_tipText: '',
_isShowToast: false,
isWEB: Taro.getEnv() === Taro.ENV_TYPE.WEB,
},
}
},
computed: {
listLen() {
return this.list.length
},
},

watch: {
listLen() {
this.initData()
},
},
beforeMount() {
this.onScrollIntoView && this.onScrollIntoView(this.__jumpTarget.bind(this))
},
mounted() {
if (ENV === Taro.ENV_TYPE.WEB) {
this.listRef = document.getElementById(this.listId)
}
this.initData()
},
methods: {
handleClick(item) {
this.onClick && this.onClick(item)
},
handleTouchMove(event) {
event.stopPropagation()
event.preventDefault()

const { list } = this
const pageY = event.touches[0].pageY
const index = Math.floor((pageY - this.startTop) / this.itemHeight)

if (index >= 0 && index <= list.length && this.currentIndex !== index) {
this.currentIndex = index
const key = index > 0 ? list[index - 1].key : 'top'
const touchView = `at-indexes__list-${key}`
this.jumpTarget(touchView, index)
}
},
handleTouchEnd() {
this.currentIndex = -1
},
/**
*
* @param {string} _scrollIntoView
* @param {number} idx
*/
jumpTarget(_scrollIntoView, idx) {
const { topKey, list } = this
const _tipText = idx === 0 ? topKey : list[idx - 1].key

if (ENV === Taro.ENV_TYPE.WEB) {
delayQuerySelector(this, '.at-indexes', 0).then((rect) => {
const targetOffsetTop = this.listRef.childNodes[idx].offsetTop
const _scrollTop = targetOffsetTop - rect[0].top
this.updateState({
_scrollTop,
_scrollIntoView,
_tipText,
})
})
return
}

this.updateState({
_scrollIntoView,
_tipText,
})
},
/**
*
* @param {string} key
*/
__jumpTarget(key) {
const { list } = this
// const index = _findIndex(list, ['key', key])
const index = list.findIndex((item) => item.key === key)
const targetView = `at-indexes__list-${key}`
this.jumpTarget(targetView, index + 1)
},
updateState(state) {
const { isShowToast, isVibrate } = this
const { _scrollIntoView, _tipText, _scrollTop } = state
// TODO: Fix dirty hack
this.setState(
{
_scrollIntoView: _scrollIntoView,
_tipText: _tipText,
_scrollTop: _scrollTop,
_isShowToast: isShowToast,
},
() => {
clearTimeout(this.timeoutTimer)
this.timeoutTimer = setTimeout(() => {
this.setState({
_tipText: '',
_isShowToast: false,
})
}, 3000)
}
)

if (isVibrate) {
Taro.vibrateShort()
}
},
initData() {
delayQuerySelector(this, '.at-indexes__menu').then((rect) => {
const len = this.list.length
this.menuHeight = rect[0].height
this.startTop = rect[0].top
this.itemHeight = Math.floor(this.menuHeight / (len + 1))
})
},
handleScroll(e) {
if (e && e.detail) {
this.setState({
_scrollTop: e.detail.scrollTop,
})
}
},
},
render() {
const { className, customStyle, animation, topKey, list } = this
const { _scrollTop, _scrollIntoView, _tipText, _isShowToast, isWEB } = this.state

const toastStyle = { minWidth: Taro.pxTransform(100) }
const rootCls = classNames('at-indexes', className)

const menuList = list.map((dataList, i) => {
const { key } = dataList
const targetView = `at-indexes__list-${key}`
return (
<view
class="at-indexes__menu-item"
key={key}
onTap={this.jumpTarget.bind(this, targetView, i + 1)}>
{key}
</view>
)
})

const indexesList = list.map((dataList) => (
<view id={`at-indexes__list-${dataList.key}`} class="at-indexes__list" key={dataList.key}>
<view class="at-indexes__list-title">{dataList.title}</view>
<AtList>
{dataList.items &&
dataList.items.map((item) => (
<AtListItem
key={item.name}
title={item.name}
onTap={this.handleClick.bind(this, item)}
/>
))}
</AtList>
</view>
))

return (
<view class={rootCls} style={customStyle}>
<AtToast customStyle={toastStyle} isOpened={_isShowToast} text={_tipText} duration={2000} />
<view
class="at-indexes__menu"
onTouchMove={this.handleTouchMove}
onTouchEnd={this.handleTouchEnd}>
<view
class="at-indexes__menu-item"
onTap={this.jumpTarget.bind(this, 'at-indexes__top', 0)}>
{topKey}
</view>
{menuList}
</view>
<scroll-view
class="at-indexes__body"
id={this.listId}
scrollY
scrollWithAnimation={animation}
scrollTop={isWEB ? _scrollTop : undefined}
scrollIntoView={!isWEB ? _scrollIntoView : ''}
onScroll={this.handleScroll.bind(this)}>
<view class="at-indexes__content" id="at-indexes__top">
{this.$slots.default}
</view>
{indexesList}
</scroll-view>
</view>
)
},
}
3 changes: 2 additions & 1 deletion src/components/notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Noticebar marquee 属性 还不可用
- Button 未完成,Invalid handler for event "getPhoneNumber": got undefined 等错误
- Accordion 动画不顺滑
- Accordion 动画不顺滑
- Indexes 跳转动画有问题
10 changes: 9 additions & 1 deletion src/pages/index/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
<view
class="index"
>
<view style="height:100vh">
<AtIndexes
:list="list"
:on-click="clickIndex"
>
<view>自定义内容</view>
</AtIndexes>
</view>
<AtPagination
:total="50"
:page-size="10"
Expand All @@ -15,7 +23,7 @@
:values="segmentedList"
/>
<TabBar
:tab-list="tabList"
:tab-list="tabBarList"
:on-click="onTabClick"
:current="tabIndex"
/>
Expand Down
35 changes: 32 additions & 3 deletions src/pages/index/indexMixins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
AtTabs,
AtTabsPane,
AtPagination,
AtIndexes,
} from '../../components/index'

export default {
Expand Down Expand Up @@ -73,6 +74,7 @@ export default {
AtTabs,
AtTabsPane,
AtPagination,
AtIndexes,
},
data() {
return {
Expand Down Expand Up @@ -127,15 +129,39 @@ export default {
accordionIcon: { value: 'chevron-down', color: 'red', size: '15' },
openAccordion: false,
tabIndex: 0,
tabList: [
tabBarList: [
{ title: '待办事项', iconType: 'bullet-list', text: 'new' },
{ title: '拍照', iconType: 'camera' },
{ title: '文件夹', iconType: 'folder', text: '100', max: 99 },
],
segmentedIndex: 0,
segmentedList: ['标签页1', '标签页2', '标签页3'],
currentTab: 0,
tabList: [{ title: '标签页1' }, { title: '标签页2' }, { title: '标签页3' }]
tabList: [{ title: '标签页1' }, { title: '标签页2' }, { title: '标签页3' }],
list: [{
title: 'A',
key: 'A',
items: [
{
'name': '阿坝'
// 此处可加其他业务字段
},
{
'name': '阿拉善'
}]
},
{
title: 'B',
key: 'B',
items: [
{
'name': '北京'
},
{
'name': '保定'
}]
}
]
}
},
methods: {
Expand Down Expand Up @@ -165,6 +191,9 @@ export default {
},
changeCurrentTab(val) {
this.currentTab = val
}
},
clickIndex(e) {
console.log(e)
},
},
}

0 comments on commit bacd574

Please # to comment.