精华内容
下载资源
问答
  • js实现双向数据绑定

    千次阅读 2017-10-10 17:55:46
    需求现在的框架都讲究什么...- 双向数据绑定:数据模型(Module)和视图(View)之间的双向绑定。就是我不管修改数据模型的相关数据,还是视图上的数据,相对应的数据也会跟着更新。实现原理主要的就是事件的绑定。 -

    需求

    现在的框架都讲究什么单向绑定,双向绑定的都是什么东西?
    - 单向数据绑定:指的是我们先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里面。
    - 双向数据绑定:数据模型(Module)和视图(View)之间的双向绑定。就是我不管修改数据模型的相关数据,还是视图上的数据,相对应的数据也会跟着更新。

    实现原理

    主要的就是事件的绑定。
    - 在视图层(View)上,可以绑定keyup事件,来更新数据模型
    - 在数据模型上面利用Object.defineProperty()方法定义对象的set方法,在触发对象属性设置时,将view层的数据也修改掉。

    案例代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <input type="text" id="myinput" >
    <script>
        var input = document.getElementById("myinput");
        var obj = {};
        Object.defineProperty(obj, "input", {
            get: function () {
                return input.value;
            },
            set: function (val) {
                input.value = val;
                changeCallback(input.value);
            }
        });
    
        input.onkeyup = function () {
            obj.input = input.value;
        };
    
        function changeCallback(val) {
            console.log("这里是不管view层,还是module层修改后的回调,最后设置的值是"+val);
        }
    
    </script>
    </body>
    </html>

    思路

    • 首先,我们先使用Object.defineProperty()方法设置obj的set方法,只要修改obj的input属性,就会触发这个这个set方法,然后触发回调,这就实现了module层的数据绑定。
    • 然后,再input上绑定keyup事件,实现了view层的绑定。
    • 只要两者有一个修改,不管input的value值,还是获取obj的input属性,都是获取最新修改的值。
    • 这应该是最简单的思路了。
    展开全文
  • “别具一格”的vue双向数据绑定原理

    千次阅读 多人点赞 2021-05-30 01:35:35
    见网上许多文章讲vue双向数据绑定一开口就大谈 Object.defineProperty 和 proxy。其实不然。 vue 中有两个“特别的”概念:响应式(它和defineProperty有关)和双向数据绑定。 其实响应式原理是一种单向行为:它是数据...

    背景和一点点看法

    见网上许多文章讲vue双向数据绑定一开口就大谈 Object.definePropertyproxy。其实不然。这是vue中响应式的“基石”。
    vue 中有两个“特别的”概念:响应式双向数据绑定
    其实响应式原理是一种单向行为:它是数据到 DOM (也就是view视图)的映射;而真正的双向绑定,除了数据变化会引起 DOM 的变化之外,还应该在操作 DOM 改变后反过来影响数据的变化!

    vue 中提供了(内置的) v-model指令实现双向绑定。


    v-model和双向绑定的简单实现

    首先,v-model并不是可作用到任意标签,它只能在一些特定的表单标签如 inputselecttextarea以及自定义组件中使用。

    通常你会了解到 v-model其实只是一个语法糖,它实际是依靠v-bind:绑定响应式数据 & 触发 input 绑定事件并传递数据。
    这么说也可以:

    <input v-model="value">
    
    <!--可以认为等价于-->
    <input
      v-bind:value="value"
      v-on:input="value= $event.target.value"
    >
    

    我们用自定义组件和上面代码来实现一个类似v-model的数据绑定:

    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <div id="root"></div>
    <script type="text/javascript">
    	const component = {
    	    template: `
    	        <div>
    	            <input type="text" @input="handleInput">
    	        </div>
    	    `,
    	    methods: {
    	        handleInput (e) {
    	            this.$emit('input', e.target.value)
    	        }
    	    }
    	}
    
    	let vm = new Vue({
    	    conponents: {
    	        CompA: component
    	    },
    	    el: '#root',
    	    template: `
    	        <div>
    	            <comp-a></comp-a>
    	        </div>
    	    `
    	})
    </script>
    

    这样一个初始化的 demo 就搭建好了:

    • 我们定义了一个组件component,实例化了一个 Vue 对象。v-model绑定的值,是从外层的 Vue 实例中传进去的。
    • 首先我们要在组件 component 里面定义一个 props
    • 然后就可以在 Vue 实例的 template 模板里面去加上这个 value ,同时绑定input事件;
    • 同样,组件component里面的 input 也得绑定 value :

    我们将上面代码中script部分完善一下:

    const component = {
        props: ['value'],
        template: `
            <div>
                <input type="text" @input="handleInput" :value="value">
            </div>
        `,
        methods: {
            handleInput (e) {
                this.$emit('input', e.target.value)
            }
        }
    }
    
    let vm = new Vue({
        components: {
            CompA: component
        },
        el: '#root',
        template: `
    	    <div>
    	    	<div>{{value}}</div>
    	        <comp-a :value="value" @input="value= $event.target.value"></comp-a>
    	    </div>
    	`,
    	data () {
    	    return {
    	        value: 'mxcnb'
    	    }
    	},
    })
    

    2
    既然是双向绑定,我们不妨试着改变一下 value 的值:

    <button @click="handleInput">改变</button>
    
    handleInput(){
    	this.value='1231'
    },
    

    3
    嗯,确实改变了。

    vue双向绑定原理

    我们大概了解了:vue双向数据绑定的原理是通过 prop 向组件传递数据(对自定义组件来说就是:在数据渲染时使用 prop 渲染数据,将 prop 绑定到子组件自身的数据上);并监听自定义事件接受组件反传的数据并更新(对自定义组件来说就是:修改数据时更新自身数据来替代 prop ,监听子组件自身数据的改变,触发事件通知父组件更改绑定到prop的数据)。

    这里监听的事件对原生input组件来说就是内置的onUpdate:modelValue函数;对自定义组件来说就是自定义事件;
    通过 prop 传递的数据就是v-bind绑定的data;
    反传的数据就是用户输入后改变了的value;

    为了进一步体验“监听子组件数据”的过程,我们完全可以将上面 components 部分修改如下:

    const component = {
        props: ['value'],
        template: `
            <div>
                <input type="text" v-model="_value">
            </div>
        `,
        computed:{
        	_value:{
        		get(){
        			return this.value
        		},
        		set(value){
        			this.$emit('input', value)
        		}
        	}
        },
    }
    

    vue源码中做了什么

    仍然以开篇一段简单的代码说起:

    <input v-model="value">
    

    我们先看这个模板编译后生成的 render 函数:

    import { vModelText as _vModelText, createVNode as _createVNode, withDirectives as _withDirectives, openBlock as _openBlock, createBlock as _createBlock } from "vue"
    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return _withDirectives((_openBlock(), _createBlock("input", {
        "onUpdate:modelValue": $event => (_ctx.value = $event)
      }, null, 8 /* PROPS */, ["onUpdate:modelValue"])), [
        [_vModelText, _ctx.value]
      ])
    }
    

    可以看到,作用在 input 标签的 v-model 指令在编译后,除了使用 withDirectives 给这个 vnode 添加了 vModelText 指令对象外,还额外传递了一个名为 onUpdate:modelValue 的 prop,它的值是一个函数,这个函数就是用来更新变量 value 。

    我们来看 vModelText 的实现:

    const vModelText = {
      created(el, { value, modifiers: { lazy, trim, number } }, vnode) {
        el.value = value == null ? '' : value
        el._assign = getModelAssigner(vnode)
        const castToNumber = number || el.type === 'number'
        addEventListener(el, lazy ? 'change' : 'input', e => {
          if (e.target.composing)
            return
          let domValue = el.value
          if (trim) {
            domValue = domValue.trim()
          }
          else if (castToNumber) {
            domValue = toNumber(domValue)
          }
          el._assign(domValue)
        })
        if (trim) {
          addEventListener(el, 'change', () => {
            el.value = el.value.trim()
          })
        }
        if (!lazy) {
          addEventListener(el, 'compositionstart', onCompositionStart)
          addEventListener(el, 'compositionend', onCompositionEnd)
        }
      },
      beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
        el._assign = getModelAssigner(vnode)
        if (document.activeElement === el) {
          if (trim && el.value.trim() === value) {
            return
          }
          if ((number || el.type === 'number') && toNumber(el.value) === value) {
            return
          }
        }
        const newValue = value == null ? '' : value
        if (el.value !== newValue) {
          el.value = newValue
        }
      }
    }
    const getModelAssigner = (vnode) => {
      const fn = vnode.props['onUpdate:modelValue']
      return isArray(fn) ? value => invokeArrayFns(fn, value) : fn
    }
    function onCompositionStart(e) {
      e.target.composing = true
    }
    function onCompositionEnd(e) {
      const target = e.target
      if (target.composing) {
        target.composing = false
        trigger(target, 'input')
      }
    }
    

    这里我们最想关注的大概就是 created 函数了:第一个参数 el 是节点的 DOM 对象,第二个参数是 binding 对象,第三个参数 vnode 是节点的 vnode 对象。

    created 函数首先把 v-model 绑定的值 value 赋值给 el.value,这个就是数据到 DOM 的单向流动;
    接着通过 getModelAssigner 方法获取 props 中的 onUpdate:modelValue 属性对应的函数,赋值给 el._assign 属性;最后通过 addEventListener 来监听 input 标签的事件,它会根据是否配置 lazy 这个修饰符来决定监听 input 还是 change 事件。

    我们接着看这个事件监听函数,当用户手动输入一些数据触发事件的时候,会执行函数,并通过 el.value 获取 input 标签新的值,然后调用 el._assign 方法更新数据,这就是 DOM 到数据的流动。

    有趣的lazy修饰符

    如果配置了 lazy 修饰符,那么监听的是 input 的 change 事件,它不会在input输入框实时输入的时候触发,而会在 input 元素值改变且失去焦点的时候触发。

    如果不配置 lazy,监听的是 input 的 input 事件,它会在用户实时输入的时候触发。此外,还会多监听 compositionstartcompositionend 事件。

    1. 当用户在使用一些中文输入法的时候,会触发 compositionstart 事件,这个时候设置 e.target.composingtrue,这样虽然 input 事件触发了,但是 input 事件的回调函数里判断了 e.target.composing 的值,如果为 true 则直接返回,不会把 DOM 值赋值给数据。
    2. 然后当用户从输入法中确定选中了一些数据完成输入后,会触发 compositionend 事件,这个时候判断 e.target.composingtrue 的话则把它设置为 false,然后再手动触发元素的 input 事件,完成数据的赋值。

    这一点非常巧妙,笔者曾尝试这样实现:

    text.addEventListener("keydown",(e)=>{
    	// 一般情况下,按下中文情况下的字母、非空格、非shift键、非enter键或按下的不是数字键时,可以不及时响应
    	if(e.key=="Process" && e.code!="Enter" && e.code!="Space" && e.key!=" " && e.key!="Shift" && e.key!="Enter" && !Number.isNaN(e.key)){
    		composing=false;
    	}else{
    		composing=true;
    	}
    })
    text.addEventListener("input",(e)=>{
    	if(composing){
    		test.value=text.value
    	}
    })
    

    4

    展开全文
  • react实现双向数据绑定

    千次阅读 2019-03-21 11:28:10
    在使用vue的时候我们都知道,vue自身是双向数据绑定,所以使用自身带的v-model就可以实现双向数据的绑定,而react却是明摆的单向数据绑定,那么如何利用react实现类似的vue的双向数据绑定? 方法如下: import React...

    利用react实现类似vue的双向数据绑定的效果

    在使用vue的时候我们都知道,vue自身是双向数据绑定,所以使用自身带的v-model就可以实现双向数据的绑定,而react却是明摆的单向数据绑定,那么如何利用react实现类似的vue的双向数据绑定?

    方法如下:

    import React, { Component } from 'react'
    
    export default class componentName extends Component {
      constructor(props) {
        super(props)
        this.state = {
    			msg:''
        }
      }
      render() {
        return (
          <div>
                <input value={this.state.msg} onChange={this.inputChange}/>
                {this.state.msg} 
    
          </div>
        )
      }
        changeHandle=(e)=>{
            this.setState({
                msg:e.target.value
            })
        }
        inputChange=()=>{
            
        }
    }
    
    • 首先在input标签中绑定value={this.state.msg}然后在onChange中用setState设置为e.target.value实现了view影响model—》视图影响模型
    • 然后将{this.state.msg} 放在所对应的地方就可以实现model影响view
    • 用这样的方法就能实现双向数据绑定
    展开全文
  • 双向数据绑定{  双向数据绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是vue的精髓之处了。  }  怎么实现{    {{msg}}  data () {  return {...

    双向数据绑定{

            双向数据绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是vue的精髓之处了。

        }

        怎么实现{

            

                {{msg}}

            data () {

                return {

                  msg : '双向数据绑定'

              }

            }

        }

    展开全文
  • vuejs双向数据绑定

    千次阅读 2018-10-27 15:30:02
    那么什么是双向数据绑定?下面这张图可以很好的说明: 绑定的双方:view层的DOM和Model层的javascript对象。 第一层绑定:将javascript对象数据通过vuejs实现的规则绑定到DOM中。上代码: 这是从JavaScript...
  • Vue 双向数据绑定原理

    千次阅读 2019-03-07 14:20:57
    vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来...vue实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set...
  • html代码: <input type="text" id="a"> <div id="b"></div> js代码: var obj = {}; Object.defineProperty(obj,'hello',{ set:function (newVal) { document.getEle...
  • Vue双向数据绑定原理

    千次阅读 2021-04-13 00:21:16
    VUE双向数据绑定原理 vue双向数据绑定是通过 数据劫持,并结合 发布-订阅模式的方法来实现的,也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变 核心:关于vue实现双向数据...
  • 双向数据绑定原理

    千次阅读 2018-12-27 11:31:20
    数据劫持 VueJS 则使用 ES5 提供的 Object.defineProperty() 方法,监控对数据的操作,从而可以自动触发数据同步。 并且,由于是在不同的数据上触发同步,可以精确的将变更发送给绑定的视图,而不是对所有的数据都...
  • Vue:实现双向数据绑定

    千次阅读 2017-05-03 11:19:44
    javascript实现数据双向绑定的三种方式Vue实现双向数据绑定的方式Vue是如何实现双向数据绑定的呢?答案是前端数据劫持。其通过Object.defineProperty()方法,这个方法可以设置getter和setter函数,在setter函数中,...
  • vue双向数据绑定的原理

    万次阅读 2017-09-04 19:30:02
    有关双向数据绑定的原理 最近两次面试的时候,被问到了vue中双向数据绑定的原理,因为初学不精,只是使用而没有深入研究,所以答不出来。之后就在网上查找了别人写的博客,学习一下。 下面是博客园一篇博客,以及...
  • Angular4的双向数据绑定

    千次阅读 2017-11-20 20:42:26
    最近在学angular4,因为angularjs中默认是双向数据绑定,但是如果在比较复杂的页面使用的话会引起性能问题,那是因为angularjs会在页面保存一个所有数据绑定的列表,每当数据发生变化时,angularjs都会反复查看列表...
  • 详解单向数据流与双向数据绑定

    千次阅读 2019-06-06 17:54:58
    在学习和接触 Vue 的过程中,接触到 Vue 的两个特性,单向数据流与双向数据绑定,他们是什么,特点如何,以及彼此之间的关系和联系又有什么,接下来,我们深入的探究一下它们。 单向数据流 数据流,表明的是数据...
  • 模拟Vue实现双向数据绑定

    千次阅读 2019-11-07 22:15:20
    最近公司要让我写部分前端,学习了一下Vue,并整理成博客。 Vue的数据绑定一直是用的很爽的一个...下面是两个手写单向/双向数据绑定的例子,仅供参考。 单向绑定 <!DOCTYPE html> <html lang="en"> &l...
  • 原生JS双向数据绑定实现

    千次阅读 2018-07-31 18:44:01
    原生JS双向数据绑定实现点击下载 ... *@desc 实现可配置属性的双向数据绑定 *使用说明: *1.声明全局对象:如 * var test = { * topInfo: { * name:"张三", * age:18, * width:400 * } * }; *2....
  • v-mode 双向数据绑定

    千次阅读 2019-04-20 11:21:33
    v-mode 双向数据绑定 效果 数据改 , 视图更 视图改, 数据更 实现 使用v-model实现 缺点 v-model默认绑定value属性, 所以v-model只能在表单使用 原理 为什么数据能直接在视图显示 v-model默认绑定了DOM对象的...
  • 【AngularJs】Angular双向数据绑定

    万次阅读 2016-08-11 16:18:54
    1、什么是双向数据绑定双向数据绑定: Angular实现了双向绑定机制。所谓的双向绑定,无非是从界面的操作能实时反映到数据,数据的变更能实时展现到界面。即数据模型(Module)和视图(View)之间的双向绑定。例子...
  • GridView双向数据绑定

    千次阅读 2011-04-25 19:29:00
    GridView双向数据绑定
  • Vue.js(二) 双向数据绑定(数据驱动)

    千次阅读 2018-12-17 21:18:09
    Vue最核心的功能时双向数据绑定和组件模块化。 双向绑定: 当视图(View)的值发生改变时会自动更新model的值; 当model的值发生改变时会自动更新视图(View); 这里的视图View是指html中的标签元素,也就是DOM元素;...
  • DatePicker 实现双向数据绑定 不能使用v-model 只能用:value on-change是需要的,把当前选择的日期传给value format="yyyy-MM-dd" 是date字段传给后端的日期格式 <template> <DatePicker type="date...
  • 数据双向绑定浅析

    万次阅读 2018-08-14 14:39:17
    近期看到一篇文章关于jquerymy.js ,是一个关于数据双向绑定的库,具体源码有4000多行,差不多是JQUERY源码的一半,还没有慢慢细读,就想先把之前对于angular和vue的双向数据绑定给梳理一下。 数据绑定其实跟框架...
  • Angular双向数据绑定简易实现

    千次阅读 2015-04-29 15:18:23
    自己最近再看AngularJS,但想了解一下内部原理,于是找到了这篇非常好的文章。 ...和Ember.js数据双向绑定中动态设施setter和getter不同,脏治检查允许AngularJS监视那些存在或者不存在的变量。
  • vue双向数据绑定的原理解析

    千次阅读 多人点赞 2019-06-26 17:13:14
    简述     每当面试官问到Vue数据双向绑定原理的时候,...虽然一句话把大概原理概括了,但是其内部的实现方式还是值得深究的,本文就以通俗易懂的方式剖析 Vue 内部双向数据绑定原理的实现过程 思路    ...
  • AngularJs——双向数据绑定示例

    千次阅读 2016-02-21 16:34:04
    最近在Hybird App,接触到了AngularJs,感觉用起来蛮爽的,今天share下AngularJs的核心功能之一:双向数据绑定。 我们在页面中加入一个表单:  Two-way Binding demo
  • 使用databindings实现数据源与控件的绑定,但是当给数据源的行数据赋值或者给控件赋值时,界面上看不到值显示,有时候控件获得焦点时会显示值,有时候又不会,这是怎么回事呢? 绑定代码如下: ``` this.te_tstel...
  • AngularJS中的双向数据绑定

    千次阅读 2018-12-18 09:33:37
    双向数据绑定 双向数据绑定是指两个方向:从数据模型到视图,从视图到数据模型。AngularJS是一个MVC框架,控制器去修改数据模型,数据模型的变更会反应到视图上。视图上发生了数据的变化,是否能够自动同步到数据...
  • 理解VUE双向数据绑定原理和实现

    千次阅读 多人点赞 2021-02-26 12:04:02
    1.vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变; 2.核心:关于VUE双向数据绑定,其核心是 Object....
  • React阶段 - React双向数据绑定原理

    千次阅读 2020-09-10 10:34:46
    React双向数据绑定原理 如果已经学过Vue,并且深入了解过Vue的双向数据绑定的话,就会明白 Vue 2.0 双向数据绑定的核心其实是通过Object.defineProperty来实现的 但是 React 中是没有这个概念的,需要我们自己去...
  • angularJS 核心理念之 双向数据绑定

    千次阅读 2018-03-19 21:06:48
    双向数据绑定是angularJS的核心理念之一。单向数据绑定:单向数据即是将用于生成界面的模板与从服务器取得的数据结合,生成用于显示的html标签。比如El表达式中常见 ${变量名}以及{{}} ,它只提供从数据源到视图的单...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 415,619
精华内容 166,247
关键字:

如何做双向数据