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 则需要多写几行代码,但也能实现同样的效果。

相关推荐
linweidong4 小时前
C++ 模块化编程(Modules)在大规模系统中的实践难点?
linux·前端·c++
leobertlan8 小时前
2025年终总结
前端·后端·程序员
子兮曰8 小时前
OpenClaw架构揭秘:178k stars的个人AI助手如何用Gateway模式统一控制12+通讯频道
前端·javascript·github
百锦再9 小时前
Reactive编程入门:Project Reactor 深度指南
前端·javascript·python·react.js·django·前端框架·reactjs
莲华君9 小时前
React快速上手:从零到项目实战
前端·reactjs教程
百锦再9 小时前
React编程高级主题:测试代码
android·前端·javascript·react.js·前端框架·reactjs
易安说AI9 小时前
Ralph Loop 让Claude无止尽干活的牛马...
前端·后端
失忆爆表症11 小时前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
小迷糊的学习记录11 小时前
Vuex 与 pinia
前端·javascript·vue.js
发现一只大呆瓜11 小时前
前端性能优化:图片懒加载的三种手写方案
前端·javascript·面试