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

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学2 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端