VueJS中v-model和.sync详解

v-model

v-model其实就是一个语法糖,绑定value事件,监听input事件。v-model默认会将value属性传递给子组件,并且会监听input事件,实现双向数据绑定

index.vue

<template>
  <div>
    <k-input v-model="msg"></k-input>
    // v-model就是下面用发的语法糖
   // 
    {{ msg }}
  </div>
</template>

<script>
import KInput from './KInput'
export default {
  name: 'kModel',
  components: {
    KInput
  },
  data () {
    return {
      msg: 'this is message'
    }
  }
}
</script>

<style lang="scss" scoped></style>

k-input.vue

<template>
  <div>
    <input type="text" :value="value" @input="inputHandle">
  </div>
</template>

<script>
export default {
  name: 'kInput',
  model: {
    prop: 'value',
    event: 'input'
  },
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  methods: {
    inputHandle (e) {
      this.$emit('input', e.target.value)
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

效果图

VueJS中v-model和.sync详解_第1张图片

.sync

子组件分发update:msg,父组件监听@update:msg

index.vue

<template>
  <div>
  	// 
  	// 下面是语法糖用法
    <k-input :msg.sync="msg"></k-input>
    {{ msg }}
  </div>
</template>

<script>
import KInput from './KInput'
export default {
  name: 'kModel',
  components: {
    KInput
  },
  data () {
    return {
      msg: 'this is message'
    }
  }
}
</script>

<style lang="scss" scoped></style>

k-input

<template>
  <div>
    <input type="text" :value="msg" @input="inputHandle">
  </div>
</template>

<script>
export default {
  name: 'kInput',
  props: {
    msg: {
      type: String,
      default: ''
    }
  },
  methods: {
    inputHandle (e) {
      this.$emit('update:msg', e.target.value)
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

自定义el-radio组件实现

仿element-ui实现el-radio的组件的实现

index.vue

<template>
  <div>
    <k-radio-group v-model="gender">
      <k-radio label="男性"></k-radio>
      <k-radio label="女性"></k-radio>
    </k-radio-group>
    <hr />
    {{ gender }}
  </div>
</template>

<script>
import KRadioGroup from './KRadioGroup'
import KRadio from './KRadio'
export default {
  name: 'kModel',
  components: {
    KRadioGroup,
    KRadio
  },
  data () {
    return {
      gender: '女性'
    }
  }
}
</script>

<style lang="scss" scoped></style>

k-radio-group

<template>
  <div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'kRadioGroup',
  model: {
    prop: 'value',
    event: 'input'
  },
  props: {
    value: {
      type: String
    }
  },
  mounted () {
    this.$on('change', (value) => {
      this.$emit('input', value)
    })
  }
}
</script>

<style lang="scss" scoped>

</style>

k-radio

<template>
  <div>
    <label>
      {{ label }}
      <input name="gender" :value="label" :checked="isChecked"  type="radio"  @change="changeHandle" />
    </label>
  </div>
</template>

<script>
export default {
  name: 'kRadio',
  props: {
    label: {
      type: String
    }
  },
  methods: {
    changeHandle (e) {
      this.$parent.$emit('change', e.target.value)
    }
  },
  computed: {
    isChecked () {
      return this.$parent.value === this.label
    }
  }
}
</script>
<style lang="scss" scoped></style>

效果图

VueJS中v-model和.sync详解_第2张图片

你可能感兴趣的:(VueJS,javascript,vue.js,javascript,reactjs,typescript,es6)