UNPKG

taro-ui-vue3

Version:

Taro UI Rewritten in Vue 3.0

260 lines (259 loc) 7.54 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { h, defineComponent, computed, ref, reactive, nextTick, watch, onMounted, onBeforeMount, mergeProps } from "vue"; import { delayQuerySelector, pxTransform } from "../utils/common"; import Taro from "@tarojs/taro"; import {ScrollView, View} from "@tarojs/components"; import AtList from "../list"; import AtListItem from "../list/item"; import AtToast from "../toast"; const AtIndexes = defineComponent({ name: "AtIndexes", props: { animation: Boolean, isVibrate: { type: Boolean, default: true }, isShowToast: { type: Boolean, default: true }, topKey: { type: String, default: "Top" }, list: { type: Array, default: () => [] }, onClick: Function, onScrollIntoView: Function }, setup(props, {attrs, slots}) { const scrollItemHeights = ref([]); const currentIndex = ref(0); const timeoutTimer = ref(null); const state = reactive({ _scrollIntoView: "", _scrollTop: 0, _tipText: "", _isShowToast: false, isWEB: Taro.getEnv() === Taro.ENV_TYPE.WEB }); const toastStyle = computed(() => ({ minWidth: pxTransform(100) })); const activeIndexStyle = computed(() => (i) => { return currentIndex.value === i ? { color: "white", backgroundColor: "rgba(97, 144, 232, 1)", borderRadius: "40px" } : {}; }); watch(() => props.list, (list, prevList) => { if (list.length !== prevList.length) { initData(); } }); function handleClick(item) { props.onClick && props.onClick(item); } function jumpTarget(_scrollIntoView, idx) { currentIndex.value = idx; updateState({ _scrollIntoView, _scrollTop: scrollItemHeights.value[idx], _tipText: idx === 0 ? props.topKey : props.list[idx - 1].key }); } function __jumpTarget(key) { const index = props.list.findIndex((item) => item.key === key); const targetView = `at-indexes__list-${key}`; jumpTarget(targetView, index + 1); } function updateState(stateValue) { const {_scrollIntoView, _tipText, _scrollTop} = stateValue; state._scrollIntoView = _scrollIntoView; state._tipText = _tipText; state._scrollTop = _scrollTop; state._isShowToast = props.isShowToast; nextTick(() => { clearTimeout(timeoutTimer.value); timeoutTimer.value = setTimeout(() => { state._tipText = ""; state._isShowToast = false; }, 1e3); }); if (props.isVibrate) { Taro.vibrateShort(); } } function initData() { return __async(this, null, function* () { if (props.list.length > 0) { yield _getScrollListItemHeights(props.list).then((res) => { scrollItemHeights.value = [...res]; }); } }); } function _getHeight(selector, delay) { if (!delay) { delay = 500; } return new Promise((resolve) => { delayQuerySelector(this, selector, delay).then((rect) => { if (rect && rect[0]) { resolve(rect[0].height); } }); }); } function _getScrollListItemHeights(list) { return new Promise((resolve) => { if (list.length > 0) { let rawHeights = []; let itemHeights = []; rawHeights.push(_getHeight(`#at-indexes__top`)); list.forEach((item) => { rawHeights.push(_getHeight(`#at-indexes__list-${item.key}`)); }); Promise.all(rawHeights).then((res) => { let height = 0; itemHeights.push(height); for (let i = 0; i < res.length; i++) { height += res[i]; itemHeights.push(height); } resolve(itemHeights); }); } }); } function handleScroll(e) { if (e && e.detail) { state._scrollIntoView = ""; for (let i = 0; i < scrollItemHeights.value.length - 1; i++) { let h1 = Math.floor(scrollItemHeights.value[i]); let h2 = Math.floor(scrollItemHeights.value[i + 1]); if (e.detail.scrollTop >= h1 && e.detail.scrollTop < h2) { currentIndex.value = i; return; } } } } onMounted(() => { initData(); }); onBeforeMount(() => { props.onScrollIntoView && props.onScrollIntoView(__jumpTarget); }); return () => h(View, mergeProps(attrs, { class: "at-indexes" }), { default: () => [ h(View, { class: "at-indexes__menu" }, { default: () => [ h(View, { class: "at-indexes__menu-item", style: activeIndexStyle.value(0), onTap: jumpTarget.bind(this, "at-indexes__top", 0) }, {default: () => props.topKey}), ...props.list.map((dataList, i) => { const {key} = dataList; const targetView = `at-indexes__list-${key}`; return h(View, { key: `${key}-${i}`, class: "at-indexes__menu-item", style: activeIndexStyle.value(i + 1), onTap: jumpTarget.bind(this, targetView, i + 1) }, {default: () => key}); }) ] }), h(ScrollView, { class: "at-indexes__body", scrollY: true, enableBackToTop: true, scrollWithAnimation: props.animation, scrollTop: state._scrollTop, scrollIntoView: !state.isWEB ? state._scrollIntoView : "", onScroll: (e) => handleScroll(e) }, { default: () => [ h(View, { id: "at-indexes__top", class: "at-indexes__content" }, {default: () => slots.default && slots.default()}), ...props.list.map((dataList) => { return h(View, { id: `at-indexes__list-${dataList.key}`, class: "at-indexes__list", key: dataList.key }, { default: () => [ h(View, { class: "at-indexes__list-title" }, {default: () => dataList.title}), h(AtList, null, { default: () => dataList.items && dataList.items.map((item) => h(AtListItem, { key: item.name, title: item.name, onClick: handleClick.bind(this, item) })) }) ] }); }) ] }), h(AtToast, { isOpened: state._isShowToast, text: state._tipText, duration: 1e3, style: toastStyle.value }) ] }); } }); var indexes_default = AtIndexes; export { indexes_default as default };