最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3自定義動(dòng)態(tài)不同UI組件篩選框案例

 更新時(shí)間:2025年04月03日 10:27:24   作者:新茶十九  
動(dòng)態(tài)組件是一種在Vue中根據(jù)條件或用戶輸入來動(dòng)態(tài)渲染不同組件,本文主要介紹了vue3自定義動(dòng)態(tài)不同UI組件篩選框案例,具有一定的參考價(jià)值,感興趣的可以了解一下

?1. 實(shí)現(xiàn)功能

??添加條件進(jìn)行數(shù)據(jù)篩選

  • 根據(jù)篩選數(shù)據(jù)條件不同,顯示不同的UI組件:包含datetime、select、input
  • 篩選完條件可繼續(xù)添加與取消條件
  • 當(dāng)然可以在條件列表中進(jìn)行直接刪除,當(dāng)刪除完所有條件之后,回到添加條件頁面
  • 清空搜索條件直接回到添加條件頁面

?2. 效果圖

??打開篩選條件彈窗??

111.gif

????查看篩選條件不同的UI結(jié)構(gòu)效果預(yù)覽????

222.gif

??????繼續(xù)添加和取消篩選條件效果??????

3333.gif

????條件列表中直接刪除條件效果????

444.gif

??清空搜索條件效果??

555.gif

?3. 組件代碼

??1. 組件目錄結(jié)構(gòu)

image.png

?? 2. 添加條件頁面

<script setup lang="ts">
import { ref } from 'vue'
import { NavData } from './constant'
import AddedCondition from './components/added-condition/index.vue'

defineOptions({
  name: 'SearchClues',
})
const { token } = useAntdToken()

// 是否有搜索添加,判斷顯示篩選區(qū)域
const isNav = ref(true)

// 添加條件彈窗
const AddedConditionRef = ref()
function handleClick(i: number) {
  if (i === 0) {
    AddedConditionRef.value.handleOpen()
    return
  }
  if (i === 1) {
    console.log(1)
    return
  }
  if (i === 2) {
    console.log(2)
  }
}

// 篩選條件判斷
function handleIsPanel(v: boolean) {
  isNav.value = !v
  if (isNav.value && !v) {
    isSearch.value = false
  }
}

function handleSearch(list: any) {
  console.log(list, 'handleSearch')
  isSearch.value = true
}

// 是否搜索
const isSearch = ref<boolean>(false)
</script>

<template>
  <div>
    <a-card>
      <div v-if="isNav" class="flex">
        <div v-for="(nav, i) in NavData" :key="i" class="flex-center cursor-pointer m-ie-8" @click="handleClick(nav.i)">
          <div class="flex-center p-2 b-rd-10 m-ie-2" :style="{ 'background-color': token?.colorPrimary }">
            <img :src="nav.url" width="24" height="24" alt="">
          </div>
          <span>{{ nav.title }}</span>
        </div>
      </div>
      <AddedCondition ref="AddedConditionRef" @handle-is-panel="handleIsPanel" @handle-search="handleSearch" />
    </a-card>
    <a-card class="m-t-5">
      <div>
        <h2>三步完成線索查找</h2>
        <div>待完成</div>
      </div>
    </a-card>
  </div>
</template>

<style lang="less" scoped></style>

??3. 選擇條件-條件列表added-condition/index.vue ??

<script setup lang="ts">
import { createVNode, ref } from 'vue'
import { DownOutlined, ExclamationCircleOutlined, MinusCircleOutlined, PlusOutlined, UpOutlined } from '@ant-design/icons-vue'
import { Modal, message } from 'ant-design-vue'
import { JudgementCondition } from '../../constant'
import SelectCondition from './select-condition.vue'
import type { Condition } from '@/api/interface/getting-clues'

defineOptions({
  name: 'AddedCondition',
})

const emit = defineEmits(['handleIsPanel', 'handleSearch', 'handleSave', 'handleClear'])
const selectionConditionRef = ref()
function handleOpen() {
  selectionConditionRef.value.handleOpen()
}

// 是否有搜索添加,判斷顯示篩選區(qū)域
const isPanel = ref(false)

function handleOk(list: Condition.ConditionItem[]) {
  conditionsList.value = list
  isPanel.value = true
  emit('handleIsPanel', isPanel.value)
}

/**
 * @constant searchGeneralType 搜索條件總類型
 * @constant conditionsList 搜索條件列表
 */
const searchGeneralType = ref('0')
const conditionsList = ref<Condition.ConditionItem[]>([])

// 獲取下拉框數(shù)據(jù)
function getDefaultOptions(condition: Condition.ConditionItem) {
  if (condition.type === 'SelectOption') {
    return condition.keys?.map(item => (
      JudgementCondition[item.key][item.value] || JudgementCondition.renderData.ifData
    ))[0]
  }
  else {
    return JudgementCondition.type.operateState
  }
}

// 獲取多選條件下拉框數(shù)據(jù)
function getKeysOptions() {
  return JudgementCondition.default.default
}

function handleDelete(index: number) {
  conditionsList.value.splice(index, 1)
}

watch(() => conditionsList, (n) => {
  if (n.value.length === 0) {
    isPanel.value = false
    emit('handleIsPanel', isPanel.value)
  }
}, { deep: true })

// 篩選
function handleSearch() {
  emit('handleSearch', conditionsList.value)
}
// 保存
const loading = ref<boolean>(false)
function handleSave() {
  Modal.confirm({
    title: '確認(rèn)',
    icon: createVNode(ExclamationCircleOutlined),
    content: '確定要保存此篩選條件嗎?',
    onOk() {
      loading.value = true
      emit('handleSave', conditionsList.value)
      setTimeout(() => {
        message.success('保存成功')
        loading.value = false
      }, 1000)
    },
    onCancel() {
      console.log('Cancel')
    },
  })
}
// 清空
function handleClear() {
  Modal.confirm({
    title: '確認(rèn)',
    icon: createVNode(ExclamationCircleOutlined),
    content: '確定要清空篩選條件嗎?',
    onOk() {
      conditionsList.value = []
      emit('handleClear', conditionsList.value)
      selectionConditionRef.value.reset()
    },
    onCancel() {
      console.log('Cancel')
    },
  })
}

// 展開折疊
const isExpanded = ref<boolean>(true)
function handleCollapse() {
  isExpanded.value = !isExpanded.value
}

defineExpose({
  handleOpen,
  handleSearch,
  handleSave,
  handleClear,
})
</script>

<template>
  <div>
    <div v-if="isPanel">
      <div class="m-be-5">
        <span class="w-16 inline-block">滿足下列</span>
        <a-select v-model:value="searchGeneralType" class="m-inline-2.5" style="width: 120px">
          <a-select-option value="0">
            所有
          </a-select-option>
          <a-select-option value="1">
            任一
          </a-select-option>
        </a-select>
        條件:
      </div>
      <div class="expandable-content" :class="{ expanded: isExpanded }">
        <div
          v-for="(condition, index) in conditionsList" :key="condition.value"
          class="flex p-be-5 p-is-18.5 condition-box"
        >
          <a-input v-model:value="condition.label" disabled class="w-50" />
          <template v-if="condition.type === 'DatePicker'">
            <a-range-picker v-model:value="condition.keysDate" class="m-inline-2.5" />
          </template>
          <template v-else-if="condition.type === 'NumberRange'">
            <a-input-number id="inputNumber" v-model:value="condition.keys[0].isSys" class="m-inline-2.5" />
          </template>
          <template v-else-if="condition.type === 'SelectOption'">
            <div v-for="(keyItem, i) in condition.keys" :key="keyItem.key + i">
              <a-select v-model:value="keyItem.isSys" class="m-inline-2.5" style="width: 180px">
                <a-select-option v-for="item in getDefaultOptions(condition)" :key="item.value" :value="item.value">
                  {{ item.label }}
                </a-select-option>
              </a-select>
            </div>
          </template>
          <template v-else>
            <a-select v-model:value="condition.viewfilter" class="m-inline-2.5" style="width: 180px">
              <a-select-option v-for="item in getDefaultOptions(condition)" :key="item.value" :value="item.value">
                {{ item.label }}
              </a-select-option>
            </a-select>
            <!-- TODO 這里是一個(gè)輸入框,點(diǎn)擊出彈窗選數(shù)據(jù) -->
            <a-select v-model:value="condition.keysMul" class="m-inline-2.5" style="width: 180px" mode="multiple">
              <a-select-option v-for="item in getKeysOptions()" :key="item.value" :value="item.value">
                {{ item.label }}
              </a-select-option>
            </a-select>
          </template>
          <MinusCircleOutlined style="color: #888" @click="handleDelete(index)" />
        </div>
      </div>
      <a-button @click="selectionConditionRef.handleOpen">
        <template #icon>
          <PlusOutlined />
        </template>
        添加條件
      </a-button>
      <div class="flex justify-between m-t-5">
        <div>
          <a-button class="m-ie-6" type="primary" @click="handleSearch">
            篩選
          </a-button>
          <a-button :loading="loading" @click="handleSave">
            保存篩選條件
          </a-button>
        </div>
        <a-button class="float-right" type="link" @click="handleClear">
          清空
        </a-button>
      </div>
      <a-divider>
        <a-button type="link" @click="handleCollapse">
          {{ isExpanded ? '收起' : '展開' }}
          <component :is="isExpanded ? UpOutlined : DownOutlined" />
        </a-button>
      </a-divider>
    </div>
    <SelectCondition ref="selectionConditionRef" @handle-ok="handleOk" />
  </div>
</template>

<style lang="less" scoped>
.condition-box {
  position: relative;

  &::before {
    content: " ";
    position: absolute;
    left: 0;
    top: -4px;
    height: 100%;
    width: 55px;
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADcAAAAoAQMAAABglfBLAAAABlBMVEXM09t2YyHaAAAAAXRSTlMAQObYZgAAABNJREFUGNNjYGBgcGCAgFGadBoAQZoKAavfri4AAAAASUVORK5CYII=) repeat;
  }

  &:last-child::before {
    top: -4px;
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADcAAAAoCAYAAABaW2IIAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACfSURBVHgB7dOxDcJQDIThs0lBQcEIRBQoBRIbEiYBNoEJXoFQaCBikBfDCFEUOXJ0X29Zf3GAg+frY5iAYsYYFxXjomJcVIyLinFRMS4qxkXFuKgYN4aU0hrOXOIEuBXL1QHOXOKy5ZPK4pyadgNHAieP5l2ryPH/8tJZ9+1zU6i21a68YiC3ze2rba0mpVm+970xg/tOiYiIiIiIaHo/tyUf6I0zVSMAAAAASUVORK5CYII=) top no-repeat;
  }
}

.expandable-content {
  max-height: 0;
  overflow: hidden;
  transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  opacity: 0;
  transform: translateY(-20px);
  margin-top: 0;
  visibility: hidden;

  &.expanded {
    max-height: 1000px;
    opacity: 1;
    transform: translateY(0);
    margin-top: 16px;
    visibility: visible;
  }
}
</style>

??4. 選擇條件-選擇條件彈窗組件added-condition/select-condition.vue ??

<script setup lang="ts">
import { reactive, ref } from 'vue'
import { hexToRgba } from '~@/utils/hexToRgba'
import { getConditionList } from '@/api/getting-clues/search-clues.ts'
import type { Condition } from '@/api/interface/getting-clues'

defineOptions({
  name: 'SelectCondition',
})
const emit = defineEmits(['handleOk'])

const { token } = useAntdToken()

const message = useMessage()

const open = ref<boolean>(false)
function handleOpen() {
  open.value = true
}
function handleCancel() {
  open.value = false
}
function handleOk() {
  if (state.selectedItemLabels.length === 0) {
    message.error('請(qǐng)選擇要添加的條件')
  }
  else {
    emit('handleOk', state.selectedItemLabels)
    open.value = false
  }
}

// search
const searchValue = ref<string>('')
function onSearch(searchValue: string) {
  console.log('use value', searchValue)
  // console.log('or use this.value', searchValue.value);
}

// 條件列表
const conditionList = ref<Condition.ConditionItem[]>([])

getConditionList().then((res) => {
  if (res.success) {
    conditionList.value = res.data
  }
})

// 主條件分類鼠標(biāo)移入和選中效果
/**
 * @constant hoveredMainIndices 鼠標(biāo)移入的索引
 * @constant selectedMainIndices 選中的索引
 * @constant currentMainIndex 當(dāng)前選中主條件index,用于獲取子條件列表
 * @constant hoveredItemIndices 選中的子條件索引
 * @constant selectedItemIndices 當(dāng)前選中的子條件
 * @constant selectedItemLabels 選擇的條件
 */

interface State {
  hoveredMainIndices: Set<number>
  selectedMainIndices: Set<number>
  currentMainIndex: number
  hoveredItemIndices: Set<number>
  selectedItemIndices: Set<number>
  selectedItemLabels: Condition.ConditionItem[]
}

const state = reactive<State>({
  hoveredMainIndices: new Set(),
  selectedMainIndices: new Set([0]),
  currentMainIndex: 0,
  hoveredItemIndices: new Set(),
  selectedItemIndices: new Set(),
  selectedItemLabels: [],
})

function handleMainClick(index: number) {
  if (state.currentMainIndex === index) {
    return
  }
  state.selectedMainIndices.clear()
  state.selectedMainIndices.add(index)
  state.currentMainIndex = index
}
function isMainSelected(index: number) {
  return state.selectedMainIndices.has(index)
}

function handleMainHovered(index: number, isHovered: boolean) {
  if (isHovered) {
    state.hoveredMainIndices.add(index)
  }
  else {
    state.hoveredMainIndices.delete(index)
  }
}
function isMainHovered(index: number) {
  return state.hoveredMainIndices.has(index)
}

function activeMainStyle(index: number) {
  if (isMainSelected(index)) {
    return {
      color: token.value?.colorPrimary,
      backgroundColor: hexToRgba(token.value?.colorPrimary, 0.05),
      borderRight: `2px solid ${token.value?.colorPrimary}`,
    }
  }
  else {
    if (isMainHovered(index)) {
      return {
        backgroundColor: 'rgba(0, 0, 0, 0.06)',
      }
    }
  }
}

// 子條件列表
const conditionChildrenList = computed(() => {
  const c = conditionList.value.find((_, index) => state.currentMainIndex === index)
  return c?.children || []
})

function handleItemClick(item: Condition.ConditionItem) {
  const a = state.selectedItemLabels.find(i => i.value === item.value)
  if (!a) {
    if (state.selectedItemLabels.length === 10) {
      return message.error('一次最多選擇10項(xiàng)')
    }
    state.selectedItemLabels.push(item)
  }
  else {
    state.selectedItemLabels = state.selectedItemLabels.filter(i => i.value !== item.value)
  }
}
function isItemSelected(item: Condition.ConditionItem) {
  return (state.selectedItemLabels.findIndex(i => i.value === item.value) !== -1)
}

function handleItemHovered(index: number, isHovered: boolean) {
  if (isHovered) {
    state.hoveredItemIndices.add(index)
  }
  else {
    state.hoveredItemIndices.delete(index)
  }
}
function isItemHovered(index: number) {
  return state.hoveredItemIndices.has(index)
}

function activeItemStyle(index: number, item: Condition.ConditionItem) {
  if (isItemSelected(item)) {
    return {
      color: '#ffffff',
      backgroundColor: token.value?.colorPrimary,
    }
  }
  else {
    if (isItemHovered(index)) {
      return {
        color: token.value?.colorPrimary,
        backgroundColor: hexToRgba(token.value?.colorPrimary, 0.05),
      }
    }
  }
}

function reset() {
  const initState: State = {
    hoveredMainIndices: new Set(),
    selectedMainIndices: new Set([0]),
    currentMainIndex: 0,
    hoveredItemIndices: new Set(),
    selectedItemIndices: new Set(),
    selectedItemLabels: [],
  }
  Object.assign(state, initState)
}

defineExpose({
  handleOpen,
  handleCancel,
  reset,
})
</script>

<template>
  <a-modal v-model:open="open" width="50vw" title="添加條件" @ok="handleOk">
    <div>
      <!-- search -->
      <div>
        <a-input-search
          v-model:value="searchValue" class="w-full" placeholder="搜索條件名稱" enter-button="搜索" size="large"
          @search="onSearch"
        />
      </div>
      <!-- main wrapper -->
      <div class="mt-5 flex">
        <div class="w-1/5 h-[50vh] overflow-y-scroll scrollbar">
          <div
            v-for="(item, index) in conditionList" :key="index" class="p-2 m-r-1 lh-6 cursor-pointer"
            :style="activeMainStyle(index)" @click="handleMainClick(index)" @mouseover="handleMainHovered(index, true)"
            @mouseleave="handleMainHovered(index, false)"
          >
            {{ item.label }}
          </div>
        </div>
        <div class="flex-1 p-l-8 h-[50vh] overflow-y-auto scrollbar">
          <span
            v-for="(item, index) in conditionChildrenList" :key="index"
            class="inline-block m-2 p-inline-6 p-block-2  b-1 b-solid b-color-#e5e5e5 b-rd-2 cursor-pointer"
            :style="activeItemStyle(index, item)" @click="handleItemClick(item)"
            @mouseover="handleItemHovered(index, true)" @mouseleave="handleItemHovered(index, false)"
          >
            {{ item.label }}
          </span>
        </div>
      </div>
    </div>
    <template #footer>
      <div class="flex-between b-t-1 b-t-solid b-color-#e5e5e5 p-2">
        <div>
          已選擇<span class="p-inline-1" :style="{ color: token?.colorPrimary }">{{ state.selectedItemLabels.length
          }}</span>個(gè)條件(一次最多10個(gè))
        </div>
        <div>
          <a-button key="back" @click="handleCancel">
            取消
          </a-button>
          <a-button key="submit" type="primary" @click="handleOk">
            確定
          </a-button>
        </div>
      </div>
    </template>
  </a-modal>
</template>

<style lang="less" scoped></style>

??5. 定義常量數(shù)據(jù)文件constant/index.ts ??

export const NavData = [
  {
    i: 0,
    title: '添加條件',
    url: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzMzOTk3MzM3MjgwIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQ2NTM1IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPjxwYXRoIGQ9Ik01MTIgOTcuNTIzODFjMjI4LjkxMjc2MiAwIDQxNC40NzYxOSAxODUuNTYzNDI5IDQxNC40NzYxOSA0MTQuNDc2MTlzLTE4NS41NjM0MjkgNDE0LjQ3NjE5LTQxNC40NzYxOSA0MTQuNDc2MTlTOTcuNTIzODEgNzQwLjkxMjc2MiA5Ny41MjM4MSA1MTIgMjgzLjA4NzIzOCA5Ny41MjM4MSA1MTIgOTcuNTIzODF6IG0zNi41NzE0MjkgMTk1LjA0NzYxOWgtNzMuMTQyODU4djE4Mi44MzI3NjFMMjkyLjU3MTQyOSA0NzUuNDI4NTcxdjczLjE0Mjg1OGwxODIuODU3MTQyLTAuMDI0MzgxVjczMS40Mjg1NzFoNzMuMTQyODU4di0xODIuODU3MTQySDczMS40Mjg1NzF2LTczLjE0Mjg1OGgtMTgyLjg1NzE0MlYyOTIuNTcxNDI5eiIgcC1pZD0iNDY1MzYiIGZpbGw9IiNmZmZmZmYiPjwvcGF0aD48L3N2Zz4=',
  },
  {
    i: 1,
    title: '熱門推薦',
    url: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzMzOTk2Mjc3MzUyIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQzNjIwIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPjxwYXRoIGQ9Ik03NzAuMDE2IDMzMi43NjhsLTc3LjgyNCA3Ni44czAtMzA3LjItMjU5LjYxNi00MDkuNTY4YzAgMC0yNS45MiAyODEuNi0xNTUuNzQ0IDM4My45MzYtMTI5Ljc5MiAxMDIuNDY0LTM4OS40NCA0MDkuNTY4IDEyOS42OTYgNjM5Ljk2OCAwIDAtMjU5LjYxNi0yODEuNiA3Ny44MjQtNDg2LjMwNCAwIDAtMjUuOTIgMTAyLjMzNiAxMDMuODcyIDIwNC44IDEyOS44MjQgMTAyLjM2OCAwIDI4MS42IDAgMjgxLjZzNjIzLjAwOC0xNTMuNjMyIDE4MS43OTItNjkxLjIzMnoiIGZpbGw9IiNmZmZmZmYiIHAtaWQ9IjQzNjIxIj48L3BhdGg+PC9zdmc+',
  },
  {
    i: 2,
    title: '已保存的篩選條件',
    url: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNzM0MDU5ODUyOTg5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjU0MTQiIGlkPSJteF9uXzE3MzQwNTk4NTI5OTAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTQyNi42NjY2NjcgNzI1LjMzMzMzM2gxNzAuNjY2NjY2djE3MC42NjY2NjdoLTE3MC42NjY2NjZ6IiBwLWlkPSI1NDE1IiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PHBhdGggZD0iTTg1OC40NTMzMzMgMzcxLjYyNjY2N2wtMjA2LjA4LTIwNi4wOEExMjggMTI4IDAgMCAwIDU2MS45MiAxMjhINDI2LjY2NjY2N3YyNTZoMjEzLjMzMzMzM2E0Mi42NjY2NjcgNDIuNjY2NjY3IDAgMCAxIDAgODUuMzMzMzMzSDM4NGE0Mi42NjY2NjcgNDIuNjY2NjY3IDAgMCAxLTQyLjY2NjY2Ny00Mi42NjY2NjZWMTI4SDI1NmExMjggMTI4IDAgMCAwLTEyOCAxMjh2NTEyYTEyOCAxMjggMCAwIDAgMTI4IDEyOGg4NS4zMzMzMzN2LTE3MC42NjY2NjdhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzQtODUuMzMzMzMzaDE3MC42NjY2NjZhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzQgODUuMzMzMzMzdjE3MC42NjY2NjdoODUuMzMzMzMzYTEyOCAxMjggMCAwIDAgMTI4LTEyOHYtMzA1LjkyYTEyOCAxMjggMCAwIDAtMzcuNTQ2NjY3LTkwLjQ1MzMzM3oiIHAtaWQ9IjU0MTYiIGZpbGw9IiNmZmZmZmYiPjwvcGF0aD48L3N2Zz4=',
  },
]

export const JudgementCondition: { [key: string]: any } = {
  type: {
    operateState: [
      {
        value: 'text',
        label: '等于任意一個(gè)',
      },
      {
        value: 'select-eq',
        label: '等于',
      },
      {
        value: 'select-in',
        label: '包含',
      },
      {
        value: 'select-in-one',
        label: '包含任意一個(gè)',
      },
      {
        value: 'select-not',
        label: '不包含',
      },
    ],
  },
  renderData: {
    existData: [
      {
        value: 0,
        label: '無',
      },
      {
        value: 1,
        label: '有',
      },
    ],
    ifData: [
      {
        value: 0,
        label: '否',
      },
      {
        value: 1,
        label: '是',
      },
    ],
  },
  tag: {
    inTag: [
      {
        value: 0,
        label: '機(jī)械',
      },
      {
        value: 1,
        label: '器械',
      },
      {
        value: 2,
        label: '設(shè)備',
      },
      {
        value: 1,
        label: '重工',
      },
    ],
  },
  // 所有的類別匹配不上走默認(rèn)
  default: {
    default: [
      {
        value: 0,
        label: '存續(xù)',
      },
      {
        value: 1,
        label: '在業(yè)',
      },
    ],
  },
}

??6. 類別json數(shù)據(jù)api/index.ts ??

// api 模擬接口
export function getConditionList(): Promise<ResData<Condition.ConditionItem[]>> {
  return new Promise((resolve) => {
    resolve(conditionList as unknown as ResData<Condition.ConditionItem[]>)
  })
}

數(shù)據(jù)json:

{
  "errcode": 200,
  "errmsg": "操作成功",
  "data": [
    {
      "value": "extraHot",
      "label": "常用",
      "children": [
        {
          "value": "businessLocation",
          "label": "企業(yè)所在地",
          "children": null,
          "type": "MultiSelect",
          "keys": [
            {
              "key": "type",
              "value": "area",
              "isSys": 0
            },
            {
              "key": "tag",
              "value": "inTag",
              "isSys": 0
            }
          ],
          "checked": true,
          "alisKey": false,
          "viewfilter": "text",
          "tooltip": "",
          "certificateFlag": true,
          "normal": true,
          "intellectualPropertyFlag": true,
          "groupName": ""
        },
        {
          "value": "mobile",
          "label": "有無手機(jī)",
          "children": null,
          "type": "SelectOption",
          "keys": [
            {
              "key": "renderData",
              "value": "existData",
              "isSys": 1
            }
          ],
          "checked": true,
          "alisKey": false,
          "viewfilter": "bool",
          "tooltip": "",
          "certificateFlag": true,
          "normal": true,
          "intellectualPropertyFlag": true,
          "groupName": ""
        },
        {
          "value": "operateState",
          "label": "經(jīng)營(yíng)狀態(tài)",
          "children": null,
          "type": "MultiSelect",
          "keys": [
            {
              "key": "type",
              "value": "operateState",
              "isSys": 0
            }
          ],
          "checked": true,
          "alisKey": false,
          "viewfilter": "select-eq",
          "tooltip": "",
          "certificateFlag": true,
          "normal": true,
          "intellectualPropertyFlag": true,
          "groupName": ""
        },
        {
          "value": "companyName",
          "label": "企業(yè)名稱",
          "children": null,
          "type": "TextTags",
          "keys": [
            {
              "key": "type",
              "value": "companyName",
              "isSys": 0
            },
            {
              "key": "tag",
              "value": "inTag",
              "isSys": 0
            }
          ],
          "checked": true,
          "alisKey": true,
          "viewfilter": "text",
          "tooltip": "",
          "certificateFlag": true,
          "normal": true,
          "intellectualPropertyFlag": true,
          "groupName": ""
        }
      ],
      "type": "",
      "keys": [],
      "checked": true,
      "alisKey": false,
      "viewfilter": "",
      "tooltip": "",
      "certificateFlag": true,
      "normal": true,
      "intellectualPropertyFlag": true,
      "groupName": ""
    },
    {
      "value": "industryInfo",
      "label": "企業(yè)基本信息",
      "children": [
        {
          "value": "foundTime",
          "label": "成立日期",
          "children": null,
          "type": "DatePicker",
          "keys": [],
          "checked": true,
          "alisKey": false,
          "viewfilter": "timeRange",
          "tooltip": "",
          "certificateFlag": true,
          "normal": true,
          "intellectualPropertyFlag": true,
          "groupName": "基本信息"
        }
      ],
      "type": "",
      "keys": [],
      "checked": true,
      "alisKey": false,
      "viewfilter": "",
      "tooltip": "",
      "certificateFlag": true,
      "normal": true,
      "intellectualPropertyFlag": true,
      "groupName": ""
    }
  ],
  "success": true
}

??7. 數(shù)據(jù)接口定義interface/index.ts ??

import type { Dayjs } from 'dayjs'

export namespace Condition {
  export interface ChildKeys {
    key: string
    value: string
    isSys: number
  }

  export interface ConditionItem {
    label: string
    value: string
    type: string
    keys: ChildKeys[]
    keysDate?: [Dayjs, Dayjs]
    keysMul?: any[]
    children: ConditionItem[]
    checked: boolean
    viewfilter: string
    tooltip: string
    [key: string]: any
  }
}

?? 4. 封裝實(shí)例缺點(diǎn)??

added-condition.vue文件內(nèi)動(dòng)態(tài)渲染UI組件代碼

在這里插入圖片描述

UI的結(jié)構(gòu)是不可預(yù)知的,所以既然叫動(dòng)態(tài),那么就需要修改以為動(dòng)態(tài)組件。。。

到此這篇關(guān)于vue3自定義動(dòng)態(tài)不同UI組件篩選框案例的文章就介紹到這了,更多相關(guān)vue3 動(dòng)態(tài)組件篩選框內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue中調(diào)用HTTP請(qǐng)求的詳細(xì)步驟

    vue中調(diào)用HTTP請(qǐng)求的詳細(xì)步驟

    這篇文章主要介紹了vue中調(diào)用HTTP請(qǐng)求的詳細(xì)步驟,文中通過代碼示例給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定幫助,需要的朋友可以參考下
    2024-07-07
  • vue-cli 默認(rèn)路由再子路由選中下的選中狀態(tài)問題及解決代碼

    vue-cli 默認(rèn)路由再子路由選中下的選中狀態(tài)問題及解決代碼

    這篇文章主要介紹了vue-cli 默認(rèn)路由再子路由選中下的選中狀態(tài)問題及解決代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • 在vue中使用SockJS實(shí)現(xiàn)webSocket通信的過程

    在vue中使用SockJS實(shí)現(xiàn)webSocket通信的過程

    最近接到一個(gè)業(yè)務(wù)需求,需要做一個(gè)聊天信息的實(shí)時(shí)展示的界面,下面小編把實(shí)現(xiàn)過程記錄下來,對(duì)vue中使用SockJS實(shí)現(xiàn)webSocket通信的相關(guān)知識(shí)感興趣的朋友一起看看吧
    2018-08-08
  • vue2如何使用vue-i18n搭建多語言切換環(huán)境

    vue2如何使用vue-i18n搭建多語言切換環(huán)境

    這篇文章主要介紹了vue2-使用vue-i18n搭建多語言切換環(huán)境的相關(guān)知識(shí),在data(){}中獲取的變量存在更新this.$i18n.locale的值時(shí)無法自動(dòng)切換的問題,需要刷新頁面才能切換語言,感興趣的朋友一起看看吧
    2023-12-12
  • vue router返回到指定的路由的場(chǎng)景分析

    vue router返回到指定的路由的場(chǎng)景分析

    這篇文章主要介紹了vue router返回到指定的路由的場(chǎng)景分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • vue路由攔截及頁面跳轉(zhuǎn)的設(shè)置方法

    vue路由攔截及頁面跳轉(zhuǎn)的設(shè)置方法

    這篇文章主要介紹了vue路由攔截及頁面跳轉(zhuǎn)的設(shè)置方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-05-05
  • Vue首頁界面加載優(yōu)化實(shí)現(xiàn)方法詳解

    Vue首頁界面加載優(yōu)化實(shí)現(xiàn)方法詳解

    如果你也遇到在 vue 應(yīng)用中,首頁加載資源過多,導(dǎo)致加載緩慢的問題,下面的方法也許能幫到你,主要的處理思想是:讓首頁多余的資源能在需要它的時(shí)候再加載
    2022-09-09
  • Vue input輸入框回車以后自動(dòng)刷新頁面(直播程序)

    Vue input輸入框回車以后自動(dòng)刷新頁面(直播程序)

    這篇文章主要介紹了直播程序,Vue input輸入框回車以后自動(dòng)刷新頁面,適用場(chǎng)景是在輸入框輸入字符并按下回車鍵搜索時(shí),刷新頁面,需要的朋友參考下實(shí)現(xiàn)代碼
    2023-01-01
  • 使用axios發(fā)送post請(qǐng)求,將JSON數(shù)據(jù)改為form類型的示例

    使用axios發(fā)送post請(qǐng)求,將JSON數(shù)據(jù)改為form類型的示例

    今天小編就為大家分享一篇使用axios發(fā)送post請(qǐng)求,將JSON數(shù)據(jù)改為form類型的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • 深入理解vue.js中的v-if和v-show

    深入理解vue.js中的v-if和v-show

    這篇文章主要給大家深入的介紹了關(guān)于vue.js中v-if和v-show的相關(guān)資料,文中詳細(xì)介紹兩者的共同點(diǎn)和區(qū)別,通過圖文介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-06-06

最新評(píng)論

资兴市| 长葛市| 平罗县| 黄梅县| 康平县| 定结县| 绥芬河市| 嘉义县| 溆浦县| 唐山市| 芷江| 和硕县| 额敏县| 新乡市| 华亭县| 巴楚县| 夏邑县| 北票市| 于都县| 阳新县| 前郭尔| 林西县| 水城县| 化隆| 卓尼县| 格尔木市| 新巴尔虎左旗| 甘洛县| 吉安县| 盘锦市| 独山县| 浦城县| 武川县| 甘肃省| 高州市| 偏关县| 孝昌县| 积石山| 古田县| 开封县| 简阳市|