摘要:它被當做一個輕量版本的使用,用于存儲已排好版的或尚未打理好格式的片段。最大的區(qū)別是因為不是真實樹的其中一部分,它的變化不會引起樹的重新渲染的操作,或者導致性能影響的問題出現(xiàn)。
工具類原文地址
項目地址
/** * Simple bind, faster than native * * @param {Function} fn * @param {Object} ctx * @return {Function} */ export function bind (fn, ctx) { return function (a) { var l = arguments.length return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx) } }
綁定函數(shù),利用 apply 和 call 方法進行 this 的綁定,
/** * Check if two values are loosely equal - that is, * if they are plain objects, do they have the same shape? * * @param {*} a * @param {*} b * @return {Boolean} */ export function looseEqual (a, b) { /* eslint-disable eqeqeq */ return a == b || ( isObject(a) && isObject(b) ? JSON.stringify(a) === JSON.stringify(b) : false )debug 類
import config from "../config" let warn if (process.env.NODE_ENV !== "production") { const hasConsole = typeof console !== "undefined" warn = function (msg, e) { if (hasConsole && (!config.silent || config.debug)) { console.warn("[Vue warn]: " + msg) /* istanbul ignore if */ if (config.debug) { if (e) { throw e } else { console.warn((new Error("Warning Stack Trace")).stack) } } } } } export { warn }
debug 類有意思的是根據(jù)環(huán)境是否是生產(chǎn)環(huán)境來確定
dom 類 dom 元素插入刪除替換操作用慣了 JQ, 還記得怎么用原生函數(shù)添加元素么?
/** * Insert el before target * * @param {Element} el * @param {Element} target */ export function before (el, target) { target.parentNode.insertBefore(el, target) } /** * Insert el after target * * @param {Element} el * @param {Element} target */ export function after (el, target) { if (target.nextSibling) { before(el, target.nextSibling) } else { target.parentNode.appendChild(el) } } /** * Remove el from DOM * * @param {Element} el */ export function remove (el) { el.parentNode.removeChild(el) } /** * Prepend el to target * * @param {Element} el * @param {Element} target */ export function prepend (el, target) { if (target.firstChild) { before(el, target.firstChild) } else { target.appendChild(el) } } /** * Replace target with el * * @param {Element} target * @param {Element} el */ export function replace (target, el) { var parent = target.parentNode if (parent) { parent.replaceChild(el, target) } }元素類的添加刪除
/** * Add class with compatibility for IE & SVG * * @param {Element} el * @param {Strong} cls */ export function addClass (el, cls) { if (el.classList) { el.classList.add(cls) } else { var cur = " " + (el.getAttribute("class") || "") + " " if (cur.indexOf(" " + cls + " ") < 0) { el.setAttribute("class", (cur + cls).trim()) } } } /** * Remove class with compatibility for IE & SVG * * @param {Element} el * @param {Strong} cls */ export function removeClass (el, cls) { if (el.classList) { el.classList.remove(cls) } else { var cur = " " + (el.getAttribute("class") || "") + " " var tar = " " + cls + " " while (cur.indexOf(tar) >= 0) { cur = cur.replace(tar, " ") } el.setAttribute("class", cur.trim()) } if (!el.className) { el.removeAttribute("class") } }
對元素的類的操作在老版本只支持 setAttribute 來操作,而隨著版本的更新,瀏覽器開始支持 classList 屬性 的 add 和 remove 方法來操作元素的類,但依舊要兼容舊版本的瀏覽器
DocumentFragment/** * Extract raw content inside an element into a temporary * container div * * @param {Element} el * @param {Boolean} asFragment * @return {Element} */ export function extractContent (el, asFragment) { var child var rawContent /* istanbul ignore if */ if ( isTemplate(el) && el.content instanceof DocumentFragment ) { el = el.content } if (el.hasChildNodes()) { trimNode(el) rawContent = asFragment ? document.createDocumentFragment() : document.createElement("div") /* eslint-disable no-cond-assign */ while (child = el.firstChild) { /* eslint-enable no-cond-assign */ rawContent.appendChild(child) } } return rawContent }
DocumentFragment 接口表示一個沒有父級文件的最小文檔對象。它被當做一個輕量版本的 Document 使用,用于存儲已排好版的或尚未打理好格式的XML片段。最大的區(qū)別是因為DocumentFragment不是真實DOM樹的其中一部分,它的變化不會引起DOM樹的重新渲染的操作(reflow) ,或者導致性能影響的問題出現(xiàn)。
更多信息可以參考MDN 文檔
元素的生命周期相關(guān)函數(shù)import { removeWithTransition } from "../transition/index" .... /** * Map a function to a range of nodes . * * @param {Node} node * @param {Node} end * @param {Function} op */ export function mapNodeRange (node, end, op) { var next while (node !== end) { next = node.nextSibling op(node) node = next } op(end) } /** * Remove a range of nodes with transition, store * the nodes in a fragment with correct ordering, * and call callback when done. * * @param {Node} start * @param {Node} end * @param {Vue} vm * @param {DocumentFragment} frag * @param {Function} cb */ export function removeNodeRange (start, end, vm, frag, cb) { var done = false var removed = 0 var nodes = [] mapNodeRange(start, end, function (node) { if (node === end) done = true nodes.push(node) removeWithTransition(node, vm, onRemoved) }) function onRemoved () { removed++ if (done && removed >= nodes.length) { for (var i = 0; i < nodes.length; i++) { frag.appendChild(nodes[i]) } cb && cb() } } }
兩個函數(shù)實現(xiàn)的是將一段范圍內(nèi)的元素刪除的實現(xiàn)
env 類env 提供了監(jiān)測是否是瀏覽器環(huán)境?屬于IE? 屬于安卓?css transition 和 animation 是否需要 webkit 前綴?
/** * Defer a task to execute it asynchronously. Ideally this * should be executed as a microtask, so we leverage * MutationObserver if it"s available, and fallback to * setTimeout(0). * * @param {Function} cb * @param {Object} ctx */ export const nextTick = (function () { var callbacks = [] var pending = false var timerFunc function nextTickHandler () { pending = false var copies = callbacks.slice(0) callbacks = [] for (var i = 0; i < copies.length; i++) { copies[i]() } } /* istanbul ignore if */ if (typeof MutationObserver !== "undefined") { var counter = 1 var observer = new MutationObserver(nextTickHandler) var textNode = document.createTextNode(counter) observer.observe(textNode, { characterData: true }) timerFunc = function () { counter = (counter + 1) % 2 textNode.data = counter } } else { timerFunc = setTimeout } return function (cb, ctx) { var func = ctx ? function () { cb.call(ctx) } : cb callbacks.push(func) if (pending) return pending = true timerFunc(nextTickHandler, 0) } })()
最后一個關(guān)于 nextTick 的實現(xiàn)暫時看不懂
options 類實現(xiàn)了一個 strats 類,但具體用在什么地方還不清楚
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85119.html
摘要:原文地址項目地址上一篇遺留的作為版本頻繁使用的,在構(gòu)造函數(shù)里以引入類實現(xiàn)了多種過濾方法包括方法的實現(xiàn)其實是對的對象的方法做了一層封裝,有意思的是發(fā)現(xiàn)發(fā)現(xiàn)方法的第二參數(shù)和第三個參數(shù),查了才知道后兩個參數(shù)分別代表要提取的屬性以及縮進格式,在這里 原文地址項目地址 上一篇遺留的 filter 作為 1.0 版本頻繁使用的 filter,在 構(gòu)造函數(shù)里以 Vue.Options.filters...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業(yè)務工作時也會不定期更...
摘要:中文官網(wǎng)英文官網(wǎng)組織發(fā)出一個問題之后,不要暫時的離開電腦,如果沒有把握先不要提問。珍惜每一次提問,感恩每一次反饋,每個人工作還是業(yè)余之外抽出的時間有限,充分準備好應有的資源之后再發(fā)問,有利于問題能夠高效質(zhì)量地得到解決。 Vue.js資源分享 更多資源請Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/maid...
摘要:因為用戶不用在第一次進入應用時下載所有代碼,用戶能更快的看到頁面并與之交互。譯高階函數(shù)利用和來編寫更易維護的代碼高階函數(shù)可以幫助你增強你的,讓你的代碼更具有聲明性。知道什么時候和怎樣使用高階函數(shù)是至關(guān)重要的。 Vue 折騰記 - (10) 給axios做個挺靠譜的封裝(報錯,鑒權(quán),跳轉(zhuǎn),攔截,提示) 稍微改改都能直接拿來用~~~喲吼吼,喲吼吼..... 如何無痛降低 if else 面...
摘要:所以整個的核心,就是如何實現(xiàn)這三樣東西以上摘自囧克斯博客的一篇文章從版本開始這個時候的項目結(jié)構(gòu)如下源碼在里面,為打包編譯的代碼,為打包后代碼放置的位置,為測試代碼目錄。節(jié)點類型摘自資源另一位作者關(guān)于源碼解析 本項目的源碼學習筆記是基于 Vue 1.0.9 版本的也就是最早的 tag 版本,之所以選擇這個版本,是因為這個是最原始沒有太多功能拓展的版本,有利于更好的看到 Vue 最開始的骨...
閱讀 2040·2021-09-30 09:47
閱讀 715·2021-09-22 15:43
閱讀 1997·2019-08-30 15:52
閱讀 2445·2019-08-30 15:52
閱讀 2556·2019-08-30 15:44
閱讀 919·2019-08-30 11:10
閱讀 3380·2019-08-29 16:21
閱讀 3306·2019-08-29 12:19