init
This commit is contained in:
104
uni_modules/nutui-uni/components/address/address.ts
Normal file
104
uni_modules/nutui-uni/components/address/address.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import { CHANGE_EVENT, CLOSE_EVENT, SELECTED_EVENT, UPDATE_MODEL_EVENT, UPDATE_VISIBLE_EVENT } from '../_constants'
|
||||
import { commonProps, isBoolean, makeArrayProp, makeNumericProp, makeStringProp, truthProp } from '../_utils'
|
||||
import { popupProps } from '../popup'
|
||||
import type { AddressExistRegionData, AddressRegionData, AddressType } from './type'
|
||||
|
||||
export const addressProps = {
|
||||
...popupProps,
|
||||
...commonProps,
|
||||
/**
|
||||
* @description 设置默认选中值
|
||||
*/
|
||||
modelValue: makeArrayProp<any>([]),
|
||||
|
||||
/**
|
||||
* @description 是否打开地址选择
|
||||
*/
|
||||
visible: Boolean,
|
||||
|
||||
/**
|
||||
* @description 地址选择类型:'exist' | 'custom' | 'custom2'
|
||||
*/
|
||||
type: makeStringProp<AddressType>('custom'),
|
||||
|
||||
/**
|
||||
* @description 自定义地址选择标题
|
||||
*/
|
||||
customAddressTitle: makeStringProp(''),
|
||||
|
||||
/**
|
||||
* @description 省份数据
|
||||
*/
|
||||
province: makeArrayProp<AddressRegionData>([]),
|
||||
|
||||
/**
|
||||
* @description 城市数据
|
||||
*/
|
||||
city: makeArrayProp<AddressRegionData>([]),
|
||||
|
||||
/**
|
||||
* @description 县区数据
|
||||
*/
|
||||
country: makeArrayProp<AddressRegionData>([]),
|
||||
|
||||
/**
|
||||
* @description 乡镇数据
|
||||
*/
|
||||
town: makeArrayProp<AddressRegionData>([]),
|
||||
|
||||
/**
|
||||
* @description 是否显示 '选择其他地区' 按钮。仅在类型为 'exist' 时生效
|
||||
*/
|
||||
isShowCustomAddress: truthProp,
|
||||
|
||||
/**
|
||||
* @description 现存地址列表
|
||||
*/
|
||||
existAddress: makeArrayProp<AddressExistRegionData>([]),
|
||||
|
||||
/**
|
||||
* @description 已有地址标题
|
||||
*/
|
||||
existAddressTitle: makeStringProp(''),
|
||||
|
||||
/**
|
||||
* @description 切换自定义地址和已有地址的按钮标题
|
||||
*/
|
||||
customAndExistTitle: makeStringProp(''),
|
||||
|
||||
/**
|
||||
* @description 弹层中内容容器的高度
|
||||
*/
|
||||
height: makeNumericProp('200'),
|
||||
|
||||
/**
|
||||
* @description 列提示文字
|
||||
*/
|
||||
columnsPlaceholder: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
}
|
||||
|
||||
export type AddressProps = ExtractPropTypes<typeof addressProps>
|
||||
|
||||
export const addressEmits = {
|
||||
[UPDATE_VISIBLE_EVENT]: (val: boolean) => isBoolean(val),
|
||||
[UPDATE_MODEL_EVENT]: () => true,
|
||||
[CLOSE_EVENT]: (val: {
|
||||
data: any
|
||||
type: string
|
||||
}) => val instanceof Object,
|
||||
[CHANGE_EVENT]: (val: {
|
||||
next?: string
|
||||
value?: AddressRegionData
|
||||
custom: string
|
||||
}) => val instanceof Object,
|
||||
switchModule: (val: { type: AddressType }) => val instanceof Object,
|
||||
closeMask: (val: { closeWay: 'self' | 'mask' | 'cross' }) => val instanceof Object,
|
||||
[SELECTED_EVENT]: (prevExistAdd: AddressExistRegionData, item: AddressExistRegionData, copyExistAdd: AddressExistRegionData[]) => prevExistAdd instanceof Object && item instanceof Object && copyExistAdd instanceof Object,
|
||||
|
||||
}
|
||||
|
||||
export type AddressEmits = typeof addressEmits
|
||||
443
uni_modules/nutui-uni/components/address/address.vue
Normal file
443
uni_modules/nutui-uni/components/address/address.vue
Normal file
@@ -0,0 +1,443 @@
|
||||
<script setup lang="ts">
|
||||
import type { ScrollViewOnScrollEvent } from '@uni-helper/uni-app-types'
|
||||
import { computed, defineComponent, reactive, ref, watch } from 'vue'
|
||||
import { CHANGE_EVENT, CLOSE_EVENT, PREFIX, SELECTED_EVENT, UPDATE_MODEL_EVENT, UPDATE_VISIBLE_EVENT } from '../_constants'
|
||||
import { getMainClass } from '../_utils'
|
||||
import requestAniFrame from '../_utils/raf'
|
||||
import { useTranslate } from '../../locale'
|
||||
import NutElevator from '../elevator/elevator.vue'
|
||||
import NutIcon from '../icon/icon.vue'
|
||||
import NutPopup from '../popup/popup.vue'
|
||||
import { addressEmits, addressProps } from './address'
|
||||
import type { AddressExistRegionData, AddressRegionData, CustomRegionData } from './type'
|
||||
|
||||
const props = defineProps(addressProps)
|
||||
const emit = defineEmits(addressEmits)
|
||||
|
||||
const classes = computed(() => {
|
||||
return getMainClass(props, componentName)
|
||||
})
|
||||
|
||||
const showPopup = ref(props.visible)
|
||||
const privateType = ref(props.type)
|
||||
const tabIndex = ref(0)
|
||||
const prevTabIndex = ref(0)
|
||||
const tabName = ref(['province', 'city', 'country', 'town'])
|
||||
const scrollDis = ref([0, 0, 0, 0])
|
||||
const scrollTop = ref(0)
|
||||
const regionData = reactive<Array<AddressRegionData[]>>([])
|
||||
|
||||
const regionList = computed(() => {
|
||||
switch (tabIndex.value) {
|
||||
case 0:
|
||||
return props.province
|
||||
case 1:
|
||||
return props.city
|
||||
case 2:
|
||||
return props.country
|
||||
default:
|
||||
return props.town
|
||||
}
|
||||
})
|
||||
|
||||
function transformData(data: AddressRegionData[]) {
|
||||
if (!Array.isArray(data))
|
||||
throw new TypeError('params muse be array.')
|
||||
|
||||
if (!data.length)
|
||||
return []
|
||||
|
||||
data.forEach((item: AddressRegionData) => {
|
||||
if (!item.title)
|
||||
console.warn('[NutUI] <Address> 请检查数组选项的 title 值是否有设置 ,title 为必填项 .')
|
||||
})
|
||||
|
||||
const newData: CustomRegionData[] = []
|
||||
|
||||
data = data.sort((a: AddressRegionData, b: AddressRegionData) => {
|
||||
return a.title.localeCompare(b.title)
|
||||
})
|
||||
|
||||
data.forEach((item: AddressRegionData) => {
|
||||
const index = newData.findIndex((value: CustomRegionData) => value.title === item.title)
|
||||
if (index <= -1) {
|
||||
newData.push({
|
||||
title: item.title,
|
||||
list: ([] as any).concat(item),
|
||||
})
|
||||
}
|
||||
else {
|
||||
newData[index].list.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
return newData
|
||||
}
|
||||
|
||||
const selectedRegion = ref<AddressRegionData[]>([])
|
||||
|
||||
let selectedExistAddress = reactive({}) // 当前选择的地址
|
||||
|
||||
const closeWay = ref<'self' | 'mask' | 'cross'>('self')
|
||||
|
||||
// 设置选中省市县
|
||||
function initCustomSelected() {
|
||||
regionData[0] = props.province || []
|
||||
regionData[1] = props.city || []
|
||||
regionData[2] = props.country || []
|
||||
regionData[3] = props.town || []
|
||||
|
||||
const defaultValue = props.modelValue
|
||||
const num = defaultValue.length
|
||||
if (num > 0) {
|
||||
tabIndex.value = num - 1
|
||||
if (regionList.value.length === 0) {
|
||||
tabIndex.value = 0
|
||||
return
|
||||
}
|
||||
for (let index = 0; index < num; index++) {
|
||||
const arr: AddressRegionData[] = regionData[index]
|
||||
selectedRegion.value[index] = arr.filter((item: AddressRegionData) => item.id === defaultValue[index])[0]
|
||||
}
|
||||
scrollTo()
|
||||
}
|
||||
}
|
||||
|
||||
function getTabName(item: AddressRegionData | null, index: number) {
|
||||
if (item && item.name)
|
||||
return item.name
|
||||
if (tabIndex.value < index && item)
|
||||
return item.name
|
||||
|
||||
else
|
||||
return props.columnsPlaceholder[index] || translate('select')
|
||||
}
|
||||
|
||||
// 手动关闭 点击叉号(cross),或者蒙层(mask)
|
||||
function handClose(type = 'self') {
|
||||
closeWay.value = type === 'cross' ? 'cross' : 'self'
|
||||
|
||||
showPopup.value = false
|
||||
}
|
||||
|
||||
// 点击遮罩层关闭
|
||||
function clickOverlay() {
|
||||
closeWay.value = 'mask'
|
||||
}
|
||||
|
||||
// 切换下一级列表
|
||||
function nextAreaList(item: AddressRegionData) {
|
||||
const tab = tabIndex.value
|
||||
prevTabIndex.value = tabIndex.value
|
||||
const callBackParams: {
|
||||
next?: string
|
||||
value?: AddressRegionData
|
||||
custom: string
|
||||
} = {
|
||||
custom: tabName.value[tab],
|
||||
}
|
||||
|
||||
selectedRegion.value[tab] = item
|
||||
|
||||
// 删除右边已选择数据
|
||||
selectedRegion.value.splice(tab + 1, selectedRegion.value.length - (tab + 1))
|
||||
|
||||
callBackParams.value = item
|
||||
|
||||
if (regionData[tab + 1]?.length > 0) {
|
||||
tabIndex.value = tab + 1
|
||||
|
||||
callBackParams.next = tabName.value[tabIndex.value]
|
||||
|
||||
scrollToTop()
|
||||
}
|
||||
else {
|
||||
handClose()
|
||||
emit(UPDATE_MODEL_EVENT)
|
||||
}
|
||||
emit(CHANGE_EVENT, callBackParams)
|
||||
}
|
||||
// 切换地区Tab
|
||||
function changeRegionTab(item: AddressRegionData, index: number) {
|
||||
prevTabIndex.value = tabIndex.value
|
||||
if (getTabName(item, index)) {
|
||||
tabIndex.value = index
|
||||
scrollTo()
|
||||
}
|
||||
}
|
||||
|
||||
function scrollChange(e: ScrollViewOnScrollEvent) {
|
||||
scrollDis.value[tabIndex.value] = e.detail.scrollTop
|
||||
}
|
||||
|
||||
function scrollToTop() {
|
||||
// scrollTop 不会实时变更。当再次赋值时,scrollTop无变化时,不会触发滚动
|
||||
scrollTop.value += 1
|
||||
requestAniFrame(() => {
|
||||
setTimeout(() => {
|
||||
// 直接设置为0无效
|
||||
scrollTop.value = 0.01
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
|
||||
function scrollTo() {
|
||||
// scrollTop 不会实时变更。当再次赋值时,scrollTop无变化时,不会触发滚动
|
||||
scrollTop.value += 1
|
||||
requestAniFrame(() => {
|
||||
setTimeout(() => {
|
||||
scrollTop.value = scrollDis.value[tabIndex.value]
|
||||
}, 10)
|
||||
})
|
||||
}
|
||||
|
||||
// 选择现有地址
|
||||
function selectedExist(item: AddressExistRegionData) {
|
||||
const copyExistAdd = props.existAddress
|
||||
let prevExistAdd: AddressExistRegionData = {} as AddressExistRegionData
|
||||
|
||||
copyExistAdd.forEach((list: AddressExistRegionData) => {
|
||||
if (list && list.selectedAddress)
|
||||
prevExistAdd = list
|
||||
list.selectedAddress = false
|
||||
})
|
||||
|
||||
item.selectedAddress = true
|
||||
|
||||
selectedExistAddress = item
|
||||
|
||||
emit(SELECTED_EVENT, prevExistAdd, item, copyExistAdd)
|
||||
|
||||
handClose()
|
||||
}
|
||||
// 初始化
|
||||
function initAddress() {
|
||||
selectedRegion.value = []
|
||||
tabIndex.value = 0
|
||||
scrollTo()
|
||||
}
|
||||
|
||||
// 关闭
|
||||
function close() {
|
||||
const data = {
|
||||
addressIdStr: '',
|
||||
addressStr: '',
|
||||
province: selectedRegion.value[0],
|
||||
city: selectedRegion.value[1],
|
||||
country: selectedRegion.value[2],
|
||||
town: selectedRegion.value[3],
|
||||
}
|
||||
|
||||
const callBackParams = {
|
||||
data: {},
|
||||
type: privateType.value,
|
||||
}
|
||||
|
||||
if (['custom', 'custom2'].includes(privateType.value)) {
|
||||
[0, 1, 2, 3].forEach((i) => {
|
||||
const item = selectedRegion.value[i]
|
||||
data.addressIdStr += `${i ? '_' : ''}${(item && item.id) || 0}`
|
||||
data.addressStr += (item && item.name) || ''
|
||||
})
|
||||
|
||||
callBackParams.data = data
|
||||
}
|
||||
else {
|
||||
callBackParams.data = selectedExistAddress
|
||||
}
|
||||
|
||||
initAddress()
|
||||
|
||||
if (closeWay.value === 'self')
|
||||
emit(CLOSE_EVENT, callBackParams)
|
||||
else
|
||||
emit('closeMask', { closeWay: closeWay.value })
|
||||
|
||||
emit(UPDATE_VISIBLE_EVENT, false)
|
||||
}
|
||||
|
||||
// 选择其他地址
|
||||
function switchModule() {
|
||||
const type = privateType.value
|
||||
privateType.value = type === 'exist' ? 'custom' : 'exist'
|
||||
initAddress()
|
||||
emit('switchModule', { type: privateType.value })
|
||||
}
|
||||
|
||||
function handleElevatorItem(key: string, item: AddressRegionData) {
|
||||
nextAreaList(item)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(value) => {
|
||||
showPopup.value = value
|
||||
},
|
||||
)
|
||||
|
||||
watch(
|
||||
() => showPopup.value,
|
||||
(value) => {
|
||||
if (value)
|
||||
initCustomSelected()
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const componentName = `${PREFIX}-address`
|
||||
const { translate } = useTranslate(componentName)
|
||||
|
||||
export default defineComponent({
|
||||
name: componentName,
|
||||
options: {
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NutPopup
|
||||
v-model:visible="showPopup"
|
||||
:z-index="zIndex"
|
||||
position="bottom"
|
||||
:lock-scroll="lockScroll"
|
||||
:round="round"
|
||||
@close="close"
|
||||
@click-overlay="clickOverlay"
|
||||
@open="closeWay = 'self'"
|
||||
>
|
||||
<view :class="classes" :style="customStyle">
|
||||
<view class="nut-address__header">
|
||||
<view class="nut-address__header-back" @click="switchModule">
|
||||
<slot v-if="type === 'exist' && privateType === 'custom'" name="backIcon">
|
||||
<NutIcon name="left" size="14px" />
|
||||
</slot>
|
||||
</view>
|
||||
|
||||
<view class="nut-address__header__title">
|
||||
{{
|
||||
privateType === 'custom'
|
||||
? customAddressTitle || translate('selectRegion')
|
||||
: existAddressTitle || translate('deliveryTo')
|
||||
}}
|
||||
</view>
|
||||
|
||||
<view class="nut-address__header-close" @click="handClose('cross')">
|
||||
<slot name="closeIcon">
|
||||
<NutIcon name="close" custom-color="#cccccc" size="14px" />
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 请选择 -->
|
||||
<view v-if="['custom', 'custom2'].includes(privateType)" class="nut-address__custom">
|
||||
<view class="nut-address__region">
|
||||
<view
|
||||
v-for="(item, index) in selectedRegion"
|
||||
:key="index"
|
||||
class="nut-address__region-item "
|
||||
:class="[index === tabIndex ? 'active' : '']"
|
||||
@click="changeRegionTab(item, index)"
|
||||
>
|
||||
<view>{{ getTabName(item, index) }} </view>
|
||||
<view class="nut-address__region-line--mini" :class="{ active: index === tabIndex }" />
|
||||
</view>
|
||||
<view v-if="tabIndex === selectedRegion.length" class="active nut-address__region-item">
|
||||
<view>{{ getTabName(null, selectedRegion.length) }} </view>
|
||||
<view class="nut-address__region-line--mini active" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="privateType === 'custom'" class="nut-address__detail">
|
||||
<div class="nut-address__detail-list">
|
||||
<scroll-view
|
||||
:scroll-y="true"
|
||||
:style="{ height: '100%' }"
|
||||
:scroll-top="scrollTop"
|
||||
@scroll="scrollChange"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in regionList"
|
||||
:key="index"
|
||||
class="nut-address__detail-item"
|
||||
:class="[selectedRegion[tabIndex]?.id === item.id ? 'active' : '']"
|
||||
@click="nextAreaList(item)"
|
||||
>
|
||||
<view>
|
||||
<slot v-if="selectedRegion[tabIndex]?.id === item.id" name="icon">
|
||||
<NutIcon name="Check" custom-class="nut-address-select-icon" width="13px" />
|
||||
</slot>{{ item.name }}
|
||||
</view>
|
||||
</div>
|
||||
</scroll-view>
|
||||
</div>
|
||||
</view>
|
||||
|
||||
<view v-else class="nut-address__elevator-group">
|
||||
<NutElevator
|
||||
:height="height"
|
||||
:index-list="transformData(regionList)"
|
||||
@click-item="handleElevatorItem"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 配送至 -->
|
||||
<view v-else-if="privateType === 'exist'" class="nut-address__exist">
|
||||
<div class="nut-address__exist-group">
|
||||
<ul class="nut-address__exist-group-list">
|
||||
<li
|
||||
v-for="(item, index) in existAddress"
|
||||
:key="index"
|
||||
class="nut-address__exist-group-item"
|
||||
:class="[item.selectedAddress ? 'active' : '']"
|
||||
@click="selectedExist(item)"
|
||||
>
|
||||
<slot v-if="!item.selectedAddress" name="unselectedIcon">
|
||||
<NutIcon name="location2" custom-class="nut-address-select-icon" width="13px" />
|
||||
</slot>
|
||||
|
||||
<slot v-if="item.selectedAddress" name="icon">
|
||||
<NutIcon name="Check" custom-class="nut-address-select-icon" width="13px" />
|
||||
</slot>
|
||||
|
||||
<div class="nut-address__exist-item-info">
|
||||
<div v-if="item.name && item.phone" class="nut-address__exist-item-info-top">
|
||||
<div class="nut-address__exist-item-info-name">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div class="nut-address__exist-item-info-phone">
|
||||
{{ item.phone }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nut-address__exist-item-info-bottom">
|
||||
<view>
|
||||
{{ item.provinceName + item.cityName + item.countyName + item.townName + item.addressDetail }}
|
||||
</view>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-if="isShowCustomAddress" class="nut-address__exist-choose" @click="switchModule">
|
||||
<div class="nut-address__exist-choose-btn">
|
||||
{{
|
||||
customAndExistTitle || translate('chooseAnotherAddress')
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="!isShowCustomAddress">
|
||||
<slot name="bottom" />
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</NutPopup>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './index';
|
||||
</style>
|
||||
232
uni_modules/nutui-uni/components/address/index.scss
Normal file
232
uni_modules/nutui-uni/components/address/index.scss
Normal file
@@ -0,0 +1,232 @@
|
||||
@import '../popup/index';
|
||||
@import '../elevator/index';
|
||||
|
||||
.nut-theme-dark {
|
||||
.nut-address {
|
||||
&__header {
|
||||
color: $dark-color;
|
||||
|
||||
&__title {
|
||||
color: $dark-color;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-address__custom {
|
||||
.nut-address__region {
|
||||
color: $dark-color;
|
||||
}
|
||||
|
||||
.nut-address__detail {
|
||||
.nut-address__detail-list {
|
||||
.nut-address__detail-item {
|
||||
color: $dark-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-address__exist {
|
||||
.nut-address__exist-group {
|
||||
.nut-address__exist-group-list {
|
||||
.nut-address__exist-group-item {
|
||||
color: $dark-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-address__exist-choose {
|
||||
border-top: 1px solid $dark-background;
|
||||
}
|
||||
}
|
||||
|
||||
&-custom-buttom {
|
||||
border-top: 1px solid $dark-background;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-address {
|
||||
display: block;
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 68px;
|
||||
padding: 0 20px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
|
||||
&__title {
|
||||
display: block;
|
||||
font-size: $address-header-title-font-size;
|
||||
color: $address-header-title-color;
|
||||
}
|
||||
}
|
||||
|
||||
// 请选择
|
||||
.nut-address__custom {
|
||||
display: block;
|
||||
|
||||
.nut-address__region {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
// margin-top: 32px;
|
||||
padding: 0 20px;
|
||||
font-size: $address-region-tab-font-size;
|
||||
color: $address-region-tab-color;
|
||||
|
||||
.nut-address__region-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
min-width: 2px;
|
||||
margin-right: 30px;
|
||||
|
||||
&.active {
|
||||
font-weight: $address-region-tab-active-item-font-weight;
|
||||
}
|
||||
|
||||
view {
|
||||
display: block;
|
||||
max-width: 100px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nut-address__region-line--mini {
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 0;
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 3px;
|
||||
margin-top: 5px;
|
||||
background: $address-region-tab-line;
|
||||
transition: 0.2s all linear;
|
||||
|
||||
&.active {
|
||||
width: 26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-address__region-line {
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 20px;
|
||||
display: inline-block;
|
||||
width: 26px;
|
||||
height: 3px;
|
||||
margin-top: 5px;
|
||||
background: $address-region-tab-line;
|
||||
border-radius: $address-region-tab-line-border-radius;
|
||||
opacity: $address-region-tab-line-opacity;
|
||||
transition: 0.2s all linear;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-address__detail {
|
||||
display: block;
|
||||
margin: 20px 20px 0;
|
||||
|
||||
.nut-address__detail-list {
|
||||
// overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
height: 270px;
|
||||
padding: 0;
|
||||
padding-top: 15px;
|
||||
|
||||
.nut-address__detail-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: $address-region-item-font-size;
|
||||
color: $address-region-item-color;
|
||||
|
||||
&.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-address__elevator-group {
|
||||
display: flex;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
// 配送至
|
||||
.nut-address__exist {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
|
||||
.nut-address__exist-group {
|
||||
height: 279px;
|
||||
padding: 15px 20px 0;
|
||||
overflow-y: scroll;
|
||||
|
||||
.nut-address__exist-group-list {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
|
||||
.nut-address__exist-group-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: $font-size-1;
|
||||
line-height: 14px;
|
||||
color: #333;
|
||||
|
||||
&.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.exist-item-icon {
|
||||
margin-right: $address-item-margin-right;
|
||||
color: $address-icon-color !important;
|
||||
}
|
||||
|
||||
// span {
|
||||
// display: inline-block;
|
||||
// flex: 1;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-address__exist-choose {
|
||||
width: 100%;
|
||||
height: 54px;
|
||||
padding: 6px 0 0;
|
||||
border-top: 1px solid #f2f2f2;
|
||||
|
||||
.nut-address__exist-choose-btn {
|
||||
width: 90%;
|
||||
height: 42px;
|
||||
margin: auto;
|
||||
font-size: 15px;
|
||||
line-height: 42px;
|
||||
color: $white;
|
||||
text-align: center;
|
||||
background: $button-primary-background-color;
|
||||
border-radius: 21px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-select-icon {
|
||||
margin-right: $address-item-margin-right;
|
||||
color: $address-icon-color !important;
|
||||
}
|
||||
}
|
||||
2
uni_modules/nutui-uni/components/address/index.ts
Normal file
2
uni_modules/nutui-uni/components/address/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './address'
|
||||
export * from './type'
|
||||
23
uni_modules/nutui-uni/components/address/type.ts
Normal file
23
uni_modules/nutui-uni/components/address/type.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export interface AddressRegionData {
|
||||
name: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface CustomRegionData {
|
||||
title: string
|
||||
list: any[]
|
||||
}
|
||||
|
||||
export interface AddressExistRegionData {
|
||||
id?: string | number
|
||||
provinceName: string
|
||||
cityName: string
|
||||
countyName: string
|
||||
townName: string
|
||||
addressDetail: string
|
||||
selectedAddress: boolean
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export const addressType = ['exist', 'custom', 'custom2'] as const
|
||||
export type AddressType = (typeof addressType)[number]
|
||||
Reference in New Issue
Block a user