mirror of
https://github.com/yudaocode/yudao-ui-admin-vue3.git
synced 2026-03-29 23:06:13 +00:00
review:“新增 iframe 和省市区选择器组件”
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref, watch } from 'vue'
|
import { onMounted, ref, watch } from 'vue'
|
||||||
import { getAreaTree } from '@/api/system/area'
|
import { getAreaTree } from '@/api/system/area'
|
||||||
|
// TODO @puhui999:这里 handleTree 貌似没用到
|
||||||
import { handleTree } from '@/utils/tree'
|
import { handleTree } from '@/utils/tree'
|
||||||
|
|
||||||
defineOptions({ name: 'AreaSelect' })
|
defineOptions({ name: 'AreaSelect' })
|
||||||
@@ -34,7 +35,7 @@ interface AreaVO {
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue?: number[] | string[]
|
modelValue?: number[] | string[]
|
||||||
level?: 1 | 2 | 3 // 1-省 2-市 3-区
|
level?: 1 | 2 | 3 // 1-省 2-市 3-区 TODO @puhui999:这里是不是放到枚举类里?
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
clearable?: boolean
|
clearable?: boolean
|
||||||
@@ -45,7 +46,7 @@ interface Props {
|
|||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
modelValue: undefined,
|
modelValue: undefined,
|
||||||
level: 3,
|
level: 3, // TODO @puhui999:枚举类;
|
||||||
disabled: false,
|
disabled: false,
|
||||||
placeholder: '请选择省市区',
|
placeholder: '请选择省市区',
|
||||||
clearable: true,
|
clearable: true,
|
||||||
@@ -57,28 +58,23 @@ const emit = defineEmits<{
|
|||||||
(e: 'update:modelValue', value: number[] | string[] | undefined): void
|
(e: 'update:modelValue', value: number[] | string[] | undefined): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// Element Plus Cascader 的 props 配置
|
|
||||||
const cascaderProps = {
|
const cascaderProps = {
|
||||||
label: 'name',
|
label: 'name',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
children: 'children',
|
children: 'children',
|
||||||
checkStrictly: true, // 允许选择任意级别
|
checkStrictly: true, // 允许选择任意级别
|
||||||
emitPath: true // 返回完整路径
|
emitPath: true // 返回完整路径
|
||||||
}
|
} // Element Plus Cascader 的 props 配置
|
||||||
|
|
||||||
// 地区树形数据
|
const areaTree = ref<AreaVO[]>([]) // 地区树形数据
|
||||||
const areaTree = ref<AreaVO[]>([])
|
const selectedValue = ref<number[] | undefined>() // 当前选中值
|
||||||
// 当前选中值
|
const loading = ref(false) // 加载状态
|
||||||
const selectedValue = ref<number[] | undefined>()
|
|
||||||
// 加载状态
|
|
||||||
const loading = ref(false)
|
|
||||||
|
|
||||||
// 加载地区树形数据
|
/** 加载地区树形数据 */
|
||||||
async function loadAreaTree(): Promise<void> {
|
async function loadAreaTree(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const data = await getAreaTree()
|
const data = await getAreaTree()
|
||||||
|
|
||||||
// 根据 level 限制层级
|
// 根据 level 限制层级
|
||||||
areaTree.value = filterTreeByLevel(data || [], props.level)
|
areaTree.value = filterTreeByLevel(data || [], props.level)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -89,13 +85,13 @@ async function loadAreaTree(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据层级过滤树形数据
|
/** 根据层级过滤树形数据 */
|
||||||
function filterTreeByLevel(tree: AreaVO[], maxLevel: number): AreaVO[] {
|
function filterTreeByLevel(tree: AreaVO[], maxLevel: number): AreaVO[] {
|
||||||
if (maxLevel <= 0) return []
|
if (maxLevel <= 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
return tree.map((node) => {
|
return tree.map((node) => {
|
||||||
const newNode = { ...node }
|
const newNode = { ...node }
|
||||||
|
|
||||||
// 如果当前是最后一层,移除 children
|
// 如果当前是最后一层,移除 children
|
||||||
if (maxLevel === 1) {
|
if (maxLevel === 1) {
|
||||||
delete newNode.children
|
delete newNode.children
|
||||||
@@ -103,25 +99,22 @@ function filterTreeByLevel(tree: AreaVO[], maxLevel: number): AreaVO[] {
|
|||||||
// 递归处理子节点
|
// 递归处理子节点
|
||||||
newNode.children = filterTreeByLevel(node.children, maxLevel - 1)
|
newNode.children = filterTreeByLevel(node.children, maxLevel - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newNode
|
return newNode
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理选中值变化
|
/** 处理选中值变化 */
|
||||||
function handleChange(value: number[] | undefined): void {
|
function handleChange(value: number[] | undefined): void {
|
||||||
if (value === undefined || value === null) {
|
if (value === undefined || value === null) {
|
||||||
emit('update:modelValue', undefined)
|
emit('update:modelValue', undefined)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('update:modelValue', value)
|
emit('update:modelValue', value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 同步 modelValue 到内部选中值
|
/** 同步 modelValue 到内部选中值 */
|
||||||
function syncSelectedValue(): void {
|
function syncSelectedValue(): void {
|
||||||
const newValue = props.modelValue
|
const newValue = props.modelValue
|
||||||
|
|
||||||
if (newValue === undefined || newValue === null) {
|
if (newValue === undefined || newValue === null) {
|
||||||
selectedValue.value = undefined
|
selectedValue.value = undefined
|
||||||
return
|
return
|
||||||
@@ -135,10 +128,10 @@ function syncSelectedValue(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听 modelValue 变化
|
/** 监听 modelValue 变化 */
|
||||||
watch(() => props.modelValue, syncSelectedValue, { immediate: true })
|
watch(() => props.modelValue, syncSelectedValue, { immediate: true })
|
||||||
|
|
||||||
// 组件挂载时加载数据
|
/** 组件挂载时加载数据 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await loadAreaTree()
|
await loadAreaTree()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
// TODO @AI:多余的变量,需要删除;
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
defineOptions({ name: 'IframeComponent' })
|
defineOptions({ name: 'IframeComponent' })
|
||||||
@@ -50,19 +51,18 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
sandbox: ''
|
sandbox: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO @puhui999:这里貌似暂时没用到?
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: string): void
|
(e: 'update:modelValue', value: string): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// 显示的 URL(优先使用 url prop,其次使用 modelValue)
|
const displayUrl = computed(() => props.url || props.modelValue || '') // 显示的 URL(优先使用 url prop,其次使用 modelValue)
|
||||||
const displayUrl = computed(() => props.url || props.modelValue || '')
|
|
||||||
|
|
||||||
// 是否显示预览
|
|
||||||
const showPreview = computed(() => {
|
const showPreview = computed(() => {
|
||||||
return displayUrl.value && isValidUrl(displayUrl.value)
|
return displayUrl.value && isValidUrl(displayUrl.value)
|
||||||
})
|
}) // 是否显示预览
|
||||||
|
|
||||||
// URL 验证
|
// TODO @puhui999:看看全局是不是有可复用的方法;
|
||||||
|
/** URL 验证 */
|
||||||
function isValidUrl(url: string): boolean {
|
function isValidUrl(url: string): boolean {
|
||||||
if (!url || url.trim() === '') return false
|
if (!url || url.trim() === '') return false
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils
|
|||||||
export const useAreaSelectRule = () => {
|
export const useAreaSelectRule = () => {
|
||||||
const label = '省市区选择器'
|
const label = '省市区选择器'
|
||||||
const name = 'AreaSelect'
|
const name = 'AreaSelect'
|
||||||
|
|
||||||
return {
|
return {
|
||||||
icon: 'icon-location',
|
icon: 'icon-location',
|
||||||
label,
|
label,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { localeProps, makeRequiredRule } from '@/components/FormCreate/src/utils
|
|||||||
export const useIframeRule = () => {
|
export const useIframeRule = () => {
|
||||||
const label = '网页 iframe'
|
const label = '网页 iframe'
|
||||||
const name = 'IframeComponent'
|
const name = 'IframeComponent'
|
||||||
|
|
||||||
return {
|
return {
|
||||||
icon: 'icon-link',
|
icon: 'icon-link',
|
||||||
label,
|
label,
|
||||||
|
|||||||
Reference in New Issue
Block a user