项目难点

99 阅读1分钟

封装复杂input组件

在vue中使用v-model语法糖将input变成一个受控组件。

<template>
    <input :value="state" name="username" @change="onChange" />
    state 值:{{ state }}
</template>
<script setup>
import { ref } from 'vue'
// 编辑时的默认值
const state = ref('稀土掘金')
const onChange = (e) => {
  state.value = e.target.value
}
</script>

如果不使用v-model,则需要用到:value和@change,且需要watch传进来的value。

<template>
  <input :value="state" type="text" @change="changeHandle" />
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue'
const props = defineProps({
  value: {
    type: String,
    default: '',
  },
})
const emit = defineEmits(['change'])
// 声明子组件本地的数据变量
const state = ref('')
watch(
  () => props.value,
  (newVal) => {
    state.value = newVal
  },
  { immediate: true }
)
const changeHandle = (e: any) => {
  state.value = e.target.value
  // 发射父组件的 change 监听事件
  emit('change', state.value)
}
</script>

在以上基础上修改,实现v-model,只需要替换掉传进来的value,换成modelValue,并且使用onUpload:来进行

<template>
  <input :value="state" type="text" @change="changeHandle" />
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue'

const props = defineProps({
-  value: {
+  modelValue: {
    type: String,
    default: '',
  },
})

- const emit = defineEmits(['change'])
+ const emit = defineEmits(['onUpdate:modelValue'])

const state = ref('')

watch(
-  () => props.value,
+  () => props.modelValue,
  (newVal) => {
    state.value = newVal
  },
  { immediate: true }
)

const changeHandle = (e: any) => {
  state.value = e.target.value
-  emit('change', state.value)
+  emit('onUpdate:modelValue', state.value)
}
</script>