当前位置:首页 > VUE

vue实现多级选择

2026-02-19 04:10:19VUE

Vue 实现多级选择的方法

使用递归组件实现多级选择

递归组件适合处理嵌套层级不确定的数据结构。定义一个组件,该组件能够调用自身来渲染子级选项。

<template>
  <div>
    <select v-model="selectedValue" @change="handleChange">
      <option v-for="item in options" :value="item.value" :key="item.value">
        {{ item.label }}
      </option>
    </select>
    <recursive-select 
      v-if="selectedItem && selectedItem.children" 
      :options="selectedItem.children"
      @selected="handleChildSelected"
    />
  </div>
</template>

<script>
export default {
  name: 'RecursiveSelect',
  props: ['options'],
  data() {
    return {
      selectedValue: null
    }
  },
  computed: {
    selectedItem() {
      return this.options.find(item => item.value === this.selectedValue)
    }
  },
  methods: {
    handleChange() {
      this.$emit('selected', this.selectedItem)
    },
    handleChildSelected(item) {
      this.$emit('selected', item)
    }
  }
}
</script>

使用第三方组件库

Element UI、Ant Design Vue 等流行 UI 库提供了现成的级联选择器组件。

vue实现多级选择

Element UI 示例:

<template>
  <el-cascader
    v-model="selectedOptions"
    :options="options"
    @change="handleChange"
  />
</template>

<script>
export default {
  data() {
    return {
      selectedOptions: [],
      options: [{
        value: 'province1',
        label: '省份1',
        children: [{
          value: 'city1',
          label: '城市1'
        }]
      }]
    }
  },
  methods: {
    handleChange(value) {
      console.log(value)
    }
  }
}
</script>

使用动态组件加载

对于性能要求较高的场景,可以动态加载下一级选项数据,而不是一次性加载所有层级。

vue实现多级选择

<template>
  <div>
    <select v-model="level1" @change="loadLevel2">
      <option v-for="item in level1Options" :value="item.id" :key="item.id">
        {{ item.name }}
      </option>
    </select>

    <select v-model="level2" @change="loadLevel3" v-if="level2Options.length">
      <option v-for="item in level2Options" :value="item.id" :key="item.id">
        {{ item.name }}
      </option>
    </select>

    <select v-model="level3" v-if="level3Options.length">
      <option v-for="item in level3Options" :value="item.id" :key="item.id">
        {{ item.name }}
      </option>
    </select>
  </div>
</template>

<script>
export default {
  data() {
    return {
      level1: null,
      level2: null,
      level3: null,
      level1Options: [],
      level2Options: [],
      level3Options: []
    }
  },
  async created() {
    this.level1Options = await this.fetchData('level1')
  },
  methods: {
    async loadLevel2() {
      this.level2Options = await this.fetchData(`level2?parent=${this.level1}`)
      this.level2 = null
      this.level3Options = []
    },
    async loadLevel3() {
      this.level3Options = await this.fetchData(`level3?parent=${this.level2}`)
      this.level3 = null
    },
    fetchData(url) {
      return axios.get(url).then(res => res.data)
    }
  }
}
</script>

使用 Vuex 管理状态

对于复杂应用,可以使用 Vuex 集中管理多级选择的状态和数据。

// store.js
export default new Vuex.Store({
  state: {
    selections: {
      level1: null,
      level2: null,
      level3: null
    },
    options: {
      level1: [],
      level2: [],
      level3: []
    }
  },
  mutations: {
    setSelection(state, { level, value }) {
      state.selections[level] = value
    },
    setOptions(state, { level, options }) {
      state.options[level] = options
    }
  },
  actions: {
    async fetchOptions({ commit }, { level, parent }) {
      const options = await axios.get(`api/${level}?parent=${parent}`)
      commit('setOptions', { level, options })
    }
  }
})

使用组合式 API (Vue 3)

Vue 3 的组合式 API 可以更灵活地组织多级选择逻辑。

<template>
  <div v-for="(level, index) in levels" :key="index">
    <select v-model="selections[index]" @change="loadNextLevel(index)">
      <option value="">请选择</option>
      <option v-for="item in level.options" :value="item.value" :key="item.value">
        {{ item.label }}
      </option>
    </select>
  </div>
</template>

<script>
import { reactive, ref } from 'vue'

export default {
  setup() {
    const levels = reactive([
      { options: [], loaded: false },
      { options: [], loaded: false },
      { options: [], loaded: false }
    ])
    const selections = ref([null, null, null])

    const loadLevel = async (index, parentId) => {
      const res = await fetch(`/api/level${index + 1}?parent=${parentId}`)
      levels[index].options = await res.json()
      levels[index].loaded = true
    }

    const loadNextLevel = (index) => {
      if (index < levels.length - 1 && selections.value[index]) {
        loadLevel(index + 1, selections.value[index])
        selections.value[index + 1] = null
      }
    }

    // 初始化加载第一级
    loadLevel(0)

    return { levels, selections, loadNextLevel }
  }
}
</script>

以上方法可根据具体需求选择使用,递归组件适合简单嵌套结构,动态加载适合大数据量场景,第三方组件库提供开箱即用的解决方案,Vuex 适合复杂状态管理,组合式 API 提供更灵活的代码组织方式。

标签: vue
分享给朋友:

相关文章

vue实现安全免登录

vue实现安全免登录

Vue 实现安全免登录的方案 免登录功能通常通过持久化认证状态(如 Token)实现,但需兼顾安全性。以下是基于 Vue 的常见实现方案: 基于 Token 的免登录 登录成功后存储 Token…

vue 实现简单登陆

vue 实现简单登陆

以下是一个使用 Vue 3 实现的简单登录功能示例,包含表单验证和基础交互逻辑: 创建 Vue 组件 <template> <div class="login-contain…

vue实现生成二维码

vue实现生成二维码

使用qrcode.vue库生成二维码 安装qrcode.vue库: npm install qrcode.vue --save 在Vue组件中使用: <template> &l…

vue 实现toast

vue 实现toast

vue 实现 toast 的方法 在 Vue 中实现 Toast 提示功能可以通过多种方式,以下是几种常见的实现方法: 使用第三方库 Vue 生态中有许多成熟的 Toast 库,例如 vue-to…

vue实现autocomplete

vue实现autocomplete

Vue 实现 Autocomplete 功能 Vue 中实现 Autocomplete(自动完成)功能可以通过自定义组件或使用现有库完成。以下是几种常见方法: 方法一:使用 Vue 原生实现 创建…

vue 实现blog

vue 实现blog

Vue 实现博客的基本步骤 使用 Vue 实现博客可以分为前端和后端两部分,前端使用 Vue.js 框架,后端可以选择 Node.js、Python 或其他服务端语言。以下是一个基于 Vue 的博客实…