Vue 3.x版的单选CheckBox组件

Vue 3引入了Composition API,提供了一种新的方式来组织和重用逻辑。我们将使用Composition API来实现这个功能。

方式一: SFC

第一步:创建基础的CheckBox组件

首先,我们创建一个简单的CheckBox组件,它接受modelValuelabel作为props,并且能够触发一个更新事件来改变其选中状态。

vue 复制代码
<template>
  <div>
    <input type="checkbox" :checked="modelValue" @change="onChange" />
    <label>{{ label }}</label>
  </div>
</template>

<script>
export default {
  props: {
    modelValue: Boolean,
    label: String,
  },
  emits: ['update:modelValue'],
  methods: {
    onChange(event) {
      this.$emit('update:modelValue', event.target.checked);
    },
  },
};
</script>

第二步:封装CheckGroup组件

接下来,我们创建CheckGroup组件,用于管理一组CheckBox,确保任何时候只有一个CheckBox被选中。

vue 复制代码
<template>
  <div>
    <CheckBox
      v-for="option in options"
      :key="option.value"
      :label="option.label"
      :modelValue="selected === option.value"
      @update:modelValue="() => updateSelected(option.value)"
    />
  </div>
</template>

<script>
import { ref } from 'vue';
import CheckBox from './CheckBox.vue'; // 确保路径正确

export default {
  components: {
    CheckBox,
  },
  props: {
    options: Array,
  },
  setup(props) {
    const selected = ref(null);

    const updateSelected = (value) => {
      selected.value = value;
    };

    return { selected, updateSelected };
  },
};
</script>

CheckGroup组件中,我们使用ref来跟踪当前选中的选项。每个CheckBox通过:modelValue绑定来确定其选中状态。当任一CheckBox的状态改变时,updateSelected方法会被调用来更新selected,从而确保只有一个CheckBox被选中。

第三步:使用CheckGroup组件

最后,展示如何使用CheckGroup组件。

vue 复制代码
<template>
  <CheckGroup :options="options" />
</template>

<script>
import CheckGroup from './CheckGroup.vue'; // 确保路径正确

export default {
  components: {
    CheckGroup,
  },
  data() {
    return {
      options: [
        { label: '选项1', value: '1' },
        { label: '选项2', value: '2' },
        { label: '选项3', value: '3' },
      ],
    };
  },
};
</script>

通过将options数组传递给CheckGroup组件,我们定义了三个CheckBox,它们将表现出单选的行为。

方式二: JS

要在Vue 3中使用defineComponent函数并在JavaScript文件中编写组件,需要将模板作为字符串提供给template字段。由于JavaScript文件不支持<template>标签,我们将使用反引号(`)来定义模板字符串。下面是如何重写CheckBox和CheckGroup组件。

CheckBox组件

首先是CheckBox组件。我们将其定义在一个.js文件中,如CheckBox.js

javascript 复制代码
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'CheckBox',
  props: {
    modelValue: Boolean,
    label: String,
  },
  emits: ['update:modelValue'],
  template: `
    <div>
      <input type="checkbox" :checked="modelValue" @change="onChange" />
      <label>{{ label }}</label>
    </div>
  `,
  methods: {
    onChange(event) {
      this.$emit('update:modelValue', event.target.checked);
    },
  },
});

CheckGroup组件

接着是CheckGroup组件。我们同样将其定义在一个.js文件中,如CheckGroup.js

javascript 复制代码
import { defineComponent, ref } from 'vue';
import CheckBox from './CheckBox.js'; // 确保路径正确

export default defineComponent({
  name: 'CheckGroup',
  components: {
    CheckBox,
  },
  props: {
    options: Array,
  },
  setup(props) {
    const selected = ref(null);

    const updateSelected = (value) => {
      selected.value = value;
    };

    return { selected, updateSelected };
  },
  template: `
    <div>
      <CheckBox
        v-for="option in options"
        :key="option.value"
        :label="option.label"
        :modelValue="selected === option.value"
        @update:modelValue="() => updateSelected(option.value)"
      />
    </div>
  `,
});

使用组件

最后,在Vue应用的入口文件或任何组件中使用CheckGroup组件,我们需要先导入并注册这个组件。假设你的入口文件是main.js,并且你想在根Vue实例中直接使用CheckGroup组件:

javascript 复制代码
import { createApp } from 'vue';
import App from './App.vue'; // 主组件
import CheckGroup from './components/CheckGroup.js'; // 确保路径正确

const app = createApp(App);
app.component('CheckGroup', CheckGroup);

app.mount('#app');

在你的App.vue或任何其他组件中,你现在可以直接使用<CheckGroup :options="options" />来渲染组件,其中options是你传递给组件的数据。

这种方式使得组件的定义和使用更加灵活,特别是当你希望在纯JavaScript环境中工作,而不是在.vue文件中时。

结尾

以上就是如何在Vue 3.x中封装一个CheckGroup组件以实现CheckBox的单选功能的步骤。这种方式充分利用了Vue 3的Composition API,提高了代码的可读性和可维护性。希望这能帮助你在Vue项目中实现类似的功能。

相关推荐
用户516816614584111 小时前
Vue Router 路由懒加载引发的生产页面白屏问题
vue.js·vue-router
前端缘梦11 小时前
Vue Keep-Alive 组件详解:优化性能与保留组件状态的终极指南
前端·vue.js·面试
Simon_He11 小时前
这次来点狠的:用 Vue 3 把 AI 的“碎片 Markdown”渲染得又快又稳(Monaco 实时更新 + Mermaid 渐进绘图)
前端·vue.js·markdown
王同学QaQ16 小时前
Vue3对接UE,通过MQTT完成通讯
javascript·vue.js
华仔啊16 小时前
基于 RuoYi-Vue 轻松实现单用户登录功能,亲测有效
java·vue.js·后端
艾小码17 小时前
告别Vue混入的坑!Composition API让我效率翻倍的3个秘密
前端·javascript·vue.js
Gracemark1 天前
高德地图-地图选择经纬度问题【使用输入提示-使用Autocomplete进行联想输入】(复盘)
vue.js
天下无贼1 天前
【手写组件】 Vue3 + Uniapp 手写一个高颜值日历组件(含跨月补全+今日高亮+选中状态)
前端·vue.js
洋葱头_1 天前
vue3项目不支持低版本的android,如何做兼容
前端·vue.js
奔跑的蜗牛ing2 天前
Vue3 + Element Plus 输入框省略号插件:零侵入式全局解决方案
vue.js·typescript·前端工程化