问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何用MVVM来实现绑定和显示TreeView控件

发布网友 发布时间:2022-05-10 04:53

我来回答

2个回答

懂视网 时间:2022-05-15 02:42

这次给大家带来怎样在实战项目中进行mvvm-simple双向绑定,在实战项目中进行mvvm-simple双向绑定的注意事项有哪些,下面就是实战案例,一起来看一下。

mvvm模式解放DOM枷锁

mvvm原理分析

JavaScript在浏览器中操作HTML经历了几个不同阶段

第一阶段 直接用浏览器提供的原生API操作DOM元素

var dom = document.getElementById('id');
dom.innerHTML = 'hello mvvm';

第二阶段 jQuery的出现解决了原生API的复杂性和浏览器间的兼容性等问题,提供了更加简易方便的API

$('#id').text('hello mvvm')

第三阶段 MVC模式使前端可以和后端配合,修改服务端渲染后的页面内容

而随着产品对于用户体验的重视,交互体验越来越重要,仅用jQuery远远不够。 MVVM模型解决了频繁操作的痛点,Model-View-ViewModel模式将数据与视图的同步交由ViewModel完成

jQuery修改节点内容:

<p>name: <span id="name">vist</span>!</p>
<p>age: <span id="age">25</span>.</p>
var name = 'bestvist';
var age = 26;
$('#name').text(name);
$('#age').text(age);

MVVM模式下只需要关注数据结构:

var me = {
 name: 'vist',
 age: 25
}

修改相应属性就好

me.name = 'bestvist';
me.age = 26;

mvvm实现

mvvm实现数据绑定的几种方式:

  1. 发布-订阅模式

  2. 脏值检查

  3. 数据劫持

比较流行的vue采用的就是数据劫持和发布-订阅模式,通过劫持es5提供的Object.defineProperty()中各个属性的get,set方法, 数据更新时触发消息给订阅者,实现数据绑定功能。

Object.defineProperty(obj, prop, descriptor)方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性,并返回这个对象。 该方法接受3个参数:

  • obj 定义属性的对象。

  • prop 被定义或修改的属性名。

  • descriptor 被定义或修改的属性的描述符。

  • 一般情况通过直接给对象属性赋值来创建属性或者修改对应属性,而使用Object.defineProperty可以修改对象属性的一些额外默认配置。 如:

    const obj = {name: 'Tom'};
    Object.defineProperty(obj, 'name', {
     get: function(val) {
     return 'Jerry'; 
     }
    })
    console.log(obj.name);
    //
    输出: Jerry

    Object.defineProperty详细解释,请戳这里

    mvvm实现的主要流程:

  • 数据代理,访问实例上的属性时直接返回对应data里的属性

  • 数据监听,对实例上的属性监听,如果数据改变通知订阅者更新

  • 指令解析,对每个元素节点进行解析,替换数据并绑定更新函数

  • 链接数据监听和指令解析,保证每个数据的更新,指令解析都可以获取并更新视图

  • 实例化类:

    new MVVM({
     el: '#app',
     data() {
     return {
     message: 'hello mvvm'
     }
     }
    })

    数据代理:

    class MVVM {
     constructor(options) {
     this.$options = options || {};
     let data = this._data = this.$options.data();
     // 数据代理 vm.xxx => vm._data.xxx
     Object.keys(data).forEach(key => {
     this._proxyData(key);
     });
     // observe(data, this);
     // this.$compile = new Compile(options.el || document.body, this);
     }
     _proxyData(key) {
     Object.defineProperty(this, key, {
     configurable: true,
     enumerable: true,
     get: () => {
     return this._data[key];
     },
     set: newVal => {
     this._data[key] = newVal;
     }
     });
     }
    }

    数据监听,劫持实例属性更新

    class Observer {
     constructor(data) {
     this.data = data;
     Object.keys(this.data).forEach(key => {
     this.defineReactive(key, this.data[key]);
     })
     }
     // 定义反应
     defineReactive(key, val) {
     let dep = new Dep();
     Object.defineProperty(this.data, key, {
     enumerable: true,
     configurable: false,
     get: () => {
     return val;
     },
     set: newVal => {
     if (val === newVal) {
      return;
     }
     val = newVal;
     // 赋值对象再进行劫持
     observe(val);
     ... // 数据修改通知
     }
     })
     }
    }
    function observe(val) {
     if (!val || typeof val !== 'object') {
     return;
     }
     return new Observer(val);
    }

    指令解析部分代码

    class Compile {
     constructor(el, vm) {
     this.$vm = vm;
     this.$el = this.isElementNode(el) ? el : document.querySelector(el);
     if (this.$el) {
     this.$fragment = this.node2Fragment(this.$el);
     this.init();
     this.$el.appendChild(this.$fragment);
     }
     }
     init() {
     this.compileElement(this.$fragment);
     }
     node2Fragment(el) {
     let fragment = document.createDocumentFragment(), child;
     // 原生节点拷贝到fragment
     while (child = el.firstChild) {
     // appendChild将元素从dom上移到fragment
     fragment.appendChild(child);
     }
     return fragment;
     }
     compileElement(el) {
     let childNodes = el.childNodes;
     [].slice.call(childNodes).forEach(node => {
     let text = node.textContent;
     let reg = /{{(.*)}}/;
     if (this.isElementNode(node)) {
     this.compile(node);
     } else if (this.isTextNode(node) && reg.test(text)) {
     this.compileText(node, RegExp.$1);
     }
     if (node.childNodes && node.childNodes.length) {
     this.compileElement(node);
     }
     })
     }
    }

    其中

    while (child = el.firstChild) {
     // appendChild将元素从dom上移到fragment
     fragment.appendChild(child);
    }

    通过appendChild改变原dom结构特点,逐步把dom元素节点移到fragment中。

    相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

    推荐阅读:

    怎样对json对象排序并删除相同id数据

    怎样操作JS读取xml内容并输出到div内

    热心网友 时间:2022-05-14 23:50

    有用过MVVM的朋友,都知道我们在项目中需要定义Model和ViewModel。
    Model指的是数据实体,它负责存储数据,并且提供了与外部资源(例如数据库或者远程服务)的交互。
    ViewModel是指View与Model之间的一个桥梁,通常情况下,View是指界面(例如WPF中的Window,或者Silverlight中的Page等等),
    使用MVVM的核心目的是让View的设计能够更加独立,它不应该包含太多的数据逻辑。
    极端情况下,它不应该有一行自定义代码。那么,你可能会问,不用代码怎么显示和更新数据呢?答案就是,View通过绑定
    (Binding)连接到ViewModel,在WPF和Silverlight中都可以实现双向(TwoWay)的绑定。这样就能实现数据的显示和更新。
    同时,ViewModel中还可以公开一些Command,以便可以让View中的特殊操作可以绑定。——这就是MVVM的核心理论
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    ...爱你你是我的罗密欧 , 我愿意变成你的朱丽叶' 谁知 有句歌词是“我爱你你是我的朱丽叶,我愿意变成你的梁山伯”是哪... 为什么打印出来的文档页码和原来的不一样 ...两台电脑用路由器上网一台是W7一台是XP如何实现两台电脑共享文件 win7怎么联另一台电脑win7怎么让网络和另一台电脑共享 w7的系统怎么共享电脑w7系统里面文件怎么共享另一台电脑 共享win7电脑w7系统里面文件怎么共享另一台电脑 翡翠有收藏价值吗,我们玩家如何去投资 价格一两万元的翡翠如何挑选 ppt怎么转换成视频?简单四步法,轻松搞定ppt微课录制 校园小说人物名字 要好听 唯美的天龙八部名字有哪些? 我在辽阳市旅游局上班(今年9月份上岗的)求一份个人工作总结! 旅游社地接部个人年终总结 小额贷款相关法律 小额贷款非法经营罪立案标准 滴滴快车的使用方法 身边小人与贵人 怎样识别最容易 成语精神抖什么 精神抖擞等成语 该怎么对待身边小人?毫无接触,躲在暗处逢人就败坏我的声誉 抖擞抖擞精神下一句 抖擞精神 是不是成语 精神抖擞是不是成语 精神抖擞是成语 精神抖擞是成语吗? 精神抖擞是成语么? 精神抖擞是成语吗 为什么空调制冷时,制冷剂少,室内交换机大部分结冰 抖擞精神算不算成语 急求:网王 若爱匪惜 的全文 ,全文啊。【或者76章以后】 帮帮忙,谢谢啦,可以发到fengmeijun123@126.com wpf treeview不用wvvm 怎么绑定图片 vs2010中treeview控件绑定数据winform界面怎么绑定?要求有例子和代码 wpf treeview判断是否有节点 C#中treeview要把一个父节点以及父节点以下的所有的子节点,一次性拖到另一个节点下面应该怎么写? 魅族mx4pro手机接收wifi信号不好是怎么回事? 魅族手机信号不好是通病吗 魅族mx4pro信号接受差的原因是什么? 仿句:白的如雪,粉的像霞,红的似火,黄的胜金,整个草原像一座五彩缤纷的大花园 “大沙漠如雪”的下一句是什么? 燕山鹅毛大如雪什么意思 燕山雪花真的大如雪吗? Iphone6无法连接到iTunes Store? 学生养成好习惯的意义 iPhone6白苹果iTunes刷机怎么办 甜糯米酒的做法 最正宗的做法 “宗”字开头的成语有哪些? 宗字开头的成语有哪些 以宗开头的成语 宗开头的成语有哪些