xml地图|网站地图|网站标签 [设为首页] [加入收藏]

深入理解vue中的,Vue实现动态响应数据变化

来源:http://www.ccidsi.com 作者:集成介绍 人气:84 发布时间:2019-08-14
摘要:Vue是MVVM方式,即Model-View-ViewModel,通过绑定数据即能够实时改变视图展现。 一、vue中的响应式属性 澳门皇家国际,在我们使用vue进行支付的经过中,也许会遇见一种情形:当生成vue实

Vue是MVVM方式,即Model-View-ViewModel,通过绑定数据即能够实时改变视图展现。

一、vue中的响应式属性

澳门皇家国际,在我们使用vue进行支付的经过中,也许会遇见一种情形:当生成vue实例后,当再一次给多少赋值时,有的时候候并不会自动更新到视图上去;

比方:使用v-blink动态绑定属性

Vue中的数据完成响应式绑定

当我们去看vue文书档案的时候,会开掘有这么一句话:即便在实例创立之后添加新的质量到实例上,它不会触发视图更新。如下代码:

<div v-blink:class="property"></div>

1、对象完成响应式:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue $set</title>
<script src="https://static.jb51.net/assets/vue/1.0.11/vue.min.js"></script>
</head>
<body>
<div id="app">
 姓名:{{ name }}<br>
 年龄:{{age}}<br>
 性别:{{sex}}<br>
 说明:{{info.content}}
</div>
<!-- JavaScript 代码需要放在尾部(指定的HTML元素之后) -->
<script>
var data = {
 name: "脚本之家",
 age: '3',
 info: {
  content: 'my name is test'
 }
} 
var key = 'content';
var vm = new Vue({
 el:'#app',
 data: data,
 ready: function(){
  //Vue.set(data,'sex', '男')
  //this.$set('info.' key, 'what is this?');
 }
});
data.sex = '男';
</script>
</body>
</html>

行使v-html来绑定带有标签的剧情(会剖析标签)

是在开首化的时候利用definePrototype的定义set和get过滤器,在实行零部件模板编写翻译时落到实处water的监听搜罗重视项,当数码爆发变化时在set中通过调用dep.notify进行披露通报,完成视图的翻新。

运作结果:

<div v-blink:class="property" v-html="content"></div>

2、数组达成响应式:

姓名:脚本之家
年龄:3
性别:
说明:my name is test

选用v-text来绑定纯文本的剧情(标签会以文件的样式出口)

对于数组则是通过接二连三重写数组的主意splice、pop、push、shift、unshift、sort、reverse、等得以修改原数组的秘籍贯彻响应式的,不过透过length以及从来动用item[index]格局修改数组是不可能兑现响应式的改造dom(这种二种艺术涉及到数组的内部贯彻)。在数量更新后为了制止过度频仍的进展dom的操作,在vue中会将更新的dom实行批量操作,实际不是直接有多少更新就刷新dom,vue将急需创新的dom压入异步队列记性批量操作,升高品质。

缘何会如此呢?当去查对应文书档案时,你会发觉响应系统 ,把贰个平时Javascript 对象传给 Vue 实例来作为它的 data 选项,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter,如上演示,将data在调节台打印出来会开掘:

<div v-blink:class="property" v-text="content"></div>

上面具体的兑现,完毕原理大约如下:

澳门皇家国际 1

无论通过哪一种样式绑定,都亟需在Vue中的data中定义

澳门皇家国际 2    

在age及name都有get和set方法,不过在sex里面并未那七个措施,因而,设置了sex值后vue并不会自动更新视图;

var App = new Vue ({
 el: '#app',
 data: {
  property: '',
  content: '',
  example: [],
 }
 methods: {
 }
});

指标中贯彻双向数据绑定,能够直接在浏览器查看效果:

化解方法:

可是如若你必要在接来下的行事中使用到新的变量,只怕您发觉你转移已在data中定义的指标的值,不过视图却尚未动态变化。能够由此以下格局缓慢解决:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Two-way data-binding</title>
</head>
<body>

 <div id="app">
  <input type="text" v-model="text">
  {{ text }}
 </div>

 <script>
  function observe (obj, vm) {
   Object.keys(obj).forEach(function (key) {
    defineReactive(vm, key, obj[key]);
   });
  }

  function defineReactive (obj, key, val) {

   var dep = new Dep();

   Object.defineProperty(obj, key, {
    get: function () {
     // 添加订阅者watcher到主题对象Dep
     if (Dep.target) dep.addSub(Dep.target);
     return val
    },
    set: function (newVal) {
     if (newVal === val) return
     val = newVal;
     // 作为发布者发出通知
     dep.notify();
    }
   });
  }

  function nodeToFragment (node, vm) {
   var flag = document.createDocumentFragment();
   var child;

   while (child = node.firstChild) {
    compile(child, vm);
    flag.appendChild(child); // 将子节点劫持到文档片段中
   }

   return flag;
  }

  function compile (node, vm) {
   var reg = /{{(.*)}}/;
   // 节点类型为元素
   if (node.nodeType === 1) {
    var attr = node.attributes;
    // 解析属性
    for (var i = 0; i < attr.length; i  ) {
     if (attr[i].nodeName == 'v-model') {
      var name = attr[i].nodeValue; // 获取v-model绑定的属性名
      node.addEventListener('input', function (e) {
       // 给相应的data属性赋值,进而触发该属性的set方法
       vm[name] = e.target.value;
      });
      node.value = vm[name]; // 将data的值赋给该node
      node.removeAttribute('v-model');
     }
    };

    new Watcher(vm, node, name, 'input');
   }
   // 节点类型为text
   if (node.nodeType === 3) {
    if (reg.test(node.nodeValue)) {
     var name = RegExp.$1; // 获取匹配到的字符串
     name = name.trim();

     new Watcher(vm, node, name, 'text');
    }
   }
  }

  function Watcher (vm, node, name, nodeType) {
   Dep.target = this;
   this.name = name;
   this.node = node;
   this.vm = vm;
   this.nodeType = nodeType;
   this.update();
   Dep.target = null;
  }

  Watcher.prototype = {
   update: function () {
    this.get();
    if (this.nodeType == 'text') {
     this.node.nodeValue = this.value;
    }
    if (this.nodeType == 'input') {
     this.node.value = this.value;
    }
   },
   // 获取data中的属性值
   get: function () {
    this.value = this.vm[this.name]; // 触发相应属性的get
   }
  }

  function Dep () {
   this.subs = []
  }

  Dep.prototype = {
   addSub: function(sub) {
    this.subs.push(sub);
   },

   notify: function() {
    this.subs.forEach(function(sub) {
     sub.update();
    });
   }
  };

  function Vue (options) {
   this.data = options.data;
   var data = this.data;

   observe(data, this);

   var id = options.el;
   var dom = nodeToFragment(document.getElementById(id), this);

   // 编译完成后,将dom返回到app中
   document.getElementById(id).appendChild(dom); 
  }

  var vm = new Vue({
   el: 'app',
   data: {
    text: 'hello world'
   }
  });

 </script>

</body>
</html>
<script>
var data = {
 name: "脚本之家",
 age: '3',
 info: {
  content: 'my name is test'
 }
} 
var key = 'content';
new Vue({
 el:'#app',
 data: data,
 ready: function(){
  Vue.set(data,'sex', '男');
  this.$set('info.' key, 'what is this?');
 }
});
</script>

本文由68399皇家赌场发布于集成介绍,转载请注明出处:深入理解vue中的,Vue实现动态响应数据变化

关键词: 68399皇家赌场

上一篇:正则表达式匹配末尾数字并

下一篇:没有了

最火资讯