Vue和React受控組件的區(qū)別小結(jié)
背景
有時(shí)候我們希望一個(gè)復(fù)選框 (checkbox) 始終保持勾選狀態(tài),即使用戶點(diǎn)擊也不會(huì)被取消。
在真實(shí)業(yè)務(wù)中,當(dāng)然可以通過(guò) :disabled 屬性直接禁用實(shí)現(xiàn),但這并不是本文要討論的重點(diǎn)。
舉個(gè)類比:假設(shè) Vue 并沒(méi)有提供 v-model.number 這樣的語(yǔ)法糖,而我們又想實(shí)現(xiàn)一個(gè)只能輸入數(shù)字的 input,那實(shí)現(xiàn)方式就會(huì)相對(duì)繁瑣。
所以本文用 checkbox 作為例子,來(lái)對(duì)比 React 和 Vue 在受控組件實(shí)現(xiàn)上的不同思路。
React 的實(shí)現(xiàn)
在 React 中,受控組件的思路非常直接:通過(guò) state 控制值,任何用戶交互最終都會(huì)回到 state 來(lái)決定組件顯示。
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管理;- 無(wú)論用戶如何點(diǎn)擊,
onChange都會(huì)把checked重置為true。
Vue3 的實(shí)現(xiàn)
在 Vue3 中,要讓組件保持“受控”,可以通過(guò) v-model 配合事件回調(diào)來(lái)實(shí)現(xiàn)。 下面展示兩種不同寫法。
寫法一:直接修改事件參數(shù)
<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>
寫法二:通過(guò)ref引用 DOM
<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 元素來(lái)重置勾選狀態(tài)。
Vue2 的實(shí)現(xiàn)
在 Vue2 中,由于沒(méi)有 defineModel 這樣的語(yǔ)法糖,我們通常通過(guò) data 和 methods 來(lái)控制。
寫法一:事件里修改event.target
<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引用
<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 的“寫法二”類似,也是通過(guò) ref 強(qiáng)行把 DOM 狀態(tài)改回去。
總結(jié)
- React:天然是受控模式,所有輸入值都由
state控制,邏輯簡(jiǎn)單直接。 - Vue3:可以通過(guò)
v-model配合事件控制,既能改event.target,也能通過(guò)ref操作 DOM。 - Vue2:思路與 Vue3 類似,只是語(yǔ)法更原始,需要手動(dòng)處理
data和ref。
通過(guò)這個(gè)例子可以看到,React 在受控組件實(shí)現(xiàn)上更自然,而 Vue 則需要多寫幾行代碼,但也能實(shí)現(xiàn)同樣的效果。
到此這篇關(guān)于Vue和React受控組件的區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)Vue和 React 受控組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決vue項(xiàng)目Error:Cannot find module‘xxx’類報(bào)錯(cuò)問(wèn)題
當(dāng)npm運(yùn)行報(bào)錯(cuò)Error:Cannot find module 'xxx'時(shí),通常是因?yàn)閚ode_modules文件或依賴未正確安裝,解決步驟包括刪除node_modules和package-lock.json文件,重新運(yùn)行npm install,并根據(jù)需要安裝額外插件,若網(wǎng)絡(luò)問(wèn)題導(dǎo)致安裝失敗2024-10-10
Vue實(shí)現(xiàn)低版本瀏覽器升級(jí)提示的代碼示例
在現(xiàn)代Web開發(fā)中,瀏覽器兼容性是一個(gè)重要的問(wèn)題,盡管大多數(shù)用戶已經(jīng)轉(zhuǎn)向了現(xiàn)代瀏覽器,但仍有一部分用戶可能仍在使用老舊的瀏覽器版本,本文將詳細(xì)介紹如何在Vue項(xiàng)目中實(shí)現(xiàn)低版本瀏覽器升級(jí)提示,并通過(guò)多個(gè)代碼示例來(lái)展示不同的應(yīng)用場(chǎng)景和技術(shù)點(diǎn),需要的朋友可以參考下2024-10-10
vue實(shí)現(xiàn)文件流形式的導(dǎo)出下載全過(guò)程
Vue項(xiàng)目中下載返回的文件流操作包括:使用Axios請(qǐng)求文件流數(shù)據(jù)、設(shè)置響應(yīng)類型為'blob'、創(chuàng)建下載鏈接并觸發(fā)下載,關(guān)鍵步驟是使用Blob對(duì)象和URL.createObjectURL生成下載鏈接2025-12-12
淺談在vue中用webpack打包之后運(yùn)行文件的問(wèn)題以及相關(guān)配置方法
下面小編就為大家分享一篇淺談在vue中用webpack打包之后運(yùn)行文件的問(wèn)題以及相關(guān)配置方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
vue中axios的post請(qǐng)求,415錯(cuò)誤的問(wèn)題
這篇文章主要介紹了vue中axios的post請(qǐng)求,415錯(cuò)誤的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
vue實(shí)現(xiàn)循環(huán)滾動(dòng)列表
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)循環(huán)滾動(dòng)列表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06
vue使用Print.js打印頁(yè)面樣式不出現(xiàn)的解決
這篇文章主要介紹了vue使用Print.js打印頁(yè)面樣式不出現(xiàn)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

