Vue不确定复选框绑定

9

我正在使用Vue进行数据绑定。 我想创建一个用于访问级别控制的小部件,因此我需要允许、拒绝和不确定状态。

这个标记很好,但没有不确定状态:

<div class="row" v-for='a in context.This.Actions'>
    <div class="col-96">
        <input class="custom-control-input access-checkbox" v-bind:id="'chk_'+a.Name" v-bind:value="a.Id" v-model="context.This.RoleActions" indeterminate="true" type="checkbox" />
        <label class="pointer" v-bind:for="'chk_'+a.Name">{{ a.Name }}</label>
    </div>
</div>

变量如下:
context.This.Actions = [
    { "Id": "id_1",
      "Name": "AAA"
    },
    { "Id": "id_2",
      "Name": "BBB"
    },
    { "Id": "id_3",
      "Name": "CCC"
    }
]

context.This.RoleActions = [ "id_1", "id_2" ]

我希望进行以下更改:

context.This.RoleActions = [ {"id_1":true}, {"id_2":false} ]

我期望您能得到以下结果:
  • 第一个复选框:已选中

  • 第二个复选框:未选中

  • 其他一个:不确定状态

3个回答

21

Indeterminate是checkbox上的一个DOM属性,这意味着在标记中放置它不会产生影响,需要以编程方式应用它。

即使这样做了,仍要记住复选框的状态仍然是选中或未选中。在处理表单时,这一点很重要。区别仅在视觉上。(来源)

有了这些注意事项,在Vue 2中,您可以像这样向复选框添加indeterminate属性:

<input type="checkbox" indeterminate.prop="true">

或在组件中绑定到动态值:

<input type="checkbox" :indeterminate.prop="dataProperty">

我建议考虑重构代码实现以上功能。


1
这里是参考链接:https://github.com/vuejs/vue/issues/4094#issuecomment-261659740 - Hafez Divandari

1
我曾经遇到过使用props在复选框上支持2和3状态的类似问题。为此,我使用了Vuetify复选框的getter和setter计算属性来处理。以下是我的示例。
<template>
  <v-container class="checkbox-container">
    <v-checkbox
      type="checkbox"
      :indeterminate="indeterminate"
      :color="indeterminate ? '#767575' : 'success'"
      v-model="internalState"
      @click.stop="onCheckbox"
      @keyup.space.prevent="onCheckbox"
    ></v-checkbox>
  </v-container>
</template>

<script>
/**
 * Responsability: boolean field editor checkbox
 * When @threeState is true : following states (check, uncheck, indeterminate) otherwise (check, uncheck)
 * @checkboxState is an external state where it contains always the current state of checkbox
 **/
export default {
  model: {
    // v-model prop
    prop: 'checkboxState',
  },
  props: {
    threeState: Boolean,
    /**
     * Init state is the starting state Which the chekbox starts from.
     * by defining initstate it will ignore the default input @boolProperty
     **/
    initState: {
      type: String,
      default: 'false',
    },
    // Reperesent the value of checked state in model
    config: {
      type: Object,
      default: () => ({
        checked: 'true',
        unchecked: 'false',
        indeterminate: null,
      }),
    },
    checkboxState: {
      type: String,
    },
  },

  data() {
    return {
      internalState: this.checkboxState,
      indeterminate: false,
    }
  },

  computed: {
    state: {
      get() {
        return this.checkboxState
      },
      set(newState) {
        this.changeCheckboxState(newState)
      },
    },
  },

  // Change the state of checkbox after DOM is mounted
  mounted() {
    this.changeCheckboxState(this.initState)
  },

  methods: {
    changeCheckboxState(state) {
      this.$vnode.data.model.callback(state)
      this.internalState = state === this.config.checked
      this.indeterminate = state === this.config.indeterminate
    },

    onCheckbox() {
      if (this.threeState) {
        switch (this.state) {
          case this.config.unchecked:
            this.state = this.config.checked
            break
          case this.config.checked:
            this.state = this.config.indeterminate
            break
          case this.config.indeterminate:
            this.state = this.config.unchecked
            break
        }
      } else {
        this.state = (!(this.state === this.config.checked)).toString()
      }
    },
  },
}
</script>

<style lang="scss" scoped>
.checkbox-container {
  width: 50px;
}
</style>

0

简单示例

<template>
  <input
    type="checkbox"
    :indeterminate="isIndeterminate"
    :checked="isChecked"
    :value="modelValue"
    @input="$emit('update:modelValue', isChecked)"
    @click="toggleCheckState"
  />
</template>

<script setup lang="ts">
const props = defineProps({
  modelValue: { type: Boolean, default: undefined }
})
defineEmits(['update:modelValue'])
import { onMounted, ref } from 'vue'

const isChecked = ref<boolean | undefined>(false)
const isIndeterminate = ref(false)

onMounted(() => {
  if (props.modelValue == undefined) isIndeterminate.value = true
  else isChecked.value = props.modelValue
})

function toggleCheckState() {
  if (isIndeterminate.value) {
    isChecked.value = true
    isIndeterminate.value = false
  } else if (isChecked.value == false) {
    isChecked.value = undefined
    isIndeterminate.value = true
  } else {
    isChecked.value = false
    isIndeterminate.value = false
  }
}
</script>

使用方法

<SmartCheckbox v-model="anyRef" /> 

{{ anyRef}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接