Эх сурвалжийг харах

增加滚动列表、文本组件

ming 3 жил өмнө
parent
commit
a593c83b55

+ 9 - 0
common/common.scss

@@ -12,6 +12,9 @@ page{
 view{
 	box-sizing: border-box;
 }
+::-webkit-scrollbar{
+	display: none;
+}
 
 .primary {
 	color: var(--primary);
@@ -88,6 +91,12 @@ view{
 .text-justify{
 	text-align-last: justify;
 }
+.underline{
+	text-decoration: underline;
+}
+.line-through{
+	text-decoration: line-through;
+}
 
 .flex{
 	display: flex;

+ 5 - 1
components/fs-card/fs-card.vue

@@ -4,7 +4,7 @@
 			<view class="fs-card-title" v-if="slots.title || title" :style="titleStyle">
 				<slot name="title">{{title}}</slot>
 			</view>
-			<view class="fs-card-content">
+			<view :class="{'fs-card-content': contentPadding}">
 				<slot></slot>
 			</view>
 			<view class="fs-card-ft" v-if="slots.footer">
@@ -34,6 +34,7 @@ const props = defineProps({
 		type: Boolean,
 		default: false
 	},
+	contentPadding: Boolean,
 })
 
 const slots = useSlots()
@@ -60,6 +61,9 @@ const slots = useSlots()
 		padding: 20rpx var(--gutter);
 		border-top: 2rpx solid var(--border-color);
 	}
+	&-content{
+		padding: 20rpx var(--gutter);
+	}
 	
 	&-full{
 		margin-left: 0;

+ 113 - 0
components/fs-scroll-list/fs-scroll-list.vue

@@ -0,0 +1,113 @@
+<template>
+	<view class="fs-scroll-list">
+		<scroll-view 
+			scroll-x
+			:show-scrollbar="false"
+			:lower-threshold="0" 
+			:upper-threshold="0" 
+			@scrolltoupper="handleToUpper" 
+			@scrolltolower="handleToLower"
+			@scroll="handleScroll"
+		>
+			<view class="fs-scroll-list-content">
+				<slot></slot>
+			</view>
+		</scroll-view>
+		
+		<view class="fs-scroll-indicator">
+			<view class="fs-scroll-indicator-line">
+				<view class="fs-scroll-indicator-bar" :style="barStyle"></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'fs-scroll-list'
+}
+</script>
+
+<script setup>
+import { onMounted, reactive, ref, computed, getCurrentInstance } from 'vue'
+
+const props = defineProps({
+	indicatorWidth: {
+		type: String,
+		default: '50px'
+	},
+	indicatorLineWidth: {
+		type: String,
+		default: '15px'
+	},
+	indicatorColor: {
+		type: String,
+		default: '#f2f2f2'
+	},
+	indicatorActiveColor: {
+		type: String,
+		default: '#3c9cff'
+	}
+})
+const emits = defineEmits(['left', 'right'])
+
+const state = reactive({
+	listWidth: 0,
+	contentWidth: 0,
+	scrollWidth: 0
+})
+onMounted(() => {
+	uni.createSelectorQuery().in(getCurrentInstance().ctx).select('.fs-scroll-list').boundingClientRect(data => {
+		state.listWidth = data.width
+	}).exec()
+})
+
+
+const indicatorLeftWidth = computed(() => {
+	return parseInt(props.indicatorWidth) - parseInt(props.indicatorLineWidth)
+})
+const listLeftWidth = computed(() => {
+	return state.contentWidth - state.listWidth
+})
+const barStyle = computed(() => {
+	const x = state.scrollWidth * indicatorLeftWidth.value / listLeftWidth.value  + 'px'
+	return `transform: translateX(${x})`
+})
+
+const handleScroll = event => {
+	state.scrollWidth = event.detail.scrollLeft
+	state.contentWidth = event.detail.scrollWidth
+}
+
+const handleToUpper = () => emits('left')
+const handleToLower = () => emits('right')
+</script>
+
+<style lang="scss" scoped>
+.fs-scroll-list{
+	&-box{
+		display: flex;
+	}
+	&-content{
+		display: flex;
+		flex-wrap: nowrap;
+	}
+}
+.fs-scroll-indicator{
+	display: flex;
+	justify-content: center;
+	
+	&-line{
+		background-color: v-bind(indicatorColor);
+		width: v-bind(indicatorWidth);
+		height: 8rpx;
+		border-radius: 50rpx;
+		overflow: hidden;
+	}
+	&-bar{
+		background-color: v-bind(indicatorActiveColor);
+		height: 8rpx;
+		width: v-bind(indicatorLineWidth);
+	}
+}
+</style>

+ 5 - 1
components/fs-sidebar/fs-sidebar.vue

@@ -7,7 +7,7 @@
 				v-for="(item, index) in list"
 				:key="item[valueKey]"
 				@click="handleClick(item, index)">
-				{{item.title}}
+				{{item[titleKey]}}
 			</view>
 		</view>
 		<view class="fs-side-bar-right">
@@ -30,6 +30,10 @@ const props = defineProps({
 	valueKey: {
 		type: String,
 		default: 'id'
+	},
+	titleKey: {
+		type: String,
+		default: 'title'
 	}
 })
 const emits = defineEmits(['change'])

+ 77 - 0
components/fs-text/fs-text.vue

@@ -0,0 +1,77 @@
+<template>
+	<text 
+		:class="[colorType,decoration,{block}]" 
+		:style="styleStr"
+		@click="handleClick">
+			{{formatText(text)}}
+		</text>
+</template>
+
+<script>
+export default {
+	name: 'fs-text'
+}
+</script>
+
+<script setup>
+import { computed } from 'vue'
+
+const props = defineProps({
+	text: String,
+	mode: {
+		type: String,
+		validator(value) {
+			return ['price', 'phone', 'name'].includes(value)
+		}
+	},
+	colorType: {
+	  type: String,
+		validator(value) {
+			return ['primary', 'success', 'info', 'warning', 'danger'].includes(value)
+		}
+	},
+	color: String,
+	link: String,
+	linkType: {
+		type: String,
+		default: 'navigateTo'
+	},
+	block: Boolean,
+	decoration: {
+		type: String,
+		validator(value) {
+			return ['underline', 'line-through'].includes(value)
+		}
+	}
+})
+const emits = defineEmits(['click'])
+
+const styleStr = computed(() => {
+	return props.color ? `color: ${props.color};` : ''
+})
+
+const formatText = text => {
+	if (props.mode === 'price') {
+		return '¥' + text
+	} else if (props.mode === 'name') {
+		return text[0] + '*' + text[text.length - 1]
+	}
+	return text
+}
+const handleClick = () => {
+	if (props.mode === 'phone') {
+		uni.makePhoneCall({
+			phoneNumber: props.text
+		})
+	} else if (props.link) {
+		uni[props.linkType]({
+			url: props.link
+		})
+	}
+	emits('click')
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 1 - 1
pages/my/my.vue

@@ -112,7 +112,7 @@ const shortcutList = ref([
 	}
 ])
 
-const showLogin = ref(true)
+const showLogin = ref(false)
 
 const handleLogout = () => {
 	store.dispatch('logout').then(res => {