定义
受控组件:组件的值的更新依赖状态值来更新,一定程度上,组件值是恒等于状态值的。
非受控组件:组件值更新由组件自己维护,需要以操作 DOM 的方式来获取组件的值。
React
在 React
中表现如下:
import React, { useState } from "react";
export default function App() {
const [vale, setValue] = useState(0);
const changeEvent = function(e) {
console.log(e);
setValue(123);
// setValue(e.target.value);
}
return (
<div className="App">
<input type="text" value={value} onChange={changeEvent} />
</div>
);
}
input 中设置了 value
,则为受控组件,onChange
事件设置如下:
-
不设置
onChange
事件,输入内容,input 并不会渲染出来。因为 input 值的更新,是依赖状态值来更新的(渲染),所以 input 不会渲染输入的内容。 -
设置
onChange
事件,但onChange
事件中不更新状态值/设置状态值为某个值,并不是用户输入的值的时候,input 也不会正确地渲染。理由同上。 -
设置
onChange
事件,且设置状态值为输入值(e.target.value
)时,input 将正确渲染内容。
如不设置 value
,则 input 组件属于非受控组件。用户输入的内容,将由 input 组件维护(更新渲染行为不受到程序控制)。
Vue
在 Vue
中,有两种常用的设置方式,一种怪异的设置方式,不同设置,表现不同。
v-model
<template>
<input v-model="value" />
</template>
<script>
export default {
name: "App",
components: {},
data: function () {
return {
value: 123,
};
}
};
</script>
表现正常,效果如 React
的设置 value
和正确设置 onChange
事件的情况一致。
:value & @input
<template>
<input :value="value" @input="setValue" />
</template>
<script>
export default {
name: "App",
components: {},
data: function () {
return {
value: 123,
};
},
methods: {
setValue(e) {
this.value = 123;
// this.value += e.data;
},
},
};
</script>
input 的表现(渲染)跟值分离了。this.value
还是设置为 123
,但 input 却正确地响应了用户的输入。
v-model & @input
<template>
<input v-model="value" @input="setValue" />
</template>
<script>
export default {
name: "App",
components: {},
data: function () {
return {
value: 123,
};
},
methods: {
setValue(e) {
this.value = 123;
// this.value += e.data;
},
},
};
</script>
这种情况,日常开发是不会这样发生的。这里的 input 表现是符合逻辑的。如设置 this.value=123
则 input 的渲染不会渲染用户输入的内容,而是 123
。如不设置 this.value
的值,则 input 表现跟 v-model
的情况一致。
分析 v-model 和 :value & @input 表现差异的原因
首先,不会去分析 v-model & @input
这种怪异的用法的。
v-model
的表现表明组件是可控的。所以分析一下 :value & @input
表现跟状态不一的情况。
为什么这种情况下,表现和状态不一呢?
我们知道 Vue 是采取依赖收集的这种方式去发现更新情况,然后更新视图的。当 input 输入时,会触发 @input
事件,但 @input
事件中,对 value
的处理是赋一个常数值(this.value = 123
)。此时,this.value
值相同,并没有触发更新,所以 Vue
认为 input 组件不需要跟新,也就不会去更新视图,所以 input 会响应用户的输入,但却没有触发 Vue
更新。
如何证明以上结论是正确的呢?请看下面 2 种情况:
- 如将
this.value = 456
,那么 input 会先从 123 变成 456,而后表现跟上面分析一致。因为 @input 中 this.value 赋值是常数,不会触发 Vue 更新视图,而 input 则是响应了用户的输入。 - 如将
this.value = Math.random()
,input 的内容会随着用户输入而变化(并不是用户输入的值),因为this.value
得到了更新,所以 Vue 更新了视图,将 input 的内容同步为this.value
的值。
React 跟 Vue 区别
从上文可知,React
跟 Vue
的区别在于:React
强制性使 input 的更新跟状态值的更新同步;而 Vue
则只会在状态值更新的时候才会同步更新视图,如状态值不变(如设置常亮this.value = 123
),组件的视图更新将表现为非受控。
为什么 React 和 Vue 会出现这样的区别
是因为它们的更新方式是不一样的。
Vue
:依赖收集,数据更新后更新视图。
React
:依靠 Render
和 Diff
配合更新,每次更新都会将状态值和视图同步。
所以,input 组件,绑定的状态值是 this.value
,onChange/@input
事件的处理是设置状态值等于一个常量:setValue(123) / this.value = 123
,那么当用户在 input 输入内容时:
Vue
:咦,状态没更新,不用更新视图,美滋滋!
React
:嗯?状态是这个,视图渲染了那个,闹啥呢,同步一下!于是将视图上的值改为状态值。
小结
- 受控组件的关键点在于,状态值更新会同步视图更新,一定条件下组件的值恒等于状态值;
React
的受控组件,状态值跟视图是两两强绑定关系的,组件值恒等于状态值;Vue
的受控组件,状态值更新一定会同步视图更新,此时组件值恒等于状态值;但视图更新在特殊情况下(如视图更新了,但状态值保持不变),组件值不等于状态值;React
和Vue
的受控组件表现略微差异的原因在于它们不同的更新方式,Vue
着重于状态值的更新情况来更新视图,而React
会强制状态值和视图保持同步。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!