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

相关推荐
C_心欲无痕19 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫19 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo20 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo21 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq21 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
烛阴21 小时前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
xkxnq1 天前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup1 天前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos
BBBBBAAAAAi1 天前
Claude Code安装记录
开发语言·前端·javascript
xiaolyuh1231 天前
【XXL-JOB】 GLUE模式 底层实现原理
java·开发语言·前端·python·xxl-job