鲜之友微信小程序_vue双向绑定及观察者模式详解

  • 栏目:公司新闻 时间:2021-01-07 15:06 分享新闻到:
<返回列表

vue双向绑定及观察者模式详解       这篇文章主要介绍了vue双向绑定及观察者模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在Vue中,使用了Object.defineProterty()这个函数来实现双向绑定,这也就是为什么Vue不兼容IE8

1 响应式原理

让我们先从相应式原理开始。我们可以通过Object.defineProterty()来自定义Object的getter和setter 从而达到我们的目的。

代码如下

function observe(value, cb) {
 Object.keys(value).forEach((key) = defineReactive(value, key, value[key] , cb))
function defineReactive (obj, key, val, cb) {
 Object.defineProperty(obj, key, {
 enumerable: true,
 configurable: true,
 get: ()= {
 /*....依赖收集等....*/
 /*Github:answershuto*/
 return val
 set:newVal= {
 val = newVal;
 cb();/*订阅者收到消息的回调*/
class Vue {
 constructor(options) {
 this._data = options.data;
 observe(this._data, options.render)
let app = new Vue({
 el: '#app',
 data: {
 text: 'text',
 text2: 'text2'
 render(){
 console.log("render");

通过observe函数对app.data上的每一个key和value都设定getter和setter。当value改变的时候触发setter,就会触发render这个函数。响应式的目的就达成,如果是视图更新的话我们通过监听dom的input事件来触发数据更新
但是现在我们只有在改变vue._data.text的时候才会触发他们的setter,但是我想偷懒,只改变vue.text就能触发到setter怎么做呢?

我们使用代理的方法

_proxy.call(this, options.data);/*构造函数中*/
/*代理*/
function _proxy (data) {
 const that = this;
 Object.keys(data).forEach(key = {
 Object.defineProperty(that, key, {
 configurable: true,
 enumerable: true,
 get: function proxyGetter () {
 return that._data[key];
 set: function proxySetter (val) {
 that._data[key] = val;

依赖收集

让我们再来看看下面的代码

new Vue({
 template: 
 ` div 
 span text1: /span {{text1}}
 span text2: /span {{text2}}
 div `,
 data: {
 text1: 'text1',
 text2: 'text2',
 text3: 'text3'
});

当你的text3变化的时候,实际上text3并没有被渲染,但是也会触发一次render函数,这显然是不对的。所以我们需要收集依赖。

我们只需要在初始化的时候渲染一遍,那所有渲染所依赖的数据都会被触发getter,这时候我们只要把这个数据放到一个列表里就好啦!

我们先来认识一下Dep(dependencies)这个类,下图是一个最简单的Dep类。我们可以把他理解为发布者(这点很重要!!)

class Dep {
 constructor () {
 this.subs = [];
 addSub (sub: Watcher) {
 this.subs.push(sub)
 removeSub (sub: Watcher) {
 remove(this.subs, sub)
 /*Github:answershuto*/
 notify () {
 // stabilize the subscriber list first
 const subs = this.subs.slice()
 for (let i = 0, l = subs.length; i i++) {
 subs[i].update()
function remove (arr, item) {
 if (arr.length) {
 const index = arr.indexOf(item)
 if (index -1) {
 return arr.splice(index, 1)

我们每次触发getter的时候,只要把触发的对象放到dep.sub里面就好啦!
但是现在问题来了,我们用什么来装这个触发的'对象',也可以说式订阅者呢

我们使用Watcher这个类

class Watcher {
 constructor (vm, expOrFn, cb, options) {
 this.cb = cb;
 this.vm = vm;
 /*在这里将观察者本身赋值给全局的target,只有被target标记过的才会进行依赖收集*/
 Dep.target = this;
 /*Github:answershuto*/
 /*触发渲染操作进行依赖收集*/
 this.cb.call(this.vm);
 update () {
 this.cb.call(this.vm);

vm即是vue实例, expOrFn就是{{a+b}}里面的a+b, cb就是回调函数就是return a+b, options是一些配置项。

Vue在第一次渲染列表的时候如果碰到{{xxx}}这样的表达式,就会new Watcher()。解析里面的函数,然后把当前的watcher实例赋给Dep.target(Dep.target是全局的,一次性只能有一个存在,因为Vue一次只处理一个依赖)。然后执行回调函数。(这里看似是执行回调函数渲染,其实又触发了一次getter,然后就会把当前的依赖添加到sub里去)

接下来开始依赖收集

class Vue {
 constructor(options) {
 this._data = options.data;
 observer(this._data, options.render);
 let watcher = new Watcher(this, );
function defineReactive (obj, key, val, cb) {
 /*在闭包内存储一个Dep对象*/
 const dep = new Dep();
 Object.defineProperty(obj, key, {
 enumerable: true,
 configurable: true,
 get: ()= {
 if (Dep.target) {
 /*Watcher对象存在全局的Dep.target中*/
 dep.addSub(Dep.target);
 set:newVal= {
 /*只有之前addSub中的函数才会触发*/
 dep.notify();
Dep.target = null; //防止依赖重复添加

这儿我们通过示例来讲解

 template 
 div 
 {{a+b}}
 /div 
 div 
 {{a-c}}
 /div 
 /template 
 script 
let app = new Vue( {
 data :{
 a: 1,
 b: 2,
 c: 3
 })

我们编译到{{a+b}},会去实例化一个对应的Watcher对象,Watcher的构造函数中有这么一句

this.cb.call(this.vm);this.cb指的是function(){return a+b};this.vm指的是这个vue对象,这样就会触发vue.a和vue.b的getter方法,a,b都有自己的dep对象,我们通过Dep.target将这个Watcher对象就加到dep的subs数组中去了,当我们变更a或者b是就会触发setter,进而触发subs数组中的update方法,视图中的a+b就会更新

有个小知识点:我们新建一个属性对象时必须通过Vue.set的方法去实现,而不能直接通过=实现,这样会检测不到,因为我们在初始化时就通过defineProperty重构了这个对象属性的getter和setter方法,新建的属性则没有所以不会被检测到

下图为Vue框架在数据初始化中使用观察者模式的示意图:

以上所述是小编给大家介绍的vue双向绑定及观察者模式详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对凡科网站的支持!


分享新闻到:

更多阅读

鲜之友微信小程序_vue双向绑定及观察者模

公司新闻 2021-01-07
vue双重关联及观查者方式详细说明 本文关键详细介绍了vue双重关联及观查者方式,原文...
查看全文

抽奖小程序是什么_echarts统计x轴区间的数

公司新闻 2021-01-07
echarts统计分析x轴区段的标值案例编码详细说明 本文关键详细介绍了echarts统计分析x轴区...
查看全文

网站优化-企业网站建设,微信小程序制作

公司新闻 2021-01-07
商品,根据国际性全新的SaaS(Software as a Service)方式,以技术专业的Saas服务宗旨,致力于于...
查看全文
返回全部新闻


区域站点: 南丰县建站培训   南宫市建站程序   囊谦县凡科建站   南和县企业建站   南华县建站培训   南江县建站程序   南京市凡科建站   南靖县企业建站   南康市建站培训   南乐县建站程序   南陵县凡科建站   南宁市企业建站   南平市建站培训   南皮县建站程序   南市区凡科建站   南通市企业建站   南投县建站培训   南雄市建站程序   南溪县凡科建站   南阳市企业建站   南漳县建站培训   南召县建站程序   南郑县凡科建站   那坡县企业建站   那曲县建站培训   纳雍县建站程序   讷河市凡科建站   内黄县企业建站   内江市建站培训   内丘县建站程序   内乡县凡科建站   嫩江市企业建站   聂荣县建站培训   尼玛县建站程序   尼木县凡科建站   宁安市企业建站   宁波市建站培训   宁城县建站程序   宁德市凡科建站   宁都县企业建站   宁国市建站培训   宁海县建站程序   宁化县凡科建站   宁晋县企业建站   宁陵县建站培训   宁明县建站程序   宁南县凡科建站   宁强县企业建站   宁陕县建站培训   宁武县建站程序   宁乡市凡科建站   宁阳县企业建站   宁远县建站培训   农安县建站程序   磐安县凡科建站   盘锦市企业建站   盘山县建站培训   磐石市建站程序   盘州市凡科建站   蓬安县企业建站   澎湖县建站培训   蓬莱市建站程序   彭山县凡科建站   蓬溪县企业建站   彭阳县建站培训   彭泽县建站程序   彭州市凡科建站   偏关县企业建站   平安县建站培训   平昌县建站程序   平定县凡科建站   屏东县企业建站   平度市建站培训   平果县建站程序   平和县凡科建站   平湖市企业建站   平江县建站培训   平乐县建站程序   平凉市凡科建站   平利县企业建站   平罗县建站培训   平陆县建站程序   屏南县凡科建站   平泉市企业建站   屏山县建站培训   平顺县建站程序   平塘县凡科建站   平潭县企业建站   平武县建站培训   萍乡市建站程序   平乡县凡科建站   平阳县企业建站   平遥县建站培训   平阴县建站程序   平邑县凡科建站   平远县企业建站   平舆县建站培训   皮山县建站程序   普安县凡科建站   浦北县企业建站   浦城县建站培训   普洱市建站程序   普格县凡科建站   浦江县企业建站   普兰县建站培训   普宁市建站程序   莆田市凡科建站   迁安市企业建站   乾安县建站培训   潜江市建站程序   潜山市凡科建站  

友情链接: 医慧互通 创建网站教程 巴渝烤哥 美国免费建站平台 免费网页建站 免费自助建站

Copyright © 2002-2020 凡科建站_企业建站_建站培训_建站程序_自建网站 版权所有 (网站地图) 备案号:粤ICP备10235580号