成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Vue

roadtogeek / 2561人閱讀

摘要:再獲取其事件屬性,我們這里只簡(jiǎn)單地獲取屬性,我們將它的屬性值和元素標(biāo)識(shí)保存到中最后等待模版掛載在元素中后,我們遍歷數(shù)組,掛載事件至此,我的已基本實(shí)現(xiàn)了實(shí)現(xiàn)的是一個(gè)簡(jiǎn)單的計(jì)數(shù)器有興趣的小伙伴可以復(fù)制以下代碼運(yùn)行查看效果

這周參考了一些博文,自己寫了一個(gè)簡(jiǎn)單的vue,網(wǎng)上這類實(shí)現(xiàn)很多,我的實(shí)現(xiàn)也沒什么新奇,權(quán)當(dāng)一個(gè)自我練習(xí)吧

本文同時(shí)發(fā)在我的github博客上,歡迎star

具體實(shí)現(xiàn)

首先,得先有一個(gè)Vue類,當(dāng)然,我寫的一個(gè)很粗糙的Vue類,所以我把它叫做BabyVue:

function BabyVue(options) {
    const { data, root, template, methods } = options;
    this.data = data;
    this.root = root;
    this.template = template;
    this.methods = methods;
    this.observe();
    this.resolveTemplate();
}

BabtVue構(gòu)造函數(shù)接受一個(gè)options,options中包含data,root(即html中指定的根結(jié)點(diǎn)),template模版,methods四個(gè)option,我們把這些option掛載到this方法上,以便后續(xù)的函數(shù)能輕松地拿到他們。然后執(zhí)行observe和resolveTemplate方法

observe方法:

BabyVue.prototype.observe = function() {
    Object.keys(this.data).forEach(key => {
        let val = this.data[key];
        const observer = new Observer();
        Object.defineProperty(this.data, key, {
            get: () => {
                if (Observer.target) {
                    observer.subscribe(Observer.target);
                }
                return val;
            },
            set: newValue => {
                if (val === newValue) {
                    return;
                }
                val = newValue;
                observer.publish(newValue);
            }
        });
    });
};

observe方法中先對(duì)this.data中的數(shù)據(jù)進(jìn)行遍歷,這里沒有考慮更深層的結(jié)構(gòu),只對(duì)第一層數(shù)據(jù)進(jìn)行遍歷,利用閉包緩存它的當(dāng)前值val和一個(gè)觀察者observer,并用Object.defineProperty方法設(shè)置它的get和set屬性,在獲取值的時(shí)候判斷Observer.target是否存在,若存在,則將Observer.target加入訂閱者(后面再詳述其作用),最后返回val;設(shè)置值的時(shí)候,將新值與val對(duì)比,若不同,則更新val值,并通知訂閱者更新

下面是Observer的代碼,實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的觀察者模式:

function Observer() {
    this.subscribers = [];
}
Observer.prototype.subscribe = function(subscriber) {
    !~this.subscribers.indexOf(subscriber) && this.subscribers.push(subscriber);
};
Observer.prototype.publish = function(newVal) {
    this.subscribers.forEach(subscriber => {
        const ele = document.querySelector(`[${subscriber}]`);
        ele && (ele.innerHTML = newVal);
    });
};

訂閱者用其特殊屬性進(jìn)行標(biāo)識(shí),在更新時(shí),先通過屬性選擇器拿到目標(biāo)dom再更新其值

下面是resolveTemplate的代碼,其主要是渲染模版、增加元素標(biāo)識(shí)和掛載事件,Vue中對(duì)模版解析使用的應(yīng)當(dāng)是更高級(jí)的方法,我這里只是對(duì)template字符串一些簡(jiǎn)單的解析

BabyVue.prototype.resolveTemplate = function() {
    const root = document.createElement("div");
    root.innerHTML = this.template;
    const children = root.children;
    const nodes = [].slice.call(children);
    let index = 0;
    const events = [];
    while (nodes.length !== 0) {
        const node = nodes.shift();
        const _index = index++;
        node.setAttribute(`v-${_index}`, "");
        if (node.children.length > 0) {
            nodes.push(...node.children);
        } else {
            if (/{{(.*)}}/.test(node.innerHTML)) {
                const key = node.innerHTML.replace(/{{(.*)}}/, "$1");
                Observer.target = `v-${_index}`;
                node.innerHTML = this.data[key];
                Observer.target = null;
            }

            const method = node.getAttribute("v-on:click");
            if (method) {
                events.push({
                    key: `v-${_index}`,
                    type: "click",
                    method
                });
            }
        }
    }
    this.root.innerHTML = root.innerHTML;
    events.forEach(event => {
        const { key, type, method } = event;
        const ele = document.querySelector(`[${key}]`);
        ele.addEventListener(type, this.methods[method].bind(this));
    });
};

我對(duì)模版中的每一個(gè)元素增加一個(gè)特殊標(biāo)示,形似v-xxx,方便根據(jù)表示標(biāo)示獲取真實(shí)dom(為什么不直接保存node?可以試試使用了createElement創(chuàng)建的元素再設(shè)置innerHTML,會(huì)出現(xiàn)一些問題)。

先根據(jù)正則匹配{},若符合條件,獲取了大括號(hào)的標(biāo)識(shí)符后,先將Object.target設(shè)為元素的標(biāo)識(shí),在將元素的innerHTML置為data中的數(shù)據(jù),要注意,在此時(shí),我們獲取了一次this.data[key],會(huì)觸發(fā)之前設(shè)置的get屬性,在其中判斷Observer.target是否存在,因?yàn)槲覀儎倓傇O(shè)置過,Observer.target當(dāng)前為元素的標(biāo)識(shí),所以,它被加到訂閱者中。

再獲取其事件屬性,我們這里只簡(jiǎn)單地獲取v-on:click屬性,我們將它的屬性值和元素標(biāo)識(shí)保存到events中

最后等待模版掛載在root元素中后,我們遍歷events數(shù)組,掛載事件

至此,我的BabyVue已基本實(shí)現(xiàn)了

Demo

實(shí)現(xiàn)的是一個(gè)簡(jiǎn)單的計(jì)數(shù)器:

有興趣的小伙伴可以復(fù)制以下代碼運(yùn)行查看效果:





  
  
  
  BabyVue



  

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/106383.html

相關(guān)文章

  • vue框架基本原理,簡(jiǎn)單實(shí)現(xiàn)一個(gè)todo-list

    摘要:前言最近在學(xué)習(xí)框架的基本原理,看了一些技術(shù)博客以及一些對(duì)源碼的簡(jiǎn)單實(shí)現(xiàn),對(duì)數(shù)據(jù)代理數(shù)據(jù)劫持模板解析變異數(shù)組方法雙向綁定有了更深的理解。 前言 最近在學(xué)習(xí)vue框架的基本原理,看了一些技術(shù)博客以及一些對(duì)vue源碼的簡(jiǎn)單實(shí)現(xiàn),對(duì)數(shù)據(jù)代理、數(shù)據(jù)劫持、模板解析、變異數(shù)組方法、雙向綁定有了更深的理解。于是乎,嘗試著去實(shí)踐自己學(xué)到的知識(shí),用vue的一些基本原理實(shí)現(xiàn)一個(gè)簡(jiǎn)單的todo-list,完成...

    Karrdy 評(píng)論0 收藏0
  • 面試被問到Vue?想進(jìn)一步提升?那就停下來看一下吧

    摘要:兩個(gè)對(duì)象鍵名沖突時(shí),取組件對(duì)象的鍵值對(duì)。允許聲明擴(kuò)展另一個(gè)組件可以是一個(gè)簡(jiǎn)單的選項(xiàng)對(duì)象或構(gòu)造函數(shù),而無需使用。這主要是為了便于擴(kuò)展單文件組件。 Vue作為最近最炙手可熱的前端框架,其簡(jiǎn)單的入門方式和功能強(qiáng)大的API是其優(yōu)點(diǎn)。而同時(shí)因?yàn)槠銩PI的多樣性和豐富性,所以他的很多開發(fā)方式就和一切基于組件的React不同,如果沒有對(duì)Vue的API(有一些甚至文檔都沒提到)有一個(gè)全面的了解,那么在...

    andot 評(píng)論0 收藏0
  • JavaScript之實(shí)現(xiàn)一個(gè)簡(jiǎn)單Vue

    摘要:的使用相信大家都很熟練了,使用起來簡(jiǎn)單。但是大部分人不知道其內(nèi)部的原理是怎么樣的,今天我們就來一起實(shí)現(xiàn)一個(gè)簡(jiǎn)單的實(shí)現(xiàn)之前我們得先看一下的實(shí)現(xiàn),因?yàn)橹饕峭ㄟ^數(shù)據(jù)劫持來實(shí)現(xiàn)的,通過來完成數(shù)據(jù)的讀取和更新。 vue的使用相信大家都很熟練了,使用起來簡(jiǎn)單。但是大部分人不知道其內(nèi)部的原理是怎么樣的,今天我們就來一起實(shí)現(xiàn)一個(gè)簡(jiǎn)單的vue Object.defineProperty() 實(shí)現(xiàn)之前我...

    Gilbertat 評(píng)論0 收藏0
  • vue簡(jiǎn)單入門(一)vue是什么,為什么我們要學(xué)vue?

    摘要:是什么為什么我們要使用說到了,我們就不得不先聊一下是什么以及為什么我們要使用,他能給我們的開發(fā)帶來什么樣的便利呢首先,我們來看一下的自我介紹讀音,類似于是一套用于構(gòu)建用戶界面的漸進(jìn)式框架。 作為一個(gè)剛?cè)胄胁痪玫牟锁B不知從什么時(shí)候開始就有了寫一個(gè)自己的專欄的想法,剛好今天沒事就給自己挖一個(gè)坑,分享一下我對(duì)vue的見解和一些領(lǐng)悟,整個(gè)專欄應(yīng)該會(huì)包括vue,vue-cli,vue-route...

    Lucky_Boy 評(píng)論0 收藏0
  • VUE - MVVM - part13 - inject & 總結(jié)

    摘要:通過裝作這些變化,我們實(shí)現(xiàn)了從而到達(dá)了數(shù)據(jù)變化觸發(fā)函數(shù)的過程。于此同時(shí),我們還實(shí)現(xiàn)了來擴(kuò)展這個(gè)可響應(yīng)的結(jié)構(gòu),讓這個(gè)對(duì)象擁有了觸發(fā)和響應(yīng)事件的能力。最后,根據(jù)我們的實(shí)現(xiàn),這是最終的產(chǎn)出,一個(gè)框架,了解一下系列文章地址優(yōu)化優(yōu)化總結(jié) 看這篇之前,如果沒有看過之前的文章,移步拉到文章末尾查看之前的文章。 provide / inject 在上一步我們實(shí)現(xiàn)了,父子組件,和 props 一樣 pr...

    niuxiaowei111 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<