vue中不熟悉的點

一捧搞、vue

  1. provide, inject

    provide選項應該是一個對象或返回一個對象的函數(shù)察净。該對象包含可注入其子孫的屬性疆股。

    inject選項應該是:

    • 一個字符串根资,或
    • 一個對象架专,對象的key是本地的綁定名,value是:
      • 在可用的注入內(nèi)容中搜索用的key(字符串或Symbol)或
      • 一個對象玄帕,該對象的:
        • from 屬性是在可用的注入內(nèi)容中搜索用的key
        • default 屬性時降級情況下使用的value
    // 父組件
    provide:{
        
    }
    // 子組件
    inject:{
        foo:{
            from:'foo',
            default:'test'
        }
    },
    mounted(){
        console.log(this.foo);  // test
    }
    
    <!--另外一種寫法-->
    
    // 子組件
    inject:['foo'];
    
    mounted(){
        console.log(this.foo);// test
    }
    
    
  2. el

    提供一個在頁面上已經(jīng)存在的DOM元素作為Vue實例的掛載目標部脚。可以是CSS選擇器裤纹,也可以是一個HTMLElement委刘。

    在實例掛載之后,元素可以用vm.el訪問。 如果再實例化時存在這個想選钱雷,實例將立即進入編譯過程骂铁,否則,需要顯示調(diào)用vm.mount()手動開啟編譯

    源代碼:

    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    } 
    
      var app = new Vue({
            data:{
                message:'hello Vue!'
            },
            el:'#bpp',
            directives:{
                
            },
            provide(){
                return {
                    getData(){
                        console.log('123')
                    }
                }
            },
            beforeCreate(){
                console.log(this.message)
            },
            mounted(){
                console.log(this._data, this._provided)
            }
        });
    // 在 id= bpp的元素上加載Vue實例
    
  3. 數(shù)組去重

function dedupe (latest, sealed) {
  // compare latest and sealed to ensure lifecycle hooks won't be duplicated
  // between merges
  if (Array.isArray(latest)) {
    const res = []
    sealed = Array.isArray(sealed) ? sealed : [sealed]
    for (let i = 0; i < latest.length; i++) {
      if (sealed.indexOf(latest[i]) < 0) {
        res.push(latest[i])
      }
    }
    return res
  } else {
    return latest
  }
}
  1. compositionstart compositionend
  1. compositionstart 事件觸發(fā)于一段文字的輸入之前(類似于 keydown 事件罩抗,但是該事件僅在若干可見字符的輸入之前拉庵,而這些可見字符的輸入可能需要一連串的鍵盤操作、語音識別或者點擊輸入法的備選詞)套蒂。
  2. compositionend 事件觸發(fā)一段文字輸入完成或者刪除文字時
<input type="text" id="text" />

function trigger(el,type){
    const e = document.createEvent('HTMLEvents');
    e.initEvent(type,true,true);
    el.dispatchEvent(e);
}
var dom = document.getElementById('text');
dom.addEventListener('compositionstart', onCompositionStart)
dom.addEventListener('compositionend', onCompositionEnd)
function onCompositionStart(e){
    e.target.composing = true
    console.log('===========================');
    console.log('e',e);
    console.log('===========================');
}
function onCompositionEnd(e){
    e.target.composing = false
    console.log('===========================');
    console.log('end',e);
    console.log('===========================');
    trigger(dom,'ceshi');
}
dom.addEventListener('ceshi',function(value){
    console.log(value)
})



二. 源碼分析

1.入口文件

package.json

scripts:{ 
    "dev": "rollup -w -c build/config.js --environment TARGET:web-full-dev",
}

build/config.js

TARGET: web-full-dev
// Runtime+compiler development build (Browser)
  'web-full-dev': {
    entry: path.resolve(__dirname, '../src/entries/web-runtime-with-compiler.js'),
    dest: path.resolve(__dirname, '../dist/vue.js'),
    format: 'umd',
    env: 'development',
    alias: { he: './entity-decoder' },
    banner
  },



if (process.env.TARGET) {
  module.exports = genConfig(builds[process.env.TARGET])
} 

entries/web-runtime-with-compiler.js

import Vue from './web-runtime'

web-runtime.js

import Vue from 'core/index'

core/index.js

import Vue from './instance/index'

import { initGlobalAPI } from './global-api/index'

initGlobalAPI(Vue)

instance/index

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

initMixin(Vue) // 添加_init方法
// 初始化一些數(shù)據(jù)钞支,其中 beforeCreate鉤子在initState()數(shù)據(jù)之前,導致在beforeCreate鉤子中拿不到data或者props的值操刀,create鉤子中能拿到data或者props中的值
    

stateMixin(Vue) // 初始化 props,data,computed,watch 全部通過defineReactive變成響應式數(shù)據(jù) 添加$watch方法
eventsMixin(Vue) // 添加$on $off $emit方法
lifecycleMixin(Vue) // 添加_update方法烁挟,$forceUpdate方法,$destroy
renderMixin(Vue) // 添加 _render方法骨坑,添加$nextTick方法

initMixin()

initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')

global-api/index.js

export function initGlobalAPI (Vue: GlobalAPI) {}
<!--添加工具函數(shù)-->
initUse(Vue)
initMixin(Vue)
initExtend(Vue)
initAssetRegisters(Vue)

  1. 其中響應式數(shù)據(jù)核心:
    Observe,Dep,Watcher,defineReactive

    1. Obejct.defineProperty

    方法會直接在一個對象上定義一個新屬性撼嗓,或者修改一個對象的現(xiàn)有屬性, 并返回這個對象欢唾。

    語法:Object.defineProperty(obj, prop, descriptor)

    參數(shù)

     obj
     要在其上定義屬性的對象且警。
     prop
     要定義或修改的屬性的名稱。
     descriptor
     將被定義或修改的屬性描述符礁遣。
    

    Object.defineProperty詳細描述

    注: configurable 為false時斑芜,屬性不能被刪除,為true時能被刪除祟霍,默認值為false

    1. defineReactive

    主要作用就是在get時將watcher對象放入Dep.subs數(shù)組中杏头,set時去更新視圖

    簡易實現(xiàn)(詳細參考Vue源碼)

    function defineReactive(obj,key,val){
        const dep = new Dep();
       
        Object.defineProperty(obj,key,{
            enumerable:true,
            configurable:true,
            get: function reactiveGetter(){
                dep.addSub(Dep.target);
                return val;
            },
            set: function reactiveSetter(newVal){
                if(val == newVal){
                    return;
                }
                dep.nodify();
                val = newVal;
                // cb(val);
            }
        });
    }
    
    
    1. Observer 將現(xiàn)有數(shù)據(jù)變成可視化數(shù)據(jù)

    簡易實現(xiàn)

    function observer(value){
        if(!value || typeof value !='object'){
            return ;
        }
        // 遞歸循環(huán)
        for(let key in value){
            if(Obejct.prototype.toString.call( value[key]) == '[Object object]'){
                dgObj(value[key],key,value);  
            }else{
                defineReactive(value, key , value[key]);
            }
        }
    }
    
    
    
    1. Dep 主要作用收集watcher對象

    簡易實現(xiàn)

    function Dep(){
    // this.subs = [];
    }
    
    Dep.prototype ={
        subs:[],
        addSub:function(subs){
            this.subs.push(subs);
        },
        nodify:function(){
            this.subs.forEach(sub =>{
                sub.update();
            });
        }
    };
    Dep.target = null;
    
    1. Watcher 將Dep.target賦值,更新視圖
    function Watcher(){
        Dep.target = this;
    }
    
    Watcher.prototype ={
        update:function(){
            console.log('視圖更新了7心拧4纪酢!垂谢!~~~');
        }
    }
    
    1. Vue構造函數(shù)

    簡易實現(xiàn)

     function Vue (options){
        this._data = options.data;
        new Watcher();
        observer(this._data);
    }
    

以上都是簡單實現(xiàn)厦画,并且有好多細節(jié)沒有體現(xiàn)出來疮茄,例如:添加watcheer實例時會有id記錄這個對象有沒有存在于數(shù)組中滥朱,如果有就不會在添加了;在給對象賦值時VUE中也考慮到了如果當前對象存在自己的setget屬性的情況力试,但是本例中沒有考慮這種情況只是簡單的賦值 等;詳細細節(jié)可以去VUE源碼中查看

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末徙邻,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子畸裳,更是在濱河造成了極大的恐慌缰犁,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異帅容,居然都是意外死亡颇象,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門并徘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遣钳,“玉大人,你說我怎么就攤上這事麦乞≡誊睿” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵姐直,是天一觀的道長倦淀。 經(jīng)常有香客問我,道長声畏,這世上最難降的妖魔是什么撞叽? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮插龄,結果婚禮上能扒,老公的妹妹穿的比我還像新娘。我一直安慰自己辫狼,他們只是感情好初斑,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著膨处,像睡著了一般见秤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上真椿,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天鹃答,我揣著相機與錄音,去河邊找鬼突硝。 笑死测摔,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的解恰。 我是一名探鬼主播锋八,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼护盈!你這毒婦竟也來了挟纱?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤腐宋,失蹤者是張志新(化名)和其女友劉穎紊服,沒想到半個月后檀轨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡欺嗤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年参萄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煎饼。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡拧揽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腺占,到底是詐尸還是另有隱情淤袜,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布衰伯,位于F島的核電站铡羡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏意鲸。R本人自食惡果不足惜烦周,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怎顾。 院中可真熱鬧读慎,春花似錦、人聲如沸槐雾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽募强。三九已至株灸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間擎值,已是汗流浹背慌烧。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鸠儿,地道東北人屹蚊。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像进每,于是被迫代替她去往敵國和親汹粤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容

  • vue理解淺談 一 理解vue的核心理念 使用vue會讓人感到身心愉悅,它同時具備angular和react的優(yōu)點...
    ambeer閱讀 24,138評論 2 18
  • 本文是lhyt本人原創(chuàng)品追,希望用通俗易懂的方法來理解一些細節(jié)和難點玄括。轉(zhuǎn)載時請注明出處冯丙。文章最早出現(xiàn)于本人github...
    lhyt閱讀 2,215評論 0 4
  • 響應式原理 Vue實現(xiàn)響應式的核心是利用了Object.defindProperty為對象的屬性添加getter和...
    C脖子閱讀 956評論 0 0
  • 「聲動派」,專注互聯(lián)網(wǎng)價值傳播泞莉,為你分享大連接時代的一切哪雕! 本文大約11000字閱讀需要12分鐘 第一部分 寫在前...
    聲動派閱讀 588評論 0 1
  • 有沒有 一個時候 莫名的難過 試圖安慰自己 卻變得更加難過 有沒有 一種難過 不能用語言訴說 無法用眼淚表達 只能...
    哈扎拉閱讀 88評論 2 3