Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
vue响应式原理实现_响应式网页设计代码,希望能够帮助你!!!。
监听Vue实例中的data选项,我们以下用一个普通的js对象模拟data,用Object.defineProperty进行定义属性值的getter和setter方法。当data选择项中的key进行获取和修改时,Vue内部会调用相应的方法。
主要考虑以下两点:
响应式原理实现代码: class Vue{
constructor(options){
//1.保存数据 this.$options = options; this.$data = options.data; this.$el = options.el; //2.将data添加到响应式系统中 new Observer(this.$data) //3.处理el new Complier(this.$el, this) //4.代理this.$data的数据 Object.keys(this.$data).forEach(key=>{
this._proxy(key) }) } _proxy(key){
Object.defineProperty(this, key, {
configurable: true, enumerable: true, set(newValue){
this.$data[key] = newValue }, get(){
return this.$data[key] } }) } } //将data中的属性加入到相应模式中 class Observer{
constructor(data){
this.data = data Object.keys(data).forEach(key=>{
this.defineReactive(this.data, key, data[key]) }) } defineReactive(data, key, val){
//一个属性(key)对应一个发布者对象 const dep = new Dep() Object.defineProperty(data, key, {
enumerable: true, configurable: true, //将订阅者加入到subs数组中 get(){
if(Dep.target){
dep.addSub(Dep.target) } return val }, //数据修改时,通知订阅者 set(newValue){
if(newValue === val) return val = newValue dep.notify() } }) } } //定义发布者:添加、通知订阅者 class Dep{
constructor(){
this.subs = [] } // addSub(sub){
this.subs.push(sub) } //订阅者更新时,调用watcher中的update()修改视图中的节点值 notify(){
this.subs.forEach(sub=>{
sub.update() }) } } //订阅者 class Watcher{
constructor(node, name, vm){
this.node = node; this.name = name; this.vm = vm; Dep.target = this; this.update() Dep.target = null } update(){
this.node.nodeValue = this.vm[this.name] } } //template编译 const reg = /\{\{(.+)\}\}/ class Complier{
constructor(el, vm){
this.el = document.querySelector(el) this.vm = vm this.frag = this._createFragment() this.el.appendChild(this.frag) } _createFragment(){
const frag = document.createDocumentFragment() let child; while(child = this.el.firstChild){
this._compile(child) frag.appendChild(child) } return frag } _compile(node){
if(node.nodeType === 1){
const attrs = node.attributes if(attrs.hasOwnProperty('v-model')){
const name = attrs['v-model'].nodeValue node.addEventListener('input',e=>{
this.vm[name] = e.target.value }) } } //节点编译时,name为订阅者名字,创建对应的watcher实例 if(node.nodeType === 3){
if(reg.test(node.nodeValue)){
const name = RegExp.$1.trim() new Watcher(node, name, this.vm) } } } }
如果感觉文章对你有帮助,别忘了点个赞哦!!!!!!!!!
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。