vue项目实现排他功能
实现排他功能的基本思路
在Vue项目中实现排他功能,通常指确保同一时间只有一个元素或组件处于激活状态。常见场景包括单选按钮组、标签页切换、折叠面板等。
使用v-model和计算属性
通过v-model绑定一个响应式数据,结合计算属性或方法实现排他逻辑:
<template>
<div>
<button
v-for="item in items"
:key="item.id"
@click="selectItem(item.id)"
:class="{ active: selectedId === item.id }"
>
{{ item.text }}
</button>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: '选项1' },
{ id: 2, text: '选项2' },
{ id: 3, text: '选项3' }
],
selectedId: null
}
},
methods: {
selectItem(id) {
this.selectedId = id === this.selectedId ? null : id
}
}
}
</script>
使用组件通信实现
对于父子组件或兄弟组件间的排他功能,可以通过事件总线或Vuex实现状态管理:
// 父组件
<template>
<div>
<child-component
v-for="item in items"
:key="item.id"
:item="item"
:active="activeId === item.id"
@activate="setActive"
/>
</div>
</template>
<script>
export default {
data() {
return {
activeId: null
}
},
methods: {
setActive(id) {
this.activeId = id
}
}
}
</script>
// 子组件
<script>
export default {
props: ['item', 'active'],
methods: {
handleClick() {
this.$emit('activate', this.item.id)
}
}
}
</script>
使用动态组件实现标签页效果
通过动态组件和keep-alive实现标签页的排他显示:
<template>
<div>
<button
v-for="tab in tabs"
:key="tab.name"
@click="currentTab = tab.name"
:class="{ active: currentTab === tab.name }"
>
{{ tab.label }}
</button>
<keep-alive>
<component :is="currentTabComponent"></component>
</keep-alive>
</div>
</template>
<script>
export default {
data() {
return {
currentTab: 'Home',
tabs: [
{ name: 'Home', label: '首页' },
{ name: 'About', label: '关于' }
]
}
},
computed: {
currentTabComponent() {
return this.currentTab.toLowerCase()
}
}
}
</script>
使用自定义指令实现
创建自定义指令处理排他逻辑:
// 全局注册指令
Vue.directive('exclusive', {
bind(el, binding, vnode) {
el.addEventListener('click', () => {
const group = binding.arg || 'default'
const value = binding.value
// 清除同组其他元素的active状态
document.querySelectorAll(`[v-exclusive=${group}]`).forEach(item => {
item.classList.remove('active')
})
// 设置当前元素为active
el.classList.add('active')
// 触发回调
if (typeof binding.value === 'function') {
binding.value()
}
})
}
})
// 使用指令
<button v-exclusive:group1="handleClick">选项1</button>
<button v-exclusive:group1="handleClick">选项2</button>
使用第三方库实现
对于复杂场景,可以考虑使用第三方UI库如Element UI、Ant Design Vue等提供的现成组件:
// 使用Element UI的Radio组件
<template>
<el-radio-group v-model="radio">
<el-radio :label="1">选项1</el-radio>
<el-radio :label="2">选项2</el-radio>
</el-radio-group>
</template>
<script>
export default {
data() {
return {
radio: 1
}
}
}
</script>
以上方法根据具体场景选择,简单交互可使用数据驱动方式,复杂场景可考虑自定义指令或组件化方案。







