Vue 和 React 受控组件的区别!

大家好,我是 前端架构师 - 大卫

更多优质内容请关注微信公众号 @程序员大卫

初心为助前端人🚀,进阶路上共星辰✨,

您的点赞与关注❤️,是我笔耕不辍的灯💡。

背景

有时候我们希望一个复选框 (checkbox) 始终保持勾选状态,即使用户点击也不会被取消。

在真实业务中,当然可以通过 :disabled 属性直接禁用实现,但这并不是本文要讨论的重点。

举个类比:假设 Vue 并没有提供 v-model.number 这样的语法糖,而我们又想实现一个只能输入数字的 input,那实现方式就会相对繁琐。

所以本文用 checkbox 作为例子,来对比 ReactVue 在受控组件实现上的不同思路。

React 的实现

在 React 中,受控组件的思路非常直接:通过 state 控制值,任何用户交互最终都会回到 state 来决定组件显示。

js 复制代码
import { useState } from "react";

function App() {
	const [checked, setChecked] = useState(true);

	const onChange = () => {
		setChecked(true);
	};

	return <input checked={checked} type="checkbox" onChange={onChange} />;
}

export default App;

这里的核心逻辑是:

  • checked 始终受 state 管理;
  • 无论用户如何点击,onChange 都会把 checked 重置为 true

Vue3 的实现

在 Vue3 中,要让组件保持"受控",可以通过 v-model 配合事件回调来实现。 下面展示两种不同写法。

写法一:直接修改事件参数

html 复制代码
<script lang="ts" setup>
import { useTemplateRef } from "vue";

const checked = defineModel({
	default: true,
});

const onChange = (e: Event) => {
	(e.target as HTMLInputElement).checked = true;
	checked.value = true;
};
</script>

<template>
	<input type="checkbox" v-model="checked" @change="onChange" />
</template>

写法二:通过 ref 引用 DOM

html 复制代码
<script lang="ts" setup>
import { useTemplateRef } from "vue";

const checked = defineModel({
	default: true,
});

const inputRef = useTemplateRef("input");

const onChange = () => {
	if (inputRef.value) {
		inputRef.value.checked = true;
	}
	checked.value = true;
};
</script>

<template>
	<input type="checkbox" ref="input" v-model="checked" @change="onChange" />
</template>

这一写法借助 ref,直接操作 DOM 元素来重置勾选状态。

Vue2 的实现

在 Vue2 中,由于没有 defineModel 这样的语法糖,我们通常通过 datamethods 来控制。

写法一:事件里修改 event.target

html 复制代码
<script>
export default {
	data() {
		return {
			checked: true,
		};
	},
	methods: {
		onChange(e) {
			e.target.checked = true;
			this.checked = true;
		},
	},
};
</script>

<template>
	<input type="checkbox" v-model="checked" @change="onChange" />
</template>

写法二:使用 ref 引用

html 复制代码
<script>
export default {
	data() {
		return {
			checked: true,
		};
	},
	methods: {
		onChange(e) {
			this.$refs.input.checked = true;
			this.checked = true;
		},
	},
};
</script>

<template>
	<input type="checkbox" ref="input" v-model="checked" @change="onChange" />
</template>

这一写法与 Vue3 的"写法二"类似,也是通过 ref 强行把 DOM 状态改回去。

总结

  • React :天然是受控模式,所有输入值都由 state 控制,逻辑简单直接。
  • Vue3 :可以通过 v-model 配合事件控制,既能改 event.target,也能通过 ref 操作 DOM。
  • Vue2 :思路与 Vue3 类似,只是语法更原始,需要手动处理 dataref

通过这个例子可以看到,React 在受控组件实现上更自然,而 Vue 则需要多写几行代码,但也能实现同样的效果。

相关推荐
Momo__1 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富1 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇1 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇1 小时前
React中的forwardRef
前端·react.js·面试
槑有老呆1 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马1 小时前
Verilog开发常见问题汇总解析
前端
子兮曰1 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端
weedsfly1 小时前
语法糖褪去之后——Babel 转译产物中的 JavaScript 本貌
前端·javascript
JustHappy1 小时前
「软件设计思想杂谈🤔」“切图仔”也能懂编译原理?框架源码也许没那么难。聊聊 Vue 的编译(上)
前端·javascript·vue.js