最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 受控组件分析(React & Vue)

    正文概述 掘金(活抓一只小机灵)   2021-01-07   700

    定义

    受控组件:组件的值的更新依赖状态值来更新,一定程度上,组件值是恒等于状态值的。

    非受控组件:组件值更新由组件自己维护,需要以操作 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 事件设置如下:

    1. 不设置 onChange 事件,输入内容,input 并不会渲染出来。因为 input 值的更新,是依赖状态值来更新的(渲染),所以 input 不会渲染输入的内容。

    2. 设置 onChange 事件,但 onChange 事件中不更新状态值/设置状态值为某个值,并不是用户输入的值的时候,input 也不会正确地渲染。理由同上。

    3. 设置 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 种情况:

    1. 如将 this.value = 456 ,那么 input 会先从 123 变成 456,而后表现跟上面分析一致。因为 @input 中 this.value 赋值是常数,不会触发 Vue 更新视图,而 input 则是响应了用户的输入。
    2. 如将 this.value = Math.random() ,input 的内容会随着用户输入而变化(并不是用户输入的值),因为 this.value 得到了更新,所以 Vue 更新了视图,将 input 的内容同步为 this.value 的值。

    React 跟 Vue 区别

    从上文可知,ReactVue 的区别在于:React 强制性使 input 的更新跟状态值的更新同步;而 Vue 则只会在状态值更新的时候才会同步更新视图,如状态值不变(如设置常亮this.value = 123),组件的视图更新将表现为非受控

    为什么 React 和 Vue 会出现这样的区别

    是因为它们的更新方式是不一样的。

    Vue:依赖收集,数据更新后更新视图。

    React:依靠 RenderDiff 配合更新,每次更新都会将状态值和视图同步。

    所以,input 组件,绑定的状态值是 this.valueonChange/@input 事件的处理是设置状态值等于一个常量:setValue(123) / this.value = 123,那么当用户在 input 输入内容时:

    Vue:咦,状态没更新,不用更新视图,美滋滋!

    React:嗯?状态是这个,视图渲染了那个,闹啥呢,同步一下!于是将视图上的值改为状态值。

    小结

    1. 受控组件的关键点在于,状态值更新会同步视图更新,一定条件下组件的值恒等于状态值;
    2. React 的受控组件,状态值跟视图是两两强绑定关系的,组件值恒等于状态值;
    3. Vue 的受控组件,状态值更新一定会同步视图更新,此时组件值恒等于状态值;但视图更新在特殊情况下(如视图更新了,但状态值保持不变),组件值不等于状态值;
    4. ReactVue 的受控组件表现略微差异的原因在于它们不同的更新方式,Vue 着重于状态值的更新情况来更新视图,而 React 会强制状态值和视图保持同步。

    起源地下载网 » 受控组件分析(React & Vue)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元