复选框组件封装

2022-04-26  本文已影响0人  Jycoding

目的:实现一个自定义复选框组件。

大致步骤:

实现组件本身的选中与不选中效果

实现组件的v-model指令

改造成 @vueuse/core 的函数写法

落地代码:

1)实现组件功能

<template>

  <div class="xtx-checkbox" @click="changeChecked()">

    <i v-if="checked" class="iconfont icon-checked"></i>

    <i v-else class="iconfont icon-unchecked"></i>

    <span v-if="$slots.default"><slot /></span>

  </div>

</template>

<script>

import { ref } from 'vue'

export default {

  name: 'XtxCheckbox',

  setup () {

    const checked = ref(false)

    const changeChecked = () => {

      checked.value = !checked.value

    }

    return { checked, changeChecked }

  }

}

</script>

<style scoped lang="less">

.xtx-checkbox {

  display: inline-block;

  margin-right: 2px;

  .icon-checked {

    color: @xtxColor;

    ~ span {

      color: @xtxColor;

    }

  }

  i {

    position: relative;

    top: 1px;

  }

  span {

    margin-left: 2px;

  }

}

</style>

2)实现双向绑定

vue3.0中v-model会拆解成 属性 modelValue 和 事件 update:modelValue

import { ref, watch } from 'vue'

// v-model  ====>  :modelValue  +  @update:modelValue

export default {

  name: 'XtxCheckbox',

  props: {

    modelValue: {

      type: Boolean,

      default: false

    }

  },

  setup (props, { emit }) {

    const checked = ref(false)

    const changeChecked = () => {

      checked.value = !checked.value

      // 使用emit通知父组件数据的改变

      emit('update:modelValue', checked.value)

    }

    // 使用侦听器,得到父组件传递数据,给checked数据

    watch(() => props.modelValue, () => {

      checked.value = props.modelValue

    }, { immediate: true })

    return { checked, changeChecked }

  }

}

3)补充 @vueuse/core 的实现

import { useVModel } from '@vueuse/core'

// v-model  ====>  :modelValue  +  @update:modelValue

export default {

  name: 'XtxCheckbox',

  props: {

    modelValue: {

      type: Boolean,

      default: false

    }

  },

  setup (props, { emit }) {

    // 使用useVModel实现双向数据绑定v-model指令

    // 1. 使用props接收modelValue

    // 2. 使用useVModel来包装props中的modelValue属性数据

    // 3. 在使用checked.value就是使用父组件数据

    // 4. 在使用checked.value = '数据' 赋值,触发emit('update:modelvalue', '数据')

    const checked = useVModel(props, 'modelValue', emit)

    const changeChecked = () => {

      const newVal = !checked.value

      // 通知父组件

      checked.value = newVal

      // 让组件支持change事件

      emit('change', newVal)

    }

    return { checked, changeChecked }

  }

}

总结: useVModel 工具函数可实现双向绑定。

上一篇下一篇

猜你喜欢

热点阅读