常见vue选题

把你了解的vue响应式的原理阐述一下?

vue中有三个核心类

首先了解vue中的三个核心类

  1. Observer: 用来给对象的属性添加getter和setter,用来***依赖收集***和***派发更新***。
  2. Dep:用来收集当前响应式对象的依赖关系,每一个响应式对象都有一个dep实例,dep.subs = watcher[].是一个watcher数组。当数据发生变更的时候,会通知dep.notify()通知各个watcher。
  3. Watcher:观察者对象, render watcher 渲染,computed watcher 计算, user watcher监听
  • 依赖收集
  1. initState,初始化vue组件实例的时候,对computed属性初始化时,会触发computed watcher 依赖收集。
  2. initState,对监听属性初始化的时候,触发的user watcher依赖收集。
  3. render,渲染的过程,触发render watcher依赖收集。
  • 派发更新

Object.defineProperty

  1. 组件中对相应的数据进行了修改,或触发setter逻辑。
  2. dep.notify()
  3. 遍历所有subs,调用每一个watcher的update方法(更新视图)。

总结原理:

当创建vue实例的时候,vue先遍历data里面的属性。data初始化属性。Object.definProperty.为属性添加getter和setter对数据的读取进行劫持。

getter:依赖收集
setter:派发更新

每一个组件实例都会有对应的watcher实例。

计算属性的实现原理

data 是属性

computed : {  //  都是一个个的方法,重新调用求值
	test() {
	
	{
}

computed watcher,计算属性的监听器。

computed watcher 持有一个dep实例,通过dirty属性编辑属性是否需要重新求值。

当computed的依赖值改变后,就会通知订阅的wathcer进行更新,对于computed watcher 会将 dirty 属性设置 true,并且进行计算属性方法的调用。

  1. computed 所谓的缓存指的是什么?

计算属性是基于他的响应式依赖进行缓存的,只有雨来大声改变时才会重新求值。

  1. 实际应用中怎么用的?真实项目中使用过吗?那computed缓存存在的意义是什么?或者你经常在什么时候使用?

比如计算属性的方发内部操作非常的耗时,遍历一个极大的数组,计算一次需要一秒或者更多。

const largeArray = [
	{ ... },
	{ ... },
	{ ... }
] // 10w 条

data: {
	id: 1
}

computed: {
	currentItem: function() {
		return largeArray.find(item => item.id === this.id);
	},
	stringId: function () {
		return String(this.id);
	}
}
  1. 一下情况,computed 可以监听到数据的变化吗?(比如 : 格式化转化,有缓存)

watcher 没有缓存,变化之后接下来做什么动作,调用什么函数
computed 简单的转换操作,有缓存

template

    {{ storageMsg }}

computed: {
    storageMsg: function(){
        return sessionStorage.getItem('xxx'); // 获取不到数据,没有响应的更新上去就不会计算
    },
   time: function(){
        return Date.now(); // 也不可以,没有响应的更新上去就不会计算
   }
}

created() {
    sessionStorage.setItem('xxx', 1111)
}

onClick() {
   sessionStorage.setItem('xxx', Math.random())
}

vue.nextTick()

Vue.nextTick(() => {

})

await Vue.nextTick();

vue 是异步执行 dom 更新的,一旦观察到数据的变化,不会立即执行,开启异步队列,把同一个event loop 中观察数据变化的watcher推送到这个队列中。去除掉重复的事件操作。

在下一次事件循环时,vue清空异步队列,进行dom更新。

怎么样开启异步队列?

Promise.then > MutationObserver -> setImmediate > setTimeout …

vm.someData = ’ new value ’ dom 并不会立即更新,而是在异步队列被清空时才会更新dom。

里面的函数在下一轮事件队列中执行

红任务 -> 微任务队列 -> ui render(只有浏览器把元素渲染到页面,之前已经拿到新的dom,只是没有展现到浏览器上)

什么时候用到nextTick?

  1. 在数据变化后,要执行某个操作,而这个依赖因数据改变而改变的dom,这个操作就应该被放到vue.nextTick回调中。
<template>
   <div v-if="loaded" ref="test"></div>
</template>

async showDiv() {
    this.loaded = true;
    // this.$refs.test // 同步获取不到test
   
    await Vue.nextTick(); // 这个操作之后,才可以获取到test
    this.$refs.test.xxx();
}

手写一个vue,实现响应式的更新。

  1. 首先新建一个目录
  • index.html 主页面
  • vue.js vue主文件
  • compiler.js 编译模板,解析指令, v-model v-html
  • dep.js 收集依赖关系,存储观察者
  • watcher.js 观察者对象类
  1. index.html 内容
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ir=edge">
	<title>My Vue</title>
</head>
<body>
	<div></div>
</body>
</html>
  1. 初始化Vue class
/**
*包括vue构造函数,接受各种配置参数等等
*/
export default class Vue {
	// 构造函数
	constructor (options ={}) {
		this.$options = options;
		this.$data = options.data;
		this.$methods = options.methods;
		this.initRootElement(options);
	}

	/**
	*获取根元素,并存储到vue实例。简答检查一下传入的是否合规。
	*/
	initRootElement(options){
		if(typeof options.el === 'string') {
			this.$el = document.querySelector(options.el);
		} else if (options.el instanceof HTMLElement) {
			this.$el = options.el;
		}

		if(!this.$el){
			throw new Error('传入的el不合法,请传入css selector 或者 htmlelement')
		}
	}
}
  1. 验证一下,新建一个index.js
import Vue from 'OpenCourse/myvue/vue.js'

const vm = new Vue({
	el: '#app',
	data: {
		msg: 'hello lubai',
	},
	methods: {
		handler() {
			alert(999);
		}
	}
})
  • 输入一个错误的el
  • 输入一个htmlelement
  1. vue里可以通过this来获取data
_proxyData(data){
	Object.keys(data).forEach(key => {
		Object.defineProperty(this, key, {
			enumerable: true,
			configurable: true,
			get() {
				return data[key];
			},
			get() {
				if(data[key] === mewValue){
					return;
				}
				data[key] = newValue;
			}
		})
	})
}
  1. 接下来,先把几个核心声明好

具体的实现先不管

写好注释,对于这种外界可能引用到的方法,最好用jsDoc来注释。

  • dep.js
export default class Dep {
	constructor() {
		// 存储所有的观察者
		rhis.subs = [];
	}

	/**
	*添加观察者
	*/
	addSub(watcher){
		
	}
	
	/**
	* 发送通知
	*/
	notify (watcher) {

	}
}
  • observer.js
export default class Observer{
	constructor(data){	
		this.traverse(data);
	}

	/** 递归遍历data里的所有属性 */
	traverse(data){

	}

	/** 给传入的数据设置 getter 和 setter */
	defineReactive(obj, key, val) {
		// TODO 递归遍历
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue.js是十分耀眼的项目之一,受到国内外开发人员的极度推崇。内容包括Vue.js概述、Vue.js的安装、定义页面、渲视图、路由、发送HTTP请求、表单的绑定和提交、打包、部署、解决js的跨域问题、Debug、Component、Vuex、页面的生命周期等,*后还给出一个实战案例供读者了解Vue.js项目开发过程。2020-2021最新Vue.js零基础入门到精通实战开发课程视频教程下载。课程以项目实战为驱动,帮你打开通往Vue.js的任督二脉,让你迅速成为一个优秀的Vue.js开发人员。 一、课程介绍Vue.js致力于构建数据驱动的web应用开发框架,是一个精简的MVVM。Vue.js 专注于 MVVM 模型的 ViewModel 层。简单的数据操作,就可以完成页面的更新,当然也有很多类似的框架,如Angular,React,但是Vue以简洁化,轻量级,数据驱动,模块友好等优势深受企业以及前端开发者的喜爱,成为前端开发人员必备的技能。2020年了,你还只会用jQuery吗?本课程以项目实战为驱动,帮你打开通往Vue.js的任督二脉,让你迅速成为一个优秀的Vue.js开发人员。二、课程需知我们的课程面向的同学是:需要有网页开发基础,熟悉HTML/CSS/JavaScript等前端开发技术,初步掌握JSON,闭包,AJAX…等JavaScript技术,在进阶阶段的课程中会使用ES6的一些语法,因此事先掌握一些ES6的知识也是有必要的。三、内容编排本课程分为三大部分讲解了运用Vue.js 进行项目实战开发。内容包括:第一步:Vue.js基础1、初识vue.js 2、模板语法3、计算属性4、class与style绑定5、条件渲染6、列表渲染7、fetch&axios8、事件处理器9、表单控件10、组件化开发第二步:Vue.js进阶1、过渡动画效果2、自定义指令3、单文件组件4、路由vue-router第三步:项目实战1、卖座苹果网站项目- 引入iconfont- 路由搭建- axios以及反向代理-嵌套路由-数据渲染2、Vue.js第三方框架使用-Element UI-mintUI3、状态管理vuex课程详细目录:Vue.js 课程介绍.docx第001集-1vue初识第002集-2条件渲染第003集-3tab切换第004集-4列表渲染第005集-5模板语法第006集-6计算属性第007集-7侦听器和class第008集-8内联样式第009集-9事件绑定第010集-10表单输入绑定第011集-11过渡动画第012集-12todolist应用第013集-13生命周期与组件生命周期第014集-14组件之间的传值第015集-15$root_$parent_$children第016集-16v-model与插槽第017集-17vue-cli第018集-18vue-devtools第019集-19vue-cli原理第020集-20vue组件化第021集-21vue聊天框第022集-22socket初识和安装第023集-23单聊和群聊以及命名空间第024集-24聊天项目第025集-25聊天登录登出第026集-26聊天列表第027集-27个人聊天第028集-28单聊功能第029集-29自动滚动和聊天第030集-30群聊第031集-31注意编译地址第032集-32vue实现原理1第033集-33vue实现原理2第034集-34less第035集-35vue-less使用第036集-36sass第037集-37vue-router第038集-38动态路由和嵌套路由第039集-39命名视图和组件传参第040集-40vue路由高级应用第041集-41Vue路由守卫第042集-42vuexstate第043集-43vuex getter第044集-44vuex-action第045集-45vuex-module第046集-46vuex-插件第047集-47vuex-vant第048集-48网易严选商城第049集-49网易商城首页第050集-50分类列表第051集-51产品列表第052集-52产品列表2第053集-53商品产品页面第054集-54产品sku第055集-55产品购物车第056集-56购物车
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值