| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- <template>
- <view
- :id="innerId ?? id"
- :class="[
- 'nana-flex-layout',
- innerClass,
- ]"
- :style="finalStyle"
- @mouseenter="handleMouseEnter"
- @mouseleave="handleMouseLeave"
- @mousedown="handleTouchStart"
- @mouseup="handleTouchEnd"
- @touchstart="handleTouchStart"
- @touchend="handleTouchEnd"
- @click.native.stop="handleClick"
- >
- <slot />
- </view>
- </template>
- <script setup lang="ts">
- /**
- * 组件说明:Flex组件,用于一些布局中快速写容器,是一系列盒子的基础组件。
- */
- import { computed, getCurrentInstance, inject, onMounted, ref, type Ref } from 'vue';
- import { useTheme } from '../theme/ThemeDefine';
- import { RandomUtils } from '@imengyu/imengyu-utils';
- import { useBaseViewStyleBuilder } from '../layout/BaseView';
- import { TouchableClickEventInceptorKey, type TouchableFlexProps } from './Touchable';
- const props = withDefaults(defineProps<TouchableFlexProps>(), {
- activeOpacity: 0.7,
- touchable: true,
- setCursor: true,
- });
- const themeContext = useTheme();
- const { commonStyle } = useBaseViewStyleBuilder(props);
- const finalStyle = computed(() => {
- const obj : Record<string, any> = {};
- if (props.pressedColor != undefined) {
- if (isPressed.value)
- obj.backgroundColor = themeContext.resolveThemeColor(props.pressedColor);
- } else if (props.activeOpacity != undefined)
- obj.opacity = isPressed.value ? props.activeOpacity : 1;
- const o : Record<string, any> = {
- ...commonStyle.value,
- ...obj,
- cursor: props.setCursor ? (props.touchable ? 'pointer' : 'not-allowed') : 'default',
- }
- for (const key in o) {
- if (o[key] === undefined)
- delete o[key];
- }
- return o;
- })
- defineOptions({
- options: {
- styleIsolation: "shared",
- virtualHost: true
- }
- })
- const emit = defineEmits([ "click", "state" ]);
- const isPressed = ref(false);
- const clickEventInceptor = inject<(Ref<() => void>)|null>(TouchableClickEventInceptorKey, null);
- function handleTouchStart() {
- if (props.touchable) {
- isPressed.value = true; // 按下时改变状态
- emit('state', 'active');
- }
- }
- function handleMouseEnter() {
- if (props.touchable)
- emit('state', 'active')
- }
- function handleMouseLeave() {
- if (props.touchable)
- emit('state', 'default')
- }
- function handleClick(e: Event) {
- if (clickEventInceptor && clickEventInceptor.value) {
- clickEventInceptor.value();
- return;
- }
- if (props.touchable) {
- emit('state', 'default')
- emit('click', e);
- }
- }
- function handleTouchEnd() {
- if (props.touchable) {
- isPressed.value = false; // 释放时恢复状态
- emit('state', 'default');
- }
- }
- onMounted(() => {
- emit('state', 'default')
- })
-
- const instance = getCurrentInstance();
- const id = 'flex-item-' + RandomUtils.genNonDuplicateID(15);
- defineExpose({
- measure() {
- return new Promise((resolve) => {
- const tabItem = uni.createSelectorQuery()
- .in(instance)
- .select(`#${id}`);
- tabItem.boundingClientRect().exec((res) => {
- resolve(res)
- })
- });
- },
- })
- </script>
|