likes
comments
collection
share

解密v-model:揭示Vue.js和React.js中实现双向数据绑定的不同策略

作者站长头像
站长
· 阅读数 17

vuev-model 的实现

vuev-model 可以在组件上使用以实现双向绑定。一般用在 form 表单中

<input v-model="msg" />

v-model 本身是一个语法糖,模板编译之后上面的代码会展开成下面的形式

默认情况下,v-model 在组件上都是使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件。

<input
  :value="searchText"
  @input="searchText = $event.target.value"
/>

如果是在组件上的 v-model 会编译成

<CustomInput
  :modelValue="searchText"
  @update:modelValue="newValue => searchText = newValue"
/>

等同于

<CustomInput v-model="searchText" />

来看一下 CustomInput 中是如何实现的

CustomInput.vue

<template>
    <div>
        <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
    </div>
</template>

<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

使用时

const msg = ref('')

const updateValue = (v) => {
  msg.value = v
}

<CustomInput :model-value="msg" @update:model-value="updateValue" />

<!--简写-->
<CustomInput :model-value="msg" @update:model-value="newV => msg = newV" />

<!--等价于 v-model 格式-->

<CustomInput v-model="msg" />

v-model 绑定多个值

<UserName
  v-model:first-name="first"
  v-model:last-name="last"
/>

<script setup>
defineProps({
  firstName: String,
  lastName: String
})

defineEmits(['update:firstName', 'update:lastName'])
</script>

<template>
  <input
    type="text"
    :value="firstName"
    @input="$emit('update:firstName', $event.target.value)"
  />
  <input
    type="text"
    :value="lastName"
    @input="$emit('update:lastName', $event.target.value)"
  />
</template>

react 中实现 v-model 的效果

vue 中,v-model 相当于给组件传递一个 props 和一个自定义事件,在 react 中没有自定义事件,我们可以在 props 中传递一个事件具体实现

CustomInput.jsx

const MyComponent = ({ modelValue, updateModelValue }) => {
  return (
    <div>
        <input value={modelValue} onInput={(e) => updateModelValue(e.target.value)} />
    </div>
  )
}

使用时


const [msg, setMsg] = useState('')

const updateValue = (v) => {
    setMsg(v)
}


<div>{ msg }</div>
<MyComponent modelValue={msg} updateModelValue={updateValue} />

封装成 hook


import React, { useState } from 'react';

function useBinding(initialValue) {
  const [value, setValue] = useState(initialValue);

  const handleChange = (newValue) => {
    setValue(newValue);
  };

  return {
    value,
    onChange: handleChange,
  };
}

export default function CustomInput({value, onChange}) {
  return (
    <input type="text" value={value} onChange={(e) => onChange(e.target.value)} />
  );
}


使用


const { value, onChange } = useBinding('');

<CustomInput value={value} onChange={onChange} />

相关主题推荐:

通过Vue3对比学习Reactjs: 模板语法 vs JSX Vue vs Reactjs之 props Vuejs vs Reactjs:组件之间如何通信

转载自:https://juejin.cn/post/7249584280824184890
评论
请登录