magiccube-vue3
Version:
vue3-js版组件库
141 lines (121 loc) • 4.7 kB
JavaScript
import { ref, computed, getCurrentInstance } from 'vue'
import getFormValidMethod from '../../utils/form-valid'
import CITY_DATA from '../../data/city.json'
import { cityCodeToData } from '../../utils/common'
const Address = {
name: 'McAddress',
props: {
city: String,
address: String,
cityData: {
type: [Array, Object],
default: () => CITY_DATA
},
placeholder: {
type: String,
default: '请选择'
},
disabled: Boolean,
maxlength: [String, Number]
},
emits: ['change', 'update:modelValue'],
setup(props, { emit }) {
const pickerEl = ref(null)
const visible = ref(false)
const cityValue = ref([])
const cityData = ref([])
const cityName = ref('')
const addressValue = ref('')
const preview = computed(() => `${cityName.value} ${addressValue.value}`)
const instance = getCurrentInstance()
const { fieldName, validator, errorMessage } = getFormValidMethod(instance)
const fieldError = computed(() => fieldName && errorMessage?.value ? errorMessage.value[fieldName] : '')
const model = computed(() => {
const c = props.city? cityCodeToData(props.city, props.cityData, 'propertyCode') : []
const cStr = c[0]?.defaultName || ''
const a = props.address || ''
return cStr || a? cStr + a : ''
})
const handleInint = () => {
if(props.city){
cityData.value = cityCodeToData(props.city, props.cityData, 'propertyCode')
cityName.value = cityData.value.map(n => n.defaultName).join(',')
}
if(props.address){
addressValue.value = props.address
}
}
const handleConfirmPopup = () => {
if (props.disabled) return false
const data = {
str: preview.value,
city: cityValue.value?.length? cityValue.value : '',
address: addressValue.value
}
emit('change', data)
handleCancelPopup()
validator && validator('change', data)
}
const handleCancelPopup = () => {
visible.value = false
}
const handleVisible = () => {
if (props.disabled) return false
visible.value = true
}
const handleCityChange = array => {
if (props.disabled) return false
const item = array[0] || {}
cityName.value = item.defaultName
cityValue.value = item.propertyCode
}
return () => (
<div ref={pickerEl}
class={[
'mc-address',
{
disabled: props.disabled
}
]}>
<div class={[
'mc-address__result',
{
error: Boolean(fieldError.value)
}
]}>
<span style="display:flex;justify-content:center;margin-right:8px;">
<img src={require('../../img/icon_location.svg')} />
</span>
{
model.value? <span style="padding-right:8px;">{model.value}</span> : ''
}
<McLink onClick={handleVisible}>{model.value? '重新选择' : '选择地址'}</McLink>
</div>
<McPopup v-model={visible.value}
title="选择地址"
width="732"
click-mask={false}
onInit={handleInint}
onConfirm={handleConfirmPopup}
onCancel={handleCancelPopup}
onClose={handleCancelPopup}>
<div style="margin-bottom:24px;">
<McCityPicker v-model={cityData.value} onChange={handleCityChange} />
</div>
<div style="margin-bottom:24px;">
<McTextarea v-model={addressValue.value} max={props.maxlength} placeholder="请输入详细地址" />
</div>
<div>
<label style="margin-right:16px;color:#828B97;">预览</label>
<span>{preview.value}</span>
</div>
</McPopup>
</div>
)
}
}
Address.install = Vue => {
Vue.component(Address.name, Address)
}
const McAddress = Address
export { McAddress, McAddress as default }