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项目中实现类似的功能。

相关推荐
Momo__2 小时前
Vue 3.6 Vapor Mode:跳过虚拟 DOM,性能极致优化
前端·vue.js
walking9573 小时前
重新学习前端之JavaScript
前端·vue.js·面试
walking9573 小时前
重新学习前端之HTML
前端·vue.js·面试
walking9573 小时前
重新学习前端之Vue
前端·vue.js·面试
泉城老铁3 小时前
springboot实现word转换pdf
vue.js·后端
walking9573 小时前
重新学习前端之Linux
前端·vue.js·面试
walking9573 小时前
重新学习前端之CSS
前端·vue.js·面试
walking9573 小时前
重新学习前端之Git
前端·vue.js·面试
Hello--_--World4 小时前
Vue指令:v-if vs v-show、v-if 与 v-for 的优先级冲突、自定义指令
前端·javascript·vue.js
Hello--_--World8 小时前
Vue:虚拟Dom
前端·javascript·vue.js