-
2021-05-12 17:49:57
方法1:用
$forceUpdate
直接在需要更新得地方加入$forceUpdate
如:methods:{ updateName(){ this.userInfo.name='小红'//在此时,确实已经将userInfo对象修改完成 console.log(this.userInfo.name);//输出结果: 小红 this.$forceUpdate();//在这里,强制刷新之后,页面的结果变为'小红' } }
方法2:用
$set
this.$set(this.userInfo,'name','小红') //第一个参数传要更新得父级 第二个参数为字符串得子级,第三个参数为具体数值
个人比较推荐用
$set
方法,$forceUpdate
方法对资源消耗比较大更多相关内容 -
vue如何从接口请求数据
2020-12-29 01:34:29这两天学习了vue如何从接口请求数据,所以,今天添加一点小笔记。获取图片列表 var demo=new Vue({el:'#app',data: {imgList:[],getImgUrl: '' //存数据接口},created: function(){this.getImg() //定义方法},...这两天学习了vue如何从接口请求数据,所以,今天添加一点小笔记。
获取图片列表var demo=new Vue({
el:'#app',
data: {
imgList:[],
getImgUrl: '' //存数据接口
},
created: function(){
this.getImg() //定义方法
},
methods: {
getImg: function(){
var that = this;
that.$http({ //调用接口
method:'GET',
url:this.getImgUrl //this指data
}).then(function(response){ //接口返回数据
this.imgList=response.data;
},function(error){
})
}
}
})
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
时间: 2017-06-19
-
Vue 数据双向响应机制
2020-06-30 11:51:42Vue 中数据双向响应的机制 参考资料(感谢各位前辈的分享和资料) 尤雨溪讲解 Vue 源码 Vue 源码解析-Vue 中文社区 小马哥 Vue 源码解析 小马哥 Vue 源码解析代码示范 vue-cli 源码 MDN Vue 的特点是数据驱动视图,...Vue 数据双向响应机制
博主wx:
-GuanEr-
,加博主进前端交流群参考资料(感谢各位前辈的分享和资料)
尤雨溪讲解 Vue 源码
Vue 源码解析-Vue 中文社区
小马哥 Vue 源码解析
小马哥 Vue 源码解析代码示范
vue-cli 源码
MDN
Vue 的特点是数据驱动视图,也就是说,数据变化时视图随之变化, 所以要先监听到数据的变化,然后再去响应依赖该数据的视图,Vue 使用 Object 的 defineProperty 函数劫持数据的变化,用 Complite 源码解析器解析我们编写的 Vue 代码, 用 Dep 类收集数据依赖,使用 Watcher 类响应数据变化并更新视图。
一、
Complite
源码解析器因为要结合
Watcher
,所以Complite
只在这里做简单的介绍,如果有时间单独写一篇.我们在
.vue
的文件中编写的代码,或者创建Vue
实例后编写的代码,部分如指令、函数,直接在DOM
中渲染调用并计算变量等是不被浏览器直接识别和解析的,所以在代码正常渲染在浏览器并执行业务逻辑之前,Vue
要先将我们的代码进行编译。编译流程如下(来自 Vue 中文社区 Vue 源码解析,全文链接在文章开头):
我们编写的Vue
实例的结构代码其实是一个字符串,这个字符串被Vue
的Complite
源码解析器编译成抽象语法数AST
(DOM 节点及属性以对象嵌套的形式存在),然后根据AST
为每个节点生成对应的render
函数,调用某个节点的render
函数就能形成对应的VNode
。Complite
除了要要编译源码之外,还要捕获数据变化,也就是绑定Watcher
,然后根据Watcher
类的,更新视图。二、
Observer
类1.
Object.defineProperty
函数 (Object.defineProperty(obj, key, desc);
)- 为一个对象添加属性,或者修改对象已有的属性,并返回这个对象。
- 由
Object
构造器直接调用,对象的实例不能调用。 - 接受三个参数,
obj
指要操作属性的源对象,key
指要操作的这个属性,desc
指要操作的属性的描述对象。 - 可以定义
Symbol
类型的数据作为key
。 - 对象属性的描述中,非常重要的两个函数
get
和set
。 - 更具体的内容,MDN 上有非常详细的说明,建议一看。
Object.defineProperty(obj, 'foo', { get() { // 每当 obj 访问 foo 属性时,get 函数会自动执行 // 不传入参数,会传入 this,但是 this 不一定指向 obj // 该函数的返回值会被当做是 foo 的属性值 }, set(newVal) { // 当 foo 属性值被修改时,set 函数会自动执行 // 接受一个参数 newVal,是为 foo 赋的新值 // 会传入 赋值时的 this 对象 } });
2.
Object.defineProperty
函数和vue-cli
的关联在
Vue
中,一个组件是一个VueComponent
实例,每个实例有自己的$data
对象,其中存储的是当前组件的数据列表,要让每个数据动态响应,就需要为每个数据添加get
和set
,来劫持数据值的改变。// 为指定对象的每个键添加 setter 和 getter function covert(obj) { const keyList = Object.keys(obj); keyList.forEach(key => { // _val 如果该属性已经存在,就是上一次的赋值,不存在为undifined // 每个 key 的操作都会形成一个闭包,所以这个闭包就成了单独存储对象某个属性值(_val)的位置 let _val = obj[key]; Object.defineProperty(obj, key, { get() { // 在这里可以捕获到属性的变化,并限制取值操作,如果 return 一个固定值,那么 obj 的某个键就永远是这个值,重新赋值也没用 return _val; }, set(val) { // 这里可以对比属性的新旧值,并限制赋值操作 _val = val; } }); }); } // ----------------------------------------------- // 调用 const data = { visible: true, num: 10 }; covert(data); // 为 data 的两个属性绑定 get 和 set data.visible = false; // 调用 set console.log(data.visible); // 调用 get
3.
vue-cli
源码中的Observer
类简介(极简)class Observer { value: any; dep: Dep; vmCount: number; constructor (value: any) { this.value = value this.dep = new Dep() this.vmCount = 0 def(value, '__ob__', this) if (Array.isArray(value)) { // 数组的另一套劫持方式 } else { this.walk(value) } } walk (obj: Object) { // 为每个键绑定 get 和 set const keys = Object.keys(obj) for (let i = 0; i < keys.length; i++) { defineReactive(obj, keys[i]) } } observeArray (items: Array<any>) { // 数组的特殊操作:由于数组数据类型的特殊性,数组的整体值的变更和劫持依旧在 set 和 get 中 // 但是 vue 为 Array 这个类的原型函数们添加了劫持,也就是说当数组的值发生改变时,要调用原型函数之前,先处理我们需要的业务操作 } } // ---------------------------------------------------------------- function defineReactive ( obj: Object, key: string, val: any, customSetter?: ?Function, shallow?: boolean ) { ... let childOb = !shallow && observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { ... }, set: function reactiveSetter (newVal) { ... } }) }
三、
Dep
类通过
Observer
类为数据们添加了getter
和setter
之后,就能观察到数据的变化,同时我们要改变跟这个数据有关系的一系列内容,可能是其他数据,也可能是页面渲染的内容。那我们就需要知道使用到这个数据的都有谁,才可以在当前数据变化时通知他们做响应。1. 依赖、依赖收集和通知依赖
- 某个数据
A
直接控制的内容,或者通过A
计算得到的内容,都被称为依赖了A
。 - 都有谁依赖了
A
,需要一个准确的计量,才能在A
每次改变时,执行对应的操作,这种计量方式是一个数组,因为依赖A
的数据很可能有多个。 - 确定谁依赖了数据
A
,并将这些依赖收集起来:依赖数据A
一定要获取数据A
,所以在A
的getter
中,做依赖收集。 - 数据
A
每次发生值的改变时,setter
会执行,所以在A
的setter
中通知依赖。
2. 依赖的操作
依赖可能被添加,也有可能伴随着组件卸载、销毁而被删除,所以依赖除了要被声明之外,还要有其他操作,依赖类
Dep
就是用来为每个数据创建依赖并处理依赖的。3.
vue-cli
中的Dep
类... let uid = 0 class Dep { static target: ?Watcher; // 静态属性,Dep 构造器访问,Dep 的实例不能访问 id: number; // 每个 Dep 实例唯一的id subs: Array<Watcher>; constructor () { this.id = uid++ // 某个数据的依赖列表 this.subs = [] } addSub (sub: Watcher) { this.subs.push(sub) } removeSub (sub: Watcher) { remove(this.subs, sub) } depend () { if (Dep.target) { Dep.target.addDep(this) } } notify () { const subs = this.subs.slice() if (process.env.NODE_ENV !== 'production' && !config.async) { subs.sort((a, b) => a.id - b.id) } // 当某个数据的值发生变化时,要循环这个数据的依赖列表,并且让他们相关的所有操作都更新一次 for (let i = 0, l = subs.length; i < l; i++) { subs[i].update() } } } ...
4.
Observer
中调用Dep
(简写)class Observer { constructor() { this.dep = new Dep(); } ... } function defineReactive() { Object.defineProperty(obj, key, { get() { // get 被调用一次,都代表有一个数据依赖于当前数据,要向当前数据的依赖列表 subs 中添加一个依赖 dep.depend() ... }, set() { // set 被调用且值发生改变时,代表当前数据更新,那么依赖于当前数据的所有内容都要发生对应变化 dep.notify() ... } ... }); }
四、
Watcher
类上面的
Dep
类只是对数据的依赖进行管理的一套方式,从Dep
的源码中我们可以捕捉到,真正的被添加到subs
数组中的依赖是Watcher
。1. 什么是
Watcher
某个表达式
Express
,用到到了某个数据A
,我们就说Express
订阅了A
,为了能让这个Express
在A
每次发生变化时,都能动态的重新计算自己,我们就为它编写一个update
方法来更新自己并做后续的数据渲染。每次A
变化,都通知Express
让它update
。在
Vue
中,到处都是这样的订阅与响应,所以产生了Watcher
类,专门处理数据变化之后其依赖们的响应动作。2.
Watcher
需要具备的功能以下三点来自小马哥源码解析及总结
- 在自身实例化时往属性订阅器(
dep
)里面添加自己。 - 自身必须有一个
update()
方法。 - 待属性变动
dep.notify()
通知时,能调用自身的update()
方法,并触发Compile中绑定的回调,则功成身退。
3. 结合
Observer
和Dep
,整个数据双向响应流程如下:- 数据初始化,初始化了
dep
属性,继承了Dep
类的subs
属性,来承接依赖列表; - 为数据绑定了
getter
和setter
; - 数据每次被调用都代表被订阅,
getter
返回数据值的同时,向subs
数组中添加了一个Watcher
; - 数据值发生改变,调用
setter
,setter
设置数据值的同时,调用Dep
提供的notify
函数,来通知该数据的依赖做出响应; notify
函数内部遍历依赖列表(即订阅者Watcher
列表)subs
数组,调用每个订阅者的update
函数,让其根绝数据新的值重新计算自己。
扫码拉你进入前端技术交流群 -
【vue】vue从服务端获取数据赋值给data,如何渲染更新视图
2019-03-28 13:37:29从服务端取到的数据需要实时反馈,否则将毫无意义! 目录 介绍一下Vue.set()方法 一:data中定义一个对象: 二:从服务端发起请求返回新数据对象: 三:用 Vue.set()方法更新数据 下面介绍一下第二种情况:...从服务端取到的数据需要实时反馈,否则将毫无意义!
目录
我先介绍一下Vue.set()方法
注:如果从服务端返回的数据量较少,或者只有几个字段,可以用vue的set方法,如果数据量较大,请直接看第二种情况。
官网API是这样介绍的:
Vue.set(target,key,value)
参数:
{Object | Array} target
{string | number} key
{any} value
返回值:设置完后的新值
用法:
向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi')
注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。
我举个简单的小例子,把这种用法介绍一下:
一:data中定义一个对象:
data() { return { person:{ age:10, name:'李古拉雷', sex:1 } } }
二:从服务端发起请求返回新数据对象:
person:{ age:20, name:'高圆圆', sex:0 }
这时需要把这个对象实时渲染到页面中去
三:用 Vue.set()方法更新数据
如下所示:
methods: { getPerson(){ this.$http({ method: "post", url:this.$$baseURL + "sys/getPerson", }).then(res => { Vue.set(this.person,0,{age:res.data.age,name:res.data.name,sex:res.data.sex}) /** * 0 更新的是位置0上的数据 * */ }); } }
这样从服务端返回的新数据就实时更新到组件上了。
******************************以上(Vue.set()使用方法)*****************************************
下面我说一下第二种情况:
这种情况就是数据量较大,字段较多的,使用Vue.set()方法就有点过分了,这时我们应该怎么做呢?
核心思想就是定义一个临时变量,因computed 是计算属性,这里面的值更新可以实时渲染组件更新页面。
一:我们在data中定义一个很大的临时对象
data() { return { myTempObj:{} // 这时一个很大的临时对象,字段特别多 } }
二:我们在计算属性中也定义一个很大的对象
这个对象是我们在页面中真正用到的对象
computed: { myObj: { get: function(){ return this.myTempObj; // 在这里把临时对象的值通过计算属性赋值给页面中用到的对象 } }, }
三:发起异步请求,从服务端返回数据
methods: { getBigObj(){ this.$http({ method: "post", url:this.$$baseURL + "sys/getBigObj", }).then(res => { this.myTempObj=res.bigObj ; // 在这里用临时变量接受服务端返回值 }); } }
四:页面模板组件中使用方法
<div class="brand-list bybrand_list" v-for="(item, index) in myObj" :key="index"> {{item.name}} </div>
以上两种情况都可以解决从服务端取到的数据不能实时更新问题,根据具体情况选择使用!
四年java开发,四年前端加产品。现今日头条前端架构师。欢迎关注我,技术人生如此有趣!
-
Vue数据类型转换
2020-05-28 10:59:26vue数据类型转换的问题 典型的String转Number问题。取决于percent属性值是整数还是分数。 1. 转换函数 /整数/parseInt(string) /分数/parseFloat(string) /Number/Number(val) 保留几位小数在方法后面加.toFixed(),... -
vue.js如何从页面获取数据
2021-01-17 17:09:31方法是利用vue-resource组件提供的一系列api:get(url, [data], [success], [options])post(url, [data], [success], [options])put(url, [data], [success], [options])patch(url, [data], [success], [options])... -
vue下拉框怎样从数据库获取数据?
2019-12-11 10:54:59vue从数据库获取数据显示到页面下拉框里面;目前有后端的查询所有数据的端口,求源码。 -
VUE数据绑定方法
2020-08-04 14:37:35Vue 框架很核心的功能就是双向的数据绑定。 双向是指:HTML 标签数据 绑定到 Vue 对象,另外反方向数据也是绑定的。通俗点说就是,Vue 对象的改变会直接影响到 HTML 的标签的变化,而且标签的变化也会反过来影响 Vue... -
vue 数据类型 属性
2019-03-28 16:22:42data export default { name: 'app', ... message:"hi vue !" } }, created(){ this.$emit('mes', this.message) } } props 组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组... -
解决Vue数据更新数据不渲染问题
2018-08-30 15:20:45Vue包装了数个数组操作函数,使用这些方法操作的数组去,其数据变动时会被vue监测: push() pop() shift() unshift() splice() sort() reverse() vue2.0还增加个方法可以观测Vue.set(items, index... -
Vue数据更新但页面没有更新的多种情况
2021-09-24 06:13:09Vue数据更新但页面没有更新的多种情况 1、Vue 无法检测实例被创建时不存在于 data 中的 变量 原因:由于 Vue 会在初始化实例时对 data中的数据执行 getter/setter 转化,所以 变量必须在 data 对象上存在才能让 Vue ... -
vue 请求数据方式
2019-05-20 22:15:46vue 请求数据方式 Vue 请求数据方式有:vue-resource、axios、fetchJsonp三种。其中,vue-resource 是 Vue官方提供的插件,axios 与 fetchJsonp 是第三方插件。 一、vue-resource 请求数据 npm 安装 vue-resource ... -
vue全局调用数据字典从服务端后取数据
2019-03-27 10:09:51服务端代码: @GetMapping("/getTypeValue/{vccodetype}") public R getTypeValue(@PathVariable(...3.在应用文件中调用,想要的数据在reponse中获取,引号中的值是需要传入的参数。参数值自行定义 -
vue 改变数据后,数据变化页面不刷新
2020-12-19 14:24:40最近在开发中遇到了这样一些情况,通过点击事件改变了对象里面得数据,但是页面却不刷新,后来发现,是在给对象添加属性时出现的问题。当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向... -
vue实时刷新页面数据
2020-12-19 17:48:14Vue不断请求数据 用定时器SetTimeOut不带参数发给后端点击{{one}}export default {data () {return {one: {}}},created () {this.getData()},methods: {async getData () {const { data: res } = await this.$... -
vue刷新当前页面,刷新数据,更新数据
2021-05-13 14:29:11第一种: this.$router.go(0) 这种就是让整个页面重新加载一次,但是会出现几秒钟的白屏情况,对用户体验不好。 第二种: location.reload() ...这种就比较简洁了,哪个数据需要刷新就调用那个方法,也相当于刷新页面 -
vue中如何获取后台数据
2020-12-19 10:20:33需要引用vue-resource在入口函数中加入import VueResource from 'vue-resource'Vue.use(VueResource);在package.json文件中加入"dependencies": {"vue": "^2.2.6","vue-resource":"^1.2.1"},请求如下mounted: ... -
vue下拉菜单 从后台获取数据
2019-11-07 17:00:10vue下拉菜单 从后台获取数据: vue: ;" size="small"> 站点名称"> 请选择" style="width: 200px;"> v-for="item in dataOptions" :key="item.value" :label="item.label" :value="item.value"> ... -
vue数据更新页面没有及时同步解决方案
2020-05-13 13:33:59我们在项目中经常会遇到数据更新了,但是视图并没有发生改变。尤其是引用类型的数据。 解决方案 Vue.set( target, propertyName/index, value ) .sync修饰符 -
Vue 双向数据绑定原理
2019-03-07 14:20:57vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。 vue实现双向数据绑定的原理就是... -
vue 对数据进行排序
2019-09-10 15:41:32单纯的数组数字进行排序,见vue使用sort()方法排序 根据数组中对象为数字情况进行排序,见下面代码 sortBykey(ary, key) { return ary.sort(function (a, b) { let x = a[key] let y = b[key] return ((x &... -
vue.js怎么获取数据库的数据
2021-01-11 19:47:38vue.js获取数据库数据的方法:1、首先我先在创建一个静态的data.json文件,在static下创建json文件夹,(webpack环境下,静态的文件放在static目录下){"data":[{"id":1,"name": "yidong", "age": "11" },{"id":2,... -
vue 数据修改但页面没刷新
2020-08-10 14:25:261.watch监听到数据的变化但页面没有刷新 在数据改动的代码后加this.$forceUpdate(); 添加this.$forceUpdate();进行强制渲染,效果实现。因为数据层次太多,...当然了,也可以使用vue中的方法this.$set(object, ... -
vue从后台获取数据生成动态菜单列表
2019-09-03 15:29:11vue前后端分离从后台获取menuList生成动态路由 将目录作为子目录添加到首页下面,可以显示出来,但是第二次点击同一个菜单时,会出现 地址叠加的情况,导致页面不能显示。而且先点击到别的页面也会出现这种情况 ... -
Vue重新渲染数据
2019-10-09 22:51:48Vue 不能检测以下数组的变动: 1、当你利用索引直接设置一个数组项时 2、当你修改数组的长度时 3、对象属性的添加或删除 来源: https://cn.vuejs.org/v2/guide/list.html 代码引入vue <script src=... -
vue 获取后端数据
2019-09-29 15:25:591、vue-resource从后端请求我们需要的数据 下载安装npm install vue-resource 装完之后重新启动项目 模拟后端数据,启动测试服务器 注意哦:最新的(我用的3.6)webpack 的build目录下删除了dev-server.js , ... -
Vue清空表单数据
2021-01-22 09:31:00表单项el-form-item要添加prop属性,prop属性需要与input框绑定数据的最后名称一致,如v-model=“form.username”, prop则应该为 prop=“username” 通过this.$refs.xxx.resetFields(); 此处xxx为form内ref属性起的... -
vue更新数据却不渲染页面解决方案
2021-12-03 20:54:591.Vue不能检测通过数组索引直接修改一个数组项 原因:由于JavaScript的限制,Vue不能检测数组和对象的变化 解决办法: this.$set(arr,index,newVal) ...听说循环数据更新的层级太深,导致数据不更新,从而导致视图.