前端萬字面經——進階篇

這是我參與8月更文挑戰的第2天,活動詳情查看:8月更文挑戰javascript

此文爲前端進階篇前邊已經出了基礎篇php

基礎篇連接點擊跳轉css

服務端編程/Ajax

JSONP 的缺點

  • JSON 只支持get,由於script 標籤只能使用get 請求;
  • JSONP 須要後端配合返回指定格式的數據。

跨域(jsonp,ajax)

JSONP:ajax 請求受同源策略影響,不容許進行跨域請求,而script 標籤src 屬性中的鏈 接卻能夠訪問跨域的js 腳本,利用這個特性,服務端再也不返回JSON 格式的數據,而是 返回一段調用某個函數的js 代碼,在src 中進行了調用,這樣實現了跨域。html

如何實現跨域

  • JSONP:經過動態建立script,再請求一個帶參網址實現跨域通訊。document.domain +iframe 跨域:兩個頁面都經過js 強制設置document.domain 爲基礎主域,就實現了同域。location.hash + iframe 跨域:a 欲與b 跨域相互通訊,經過中間頁c 來實現。三個頁面,不一樣域之間利用iframe 的location.hash 傳值,相同域之間直接js 訪問來通訊。window.name + iframe 跨域:經過iframe 的src 屬性由外域轉向本地域,跨域數據即由iframe的window.name 從外域傳遞到本地域。
  • postMessage 跨域:能夠跨域操做的window 屬性之一。
  • CORS:服務端設置Access-Control-Allow-Origin 便可,前端無須設置,若要帶cookie 請求,先後端都須要設置。
  • 代理跨域:起一個代理服務器,實現數據的轉發

實現一個Ajax

AJAX 建立異步對象XMLHttpRequest操做XMLHttpRequest 對象前端

  1. 設置請求參數(請求方式,請求頁面的相對路徑,是否異步)
  2. 設置回調函數,一個處理服務器響應的函數,使用onreadystatechange ,相似函數指針
  3. 獲取異步對象的readyState 屬性:該屬性存有服務器響應的狀態信息。每當readyState 改變時,onreadystatechange 函數就會被執行。
  4. 判斷響應報文的狀態,若爲200 說明服務器正常運行並返回響應數據。
  5. 讀取響應數據,能夠經過responseText 屬性來取回由服務器返回的數據。
var xhr = new XMLHttpRequest();
xhr.open('get', 'aabb.php', true);
xhr.send(null);
xhr.onreadystatechange = function() {
    if(xhr.readyState==4) {
        if(xhr.status==200) {
        console.log(xhr.responseText);
        }
    }
}
複製代碼

移動web 開發

知道PWA 嗎

PWA 全稱Progressive Web App,即漸進式WEB 應用。一個PWA 應用首先是一個網頁,能夠經過Web 技術編寫出一個網頁應用. 隨後添加上App Manifest 和Service Worker來實現PWA 的安裝和離線等功能vue

移動佈局方案

直接給你們一個連接吧超詳細。 juejin.im/post/599970…java

Rem, Em

rem 單位如何轉換爲像素值 當使用rem 單位的時候,頁面轉換爲像素大小取決於葉根元素的字體大小,即HTML 元素的字體大小。根元素字體大小乘rem 的值。例如,根元素的字體大小爲16px,那麼 10rem 就等同於10*16=160px。node

em 是如何轉換成px 的 當使用em 單位的時候,像素值是將em 值乘以使用em 單位的元素的字體大小。例如一 個div 的字體爲18px,設置它的寬高爲10em,那麼此時寬高就是18px*10em=180px。react

.test{
    width: 10em;
    height: 10em;
    background-color: #ff7d42;
    font-size: 18px;
}
/** 必定要記住的是,em 是根據使用它的元素的font-size 的大小來變化的,而不是根據父 元素字體大小。有些元素大小是父元素的多少倍那是由於繼承了父元素中font-size 的設 定,因此才起到的做用。 */
複製代碼

em 單位的繼承效果 使用em 單位存在繼承的時候,每一個元素將自動繼承其父元素的字體大小,繼承的效果 只能被明確的字體單位覆蓋,好比px 和vw。只要父級元素上面一直有fontsize 爲em 單 位,則會一直繼承,但假如本身設置了font-size 的單位爲px 的時候,則會直接使用自 己的px 單位的值。jquery

根html 的元素將會繼承瀏覽器中設置的字體大小 除非顯式的設置固定值去覆蓋。因此html 元素的字體大小雖然是直接肯定rem 的值, 但這個字體大小首先是來源於瀏覽器的設置。(因此必定要設置html 的值的大小,因 爲有可能用戶的瀏覽器字體大小是不一致的。)

當em 單位設置在html 元素上時 它將轉換爲em 值乘以瀏覽器字體大小的設置。

html{
    font-size: 1.5em;
}
/** 能夠看到,由於瀏覽器默認字體大小爲16px,因此當設置HTML 的fontsize 的值爲1.5em 的售後,其對應的px 的值爲16*1.5=24px 因此此時,再設置其餘元素的rem 的值的時候,其對應的像素值爲n*24px。 例如,test 的rem 的值爲10, */
.test{
    width: 10rem;
    height: 10rem;
    background-color: #ff7d42;
}
/** 總結: 1. rem 單位翻譯爲像素值的時候是由html 元素的字體大小決定的。此字體大小會 被瀏覽器中字體大小的設置影響,除非顯式的在html 爲font-size 重寫一個單位。 2. em 單位轉換爲像素值的時候,取決於使用它們的元素的font-size 的大小,可是有 由於有繼承關係,因此比較複雜。 優缺點 em 可讓咱們的頁面更靈活,更健壯,比起處處寫死的px 值,em 彷佛更有張力,改 動父元素的字體大小,子元素會等比例變化,這一變化彷佛預示了無限可能, em 作彈性佈局的缺點還在於牽一髮而動全身,一旦某個節點的字體大小發生變化,那 麼其後代元素都得從新計算 */
複製代碼

移動端適配1px 的問題

推薦 blog.csdn.net/weixin_4367…

  1. 用小數來寫px 值(不推薦)
// IOS8 下已經支持帶小數的px 值, media query 對應devicePixelRatio 有個查詢值
// -webkit-min-device-pixel-ratio, css 能夠寫成這樣
// 經過-webkit-min-device-pixel-ratio 設置。
.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border { border: 0.333333px solid #999 }
}
// 若是使用less/sass 的話只是加了1 句mixin
// 缺點: 安卓與低版本IOS 不適用, 這個或許是將來的標準寫法, 如今不作期望
複製代碼
  1. flexible.js

這是淘寶移動端採起的方案, github 的地址:https://github.com/amfe/lib-flexible. 前面已經 說過1px 變粗的緣由就在於一刀切的設置viewport 寬度, 若是能把viewport 寬度設置 爲實際的設備物理寬度, css 裏的1px 不就等於實際1px 長了麼. flexible.js 就是這樣 乾的. <meta name=」viewport」>裏面的scale 值指的是對ideal viewport 的縮放, flexible.js 檢 測到IOS 機型, 會算出scale = 1/devicePixelRatio, 而後設置viewport

  1. 僞類+transform 實現
/** 對於解決1px 邊框問題,我我的以爲最完美的解決辦法仍是僞類+transform 比較好。 原理:是把原先元素的border 去掉,而後利用:before 或者:after 重作border ,並 transform 的scale 縮小一半,原先的元素相對定位,新作的border 絕對定位。 media query 經過媒體查詢,能夠經過給不一樣分辨率的設備編寫不一樣的樣式來實現響應式的佈局,比 如咱們爲不一樣分辨率的屏幕,設置不一樣的背景圖片。好比給小屏幕手機設置@2x 圖,爲 大屏幕手機設置@3x 圖,經過媒體查詢就能很方便的實現。 可是媒體查詢的缺點也很明顯,若是在瀏覽器大小改變時,須要改變的樣式太多,那麼 多套樣式代碼會很繁瑣。*/
@media screen and (min-width: 320px) {
html {
font-size: 50px;
}
}
@media
/** 方便應用普遍適用於pc 端手機頁面,一般作自適應佈局時咱們比較經常使用。
缺點:相對於代碼要重複不少,得知道設備的寬度,手機的分辨率不少因此麻煩了點,
不過性能方面確定最高; 可能存在閃屏的問題
@media 處理手機和pc 端界面兼容的問題,在IE 上的訪問出現問題,百度方法,找找
兩種,一種是respond.js,另外一種是 
css3-mediaquerieshttp://blog.csdn.net/small_tu/article/details/47317453
*/
複製代碼

移動端性能優化相關經驗

給你們一個參考不一一列舉了移動端性能優化的方法

移動端兼容性

其餘參考連接:https://zhuanlan.zhihu.com/p/28206065

手勢事件

手勢事件 事件詳解
touchstart 當手指接觸屏幕時觸發 來代替 click 事件 來觸發移動端的點擊事件
touchmove 當手指接觸屏幕時觸發 代替 scroll 事件
touchend 當手指離開屏幕時觸發 來代替 click 事件 來觸發移動端的點擊事件

2X 圖3X 圖適配

實際程序開發當中,咱們代碼中用的值是指邏輯分辨率pt,而不是像素分辨率px, 好比咱們定義一個按鈕的高度爲45,這個45 指的是45pt 而不是45px。在非Retina 屏下1pt = 1px,4 和4.7 寸Retina 屏下1pt = 2px,5.5 和x 下1pt = 3px.咱們製做不一樣尺寸的圖片, 好比@1x 爲22px,則@2x 爲44px,@3x 爲66px,命名分別爲image.png,在項目的 Assets.xcassets 中新建New Image Set,修更名字爲image,並把相應尺寸的圖片拖放至相應位置。

/* 根據dpr 顯示2x 圖/3x 圖*/
.bg-image(@url){
background-image:~"url('@{url}@2x.png')";
@media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3){
background-image:~"url('@{url}@3x.png')";
}
}
.bg-color(@color) {
background-color: @color;
}
複製代碼

圖片在安卓上,有些設備模糊問題

這個問題是 devicePixelRatio 的不一樣致使的,由於手機分辨率過小了,若是按照分辨率顯示網頁,字會很是小,全部蘋果系統當初就把 iphone 4 的960x640像素的分辨率在網頁裏更改成480x320像素。這樣是 devicePixelRatio = 2. 而 Android 的 devicePixelRatio 比較亂,值有1.五、2和3,爲了在手機裏更爲清晰地顯示圖片, 必須使用2倍寬高的背景圖來代替 img 標籤(通常狀況下都使用2倍) 例如:一個 div 的寬高是 100x100 背景圖必須是200x200,而後設置 background-size:contain 樣式,顯示出來就比較清晰。

防止手機中頁面放大和縮小

<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
複製代碼

transiton 閃屏

//設置內聯的元素在3D 空間如何呈現:保留
3D-webkit-transform-style:preserve-3D;
//設置進行轉換的元素的背面在面對用戶時是否可見:隱藏
-webkit-backface-visibility:hidden;
複製代碼

上下拉動滾動條時卡頓、慢

body {
    -webkit-overflow-scrolling: touch;
    overflow-scrolling:touch;
}
複製代碼

長時間按住頁面出現閃退

element{
    -webkit-touch-callout: none;
}
複製代碼

前端工程化

Babel 的原理是什麼?

babel 的轉譯過程也分爲三個階段,這三步具體是:

  • 解析Parse: 將代碼解析生成抽象語法樹( 即AST ),即詞法分析與語法分析的過程
  • 轉換Transform: 對於AST 進行變換一系列的操做,babel 接受獲得AST 並通babel-traverse 對其進行遍歷,在此過程當中進行添加、更新及移除等操做。
  • 生成Generate: 將變換後的AST 再轉換爲JS 代碼, 使用到的模塊是babel-generator

image.png

如何寫一個babel 插件?

Babel 解析成AST,而後插件更改AST,最後由Babel 輸出代碼那麼Babel 的插件模塊須要你暴露一個function,function 內返回visitor

module.export = function(babel){
    return {
        visitor:{
        }
    }
}
複製代碼

visitor 是對各種型的AST 節點作處理的地方,那麼咱們怎麼知道Babel 生成了的 AST 有哪些節點呢?很簡單,你能夠把Babel 轉換的結果打印出來, 或者這裏有傳送門:AST explorer

image.png

/** 這裏咱們看到const result = 1 + 2 中的1 + 1 是一個BinaryExpression 節點,那麼在 visitor 中,咱們就處理這個節點 */
var babel = require('babel-core');
var t = require('babel-types');
const visitor = {
BinaryExpression(path) {
const node = path.node;
let result;
// 判斷表達式兩邊,是否都是數字
if (t.isNumericLiteral(node.left) && t.isNumericLiteral(node.right)) {
// 根據不一樣的操做符做運算
switch (node.operator) {
case "+":
result = node.left.value + node.right.value;
break
case "-":
result = node.left.value - node.right.value;
break;
case "*":
result = node.left.value * node.right.value;
break;
case "/":
result = node.left.value / node.right.value;
break;
case "**":
let i = node.right.value;
while (--i) {
result = result || node.left.value;
result = result * node.left.value;
}
break;
default:
}
}
// 若是上面的運算有結果的話
if (result !== undefined) {
// 把表達式節點替換成number 字面量
path.replaceWith(t.numericLiteral(result));
}
}
};
module.exports = function (babel) {
return {
visitor
};
}
// 插件寫好了,咱們運行下插件試試
const babel = require("babel-core");
const result = babel.transform("const result = 1 + 2;",{
plugins:[
require("./index")
]
});
console.log(result.code); // const result = 3;
/** 與預期一致,那麼轉換const result = 1 + 2 + 3 + 4 + 5;呢? 結果是: const result = 3 + 3 + 4 + 5; 這就奇怪了,爲何只計算了1 + 2 以後,就沒有繼續往下運算了? 咱們看一下這個表達式的AST 樹 你會發現Babel 解析成表達式裏面再嵌套表達式。 表達式( 表達式( 表達式( 表達式(1 + 2) + 3) + 4) + 5) 而咱們的判斷條件並不符合全部的,只符合1 + 2 */
// 判斷表達式兩邊,是否都是數字
if (t.isNumericLiteral(node.left) && t.isNumericLiteral(node.right)) {}
/** 那麼咱們得改一改 第一次計算1 + 2 以後,咱們會獲得這樣的表達式 表達式( 表達式( 表達式(3 + 3) + 4) + 5) 其中3 + 3 又符合了咱們的條件, 咱們經過向上遞歸的方式遍歷父級節點 又轉換成這樣: 表達式( 表達式(6 + 4) + 5) 表達式(10 + 5) 15 */
// 若是上面的運算有結果的話
if (result !== undefined) {
// 把表達式節點替換成number 字面量
path.replaceWith(t.numericLiteral(result));
let parentPath = path.parentPath;
// 向上遍歷父級節點
parentPath && visitor.BinaryExpression.call(this, parentPath);
}
/** 到這裏,咱們就得出告終果const result = 15; 那麼其餘運算呢: */
const result = 100 + 10 - 50>>>const result = 60;
const result = (100 / 2) + 50>>>const result = 100;
const result = (((100 / 2) + 50 * 2) / 50) ** 2>>>const result = 9;
複製代碼

你的git 工做流是怎樣的?

參考回答: 給本身引流一下能夠參考我轉載的政採雲的一篇文章很詳細 點此此處跳轉

webpack 和gulp 區別(模塊化與流的區別)

  • webpack 是一個前端模塊化方案,更側重模塊打包,咱們能夠把開發中的全部資源(圖片、js 文件、css 文件等)都當作模塊,經過loader(加載器)和plugins(插件)對資源進行處理,打包成符合生產環境部署的前端資源。
  • gulp 強調的是前端開發的工做流程,咱們能夠經過配置一系列的task,定義task 處理的事務(例如文件壓縮合並、雪碧圖、啓動server、版本控制等),而後定義執行順序,來讓gulp 執行這些task,從而構建項目的整個前端開發流程。

Vue

說說本身對vue的理解

Vue 是一個構建數據驅動的漸進性框架,它的目標是經過API 實現響應數據綁定和視圖更新。 優勢:

  1. 數據驅動視圖,對真實dom 進行抽象出virtual dom(本質就是一個js 對象),並配合diff 算法、響應式和觀察者、異步隊列等手段以最小代價更新dom,渲染頁面。
  2. 組件化,組件用單文件的形式進行代碼的組織編寫,使得咱們能夠在一個文件裏編寫html\css(scoped 屬性配置css 隔離)\js 而且配合Vue-loader 以後,支持更強大的預處理器等功能。
  3. 因爲採用虛擬dom,讓Vue ssr 先天就足,強大且豐富的API 提供一系列的api 能知足業務開發中各種需求。
  4. 生命週期鉤子函數,選項式的代碼組織方式,寫熟了仍是蠻順暢的,但仍然有優化空間(Vue3 composition-api)

缺點:

  1. 因爲底層基於Object.defineProperty(vue3.0採用 new Proxy()) 實現響應式,而這個api 自己不支持IE8及如下瀏覽器
  2. csr 的先天不足,首屏性能問題(白屏)
  3. 因爲百度等搜索引擎爬蟲沒法爬取js 中的內容,故spa 先天就對seo 優化心有餘力不足(谷歌的puppeteer 就挺牛逼的,實現預渲染底層也是用到了這個工具)

什麼是虛擬DOM?

虛擬dom 是相對於瀏覽器所渲染出來的真實dom 的,在react,vue 等技術出現以前, 咱們要改變頁面展現的內容只能經過遍歷查詢dom 樹的方式找到須要修改的dom 然 後修改樣式行爲或者結構,來達到更新ui 的目的。 這種方式至關消耗計算資源,由於每次查詢dom 幾乎都須要遍歷整顆dom 樹,若是 創建一個與dom 樹對應的虛擬dom 對象( js 對象),以對象嵌套的方式來表示dom 樹,那麼每次dom 的更改就變成了js 對象的屬性的更改,這樣一來就能查找js 對象 的屬性變化要比查詢dom 樹的性能開銷小。

vue 生命週期

image.png

vue 如何監聽鍵盤事件?

// @keyup. 方法
<template>
<input ref="myInput" type="text" value="hello world" autofocus @keyup.enter="handleKey"> </template>
<script> export default { methods: { handleKey(e) { console.log(e) } } } </script>
// addEventListener
<script> export default { mounted() { document.addEventListener('keyup', this.handleKey) }, beforeDestroy() { document.removeEventListener('keyup', this.handleKey) }, methods: { handleKey(e) { console.log(e) } } } </script>
<script> export default { mounted() { document.addEventListener('keyup', this.handleKey) }, beforeDestroy() { document.removeEventListener('keyup', this.handleKey) }, methods: { handleKey(e) { console.log(e) } } } </script>
複製代碼

watch 怎麼深度監聽對象變化

deep 設置爲true 就能夠監聽到對象的變化
let vm=new Vue({
    el:"#first",
    data:{msg:{name:'北京'}},
    watch:{
        msg:{
            handler (newMsg,oldMsg){
                console.log(newMsg);
            },
            immediate:true,
            deep:true
        }
    }
})
複製代碼

刪除數組用delete 和Vue.delete 有什麼區別?

  • delete:只是被刪除數組成員變爲empty / undefined,其餘元素鍵值不變
  • Vue.delete:直接刪了數組成員,並改變了數組的鍵值(對象是響應式的,確保刪除能觸發更新視圖,這個方法主要用於避開Vue 不能檢測到屬性被刪除的限制)

watch 和計算屬性有什麼區別?

通俗來說,既能用computed 實現又能夠用watch 監聽來實現的功能,推薦用computed, 重點在於computed 的緩存功能

computed 計算屬性是用來聲明式的描述一個值依賴了其它的值,當所依賴的值或者變量 改變時,計算屬性也會跟着改變;

watch 監聽的是已經在data 中定義的變量,當該變量變化時,會觸發watch 中的方法。

Vue 雙向綁定原理

Vue 數據雙向綁定是經過數據劫持結合發佈者-訂閱者模式的方式來實現的。利用了 Object.defineProperty() 這個方法從新定義了對象獲取屬性值(get)和設置屬性值(set)。

Vue3.0採用了 new Proxy() 能夠參考https://juejin.cn/post/6950826293923414047 掘金簽約的大神所寫。

說一下axios怎麼用? 怎麼解決跨域的問題?

axios 的是一種異步請求,用法和ajax 相似,安裝npm install axios --save 便可使用,請 求中包括get,post,put, patch ,delete 等五種請求方式,解決跨域能夠在請求頭中添加 Access-Control-Allow-Origin,也能夠在index.js 文件中更改proxyTable 配置等解決跨域 問題。

在vue 項目中如何引入第三方庫(好比jQuery)?

// 一、絕對路徑直接引入
// 在index.html 中用script 引入
<script src="./static/jquery-1.12.4.js"></script>
// 而後在webpack 中配置external
externals: { 'jquery': 'jQuery' }
// 在組件中使用時import
import $ from 'jquery'
// 2 、在webpack 中配置alias
resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': resolve('src'), 'jquery':
resolve('static/jquery-1.12.4.js') } }
// 而後在組件中import
// 三、在webpack 中配置plugins
plugins: [ new webpack.ProvidePlugin({ $: 'jquery' }) ]
// 全局使用,但在使用eslint 狀況下會報錯,須要在使用了$ 的代碼前添加/*eslint-disable*/ 來去掉ESLint 的檢查。
複製代碼

Vue3.0 裏爲何要用Proxy API 替代defineProperty API?

響應式優化。

  1. defineProperty API 的侷限性最大緣由是它只能針對單例屬性作監聽。Vue2.x 中的響應式實現正是基於defineProperty 中的descriptor,對data 中的屬性作了遍歷+ 遞歸,爲每一個屬性設置了getter、setter。這也就是爲何Vue 只能對data 中預約義過的屬性作出響應的緣由,在Vue 中使用下標的方式直接修改屬性的值或者添加一個預先不存在的對象屬性是沒法作到setter 監聽的,這是defineProperty 的侷限性。
  2. Proxy API 的監聽是針對一個對象的,那麼對這個對象的全部操做會進入監聽操做,這就徹底能夠代理全部屬性,將會帶來很大的性能提高和更優的代碼。Proxy 能夠理解成,在目標對象以前架設一層「攔截」,外界對該對象的訪問,都必須先經過這層攔截,所以提供了一種機制,能夠對外界的訪問進行過濾和改寫。
  3. 響應式是惰性的在Vue.js 2.x 中,對於一個深層屬性嵌套的對象,要劫持它內部深層次的變化,就須要遞歸遍歷這個對象,執行Object.defineProperty 把每一層對象數據都變成響應式的,這無疑會有很大的性能消耗。在Vue.js 3.0 中,使用Proxy API 並不能監聽到對象內部深層次的屬性變化,所以它的處理方式是在getter 中去遞歸響應式,這樣的好處是真正訪問到的內部屬性纔會變成響應式,簡單的能夠說是按需實現響應式,減小性能消耗。

基礎用法:

let datas = {
    num:0
}
let proxy = new Proxy(datas,{
    get(target,property){
        return target[property]
    },
    set(target,property,value){
        target[property] += value
    }
})
複製代碼

Vue3.0 編譯作了哪些優化?

  1. 生成Block tree

Vue.js 2.x 的數據更新並觸發從新渲染的粒度是組件級的,單個組件內部須要遍歷該組 件的整個vnode 樹。在2.0 裏,渲染效率的快慢與組件大小成正相關:組件越大,渲染 效率越慢。而且,對於一些靜態節點,又無數據更新,這些遍歷都是性能浪費。 Vue.js 3.0 作到了經過編譯階段對靜態模板的分析,編譯生成了Block tree。Block tree 是一個將模版基於動態節點指令切割的嵌套區塊,每一個區塊內部的節點結構是固定的, 每一個區塊只須要追蹤自身包含的動態節點。因此,在3.0 裏,渲染效率再也不與模板大小 成正相關,而是與模板中動態節點的數量成正相關。

  1. slot 編譯優化

Vue.js 2.x 中,若是有一個組件傳入了slot,那麼每次父組件更新的時候,會強制使子組 件update,形成性能的浪費。

Vue.js 3.0 優化了slot 的生成,使得非動態slot 中屬性的更新只會觸發子組件的更新。 動態slot 指的是在slot 上面使用v-if,v-for,動態slot 名字等會致使slot 產生運行時動 態變化可是又沒法被子組件track 的操做。

3.diff 算法優化

Vue2.x 中的虛擬dom 是進行全量的對比。 Vue3.0 中新增了靜態標記(PatchFlag):在與上次虛擬結點進行對比的時候,值對比 帶有patch flag 的節點,而且能夠經過flag 的信息得知當前節點要對比的具體內容化。

  1. hoistStatic 靜態提高

Vue2.x : 不管元素是否參與更新,每次都會從新建立。 Vue3.0 : 對不參與更新的元素,只會被建立一次,以後會在每次渲染時候被不停的複用。

  1. cacheHandlers 事件偵聽器緩存

默認狀況下onClick 會被視爲動態綁定,因此每次都會去追蹤它的變化可是由於是同一個函數,因此沒有追蹤變化,直接緩存起來複用便可。

講講 proxy

vue 的數據劫持有兩個缺點:

  1. 沒法監聽經過索引修改數組的值的變化
  2. 沒法監聽object 也就是對象的值的變化

因此vue2.x 中才會有$set 屬性的存在 proxy 是es6 中推出的新api,能夠彌補以上兩個缺點,因此vue3.x 版本用proxy 替換 object.defineproperty。

React

redux 中間件

中間件提供第三方插件的模式,自定義攔截action -> reducer 的過程。變爲action -> middlewares -> reducer 。這種機制可讓咱們改變數據流,實現如異步action ,action 過 濾,日誌輸出,異常報告等功能。

常見的中間件:redux-logger:提供日誌輸出;redux-thunk:處理異步操做;redux-promise: 處理異步操做;actionCreator 的返回值是promise

React 組件的劃分業務組件技術組件?

根據組件的職責一般把組件分爲UI 組件和容器組件。UI 組件負責UI 的呈現,容器組件負責管理數據和邏輯。二者經過React-Redux 提供connect 方法聯繫起來。

React 生命週期函數

// 1. 初始化階段
getDefaultProps:獲取實例的默認屬性
getInitialState:獲取每一個實例的初始化狀態
componentWillMount:組件即將被裝載、渲染到頁面上
render:組件在這裏生成虛擬的DOM 節點
componentDidMount:組件真正在被裝載以後
// 2. 運行中狀態
componentWillReceiveProps:組件將要接收到屬性的時候調用
shouldComponentUpdate:組件接受到新屬性或者新狀態的時候(能夠返回false,接收數據
後不更新,阻止render 調用,後面的函數不會被繼續執行了)
componentWillUpdate:組件即將更新不能修改屬性和狀態
render:組件從新描繪
componentDidUpdate:組件已經更新
// 3. 銷燬階段:
componentWillUnmount:組件即將銷燬
複製代碼

React 性能優化是哪一個周期函數?

shouldComponentUpdate 這個方法用來判斷是否須要調用render 方法從新描繪dom。因 爲dom 的描繪很是消耗性能,若是咱們能在shouldComponentUpdate 方法中可以寫出更 優化的dom diff 算法,能夠極大的提升性能。

React 性能優化方案

  1. 重寫shouldComponentUpdate 來避免沒必要要的dom 操做。
  2. 使用production 版本的React.js。
  3. 使用key 來幫助React 識別列表中全部子組件的最小變化

簡述flux 思想

Flux 的最大特色,就是數據的"單向流動"。

  • 用戶訪問View
  • View 發出用戶的Action
  • Dispatcher 收到Action,要求Store 進行相應的更新
  • Store 更新後,發出一個"change"事件
  • View 收到"change"事件後,更新頁面

瞭解shouldComponentUpdate 嗎

React 虛擬dom 技術要求不斷的將dom 和虛擬dom 進行diff 比較,若是dom 樹比價大, 這種比較操做會比較耗時,所以React 提供了shouldComponentUpdate 這種補丁函數,如 果對於一些變化,若是咱們不但願某個組件刷新,或者刷新後跟原來其實同樣,就能夠 使用這個函數直接告訴React,省去diff 操做,進一步的提升了效率。

React 的工做原理

React 會建立一個虛擬DOM(virtual DOM)。當一個組件中的狀態改變時,React 首先會 經過"diffing" 算法來標記虛擬DOM 中的改變,第二步是調節(reconciliation),會用diff 的結果來更新DOM。

使用React 有何優勢

  1. 只需查看render 函數就會很容易知道一個組件是如何被渲染的。
  2. JSX 的引入,使得組件的代碼更加可讀,也更容易看懂組件的佈局,或者組件之間是如何互相引用的。
  3. 支持服務端渲染,這能夠改進SEO 和性能。

類組件(Class component)和函數式組件(Functional component)之間有何不一樣

  1. 類組件不只容許你使用更多額外的功能,如組件自身的狀態和生命週期鉤子,也能使組件直接訪問store 並維持狀態
  2. 當組件僅是接收props,並將組件自身渲染到頁面時,該組件就是一個'無狀態組件(stateless component)',可使用一個純函數來建立這樣的組件。這種組件也被稱爲啞組件(dumb components)或展現組件

(組件的)狀態(state)和屬性(props)之間有何不一樣?

  1. State 是一種數據結構,用於組件掛載時所需數據的默認值。State 可能會隨着時間的推移而發生突變,但多數時候是做爲用戶事件行爲的結果。
  2. Props(properties 的簡寫)則是組件的配置。props 由父組件傳遞給子組件,而且就子組件而言,props 是不可變的(immutable)。組件不能改變自身的props,可是能夠把其子組件的props 放在一塊兒(統一管理)。Props 也不只僅是數據--回調函數也能夠經過props傳遞。

在那個生命週期發起 ajax 請求

在React 組件中,應該在componentDidMount 中發起網絡請求。這個方法會在組件第 一次「掛載」(被添加到DOM)時執行,在組件的生命週期中僅會執行一次。更重要的是, 你不能保證在組件掛載以前Ajax 請求已經完成,若是是這樣,也就意味着你將嘗試在 一個未掛載的組件上調用setState,這將不起做用。在componentDidMount 中發起網絡 請求將保證這有一個組件能夠更新了。

在React 中,refs 的做用是什麼

Refs 能夠用於獲取一個DOM 節點或者React 組件的引用。什麼時候使用refs 的好的示例 有管理焦點/文本選擇,觸發命令動畫,或者和第三方DOM 庫集成。你應該避免使用 String 類型的Refs 和內聯的ref 回調。Refs 回調是React 所推薦的。

何爲高階組件(higher order component)?

高階組件是一個以組件爲參數並返回一個新組件的函數。HOC 運行你重用代碼、邏輯 和引導抽象。最多見的多是Redux 的connect 函數。除了簡單分享工具庫和簡單的 組合,HOC 最好的方式是共享React 組件之間的行爲。若是你發現你在不一樣的地方寫 了大量代碼來作同一件事時,就應該考慮將代碼重構爲可重用的HOC。

爲何建議傳遞給setState 的參數是一個callback 而不是一個對象

由於this.props 和this.state 的更新多是異步的,不能依賴它們的值去計算下一個state。

怎麼阻止組件的渲染

在組件的render 方法中返回null 並不會影響觸發組件的生命週期方法

當渲染一個列表時,何爲key?設置key 的目的是什麼

Keys 會有助於React 識別哪些items 改變了,被添加了或者被移除了。Keys 應該被賦 予數組內的元素以賦予(DOM)元素一個穩定的標識,選擇一個key 的最佳方法是使用一 個字符串,該字符串能唯一地標識一個列表項。不少時候你會使用數據中的IDs 做爲 keys,當你沒有穩定的IDs 用於被渲染的items 時,可使用項目索引做爲渲染項的 key,但這種方式並不推薦,若是items 能夠從新排序,就會致使re-render 變慢

(在構造函數中)調用super(props) 的目的是什麼

在super() 被調用以前,子類是不能使用this 的,在ES2015 中,子類必須在constructor 中調用super()。傳遞props 給super() 的緣由則是便於(在子類中)能在constructor 訪問 this.props。

JSX

JSX 是JavaScript 語法的一種語法擴展,並擁有JavaScript 的所有功能。JSX 生產 React "元素",你能夠將任何的JavaScript 表達式封裝在花括號裏,而後將其嵌入到JSX 中。在編譯完成以後,JSX 表達式就變成了常規的JavaScript 對象,這意味着你能夠在 if 語句和for 循環內部使用JSX,將它賦值給變量,接受它做爲參數,並從函數中返回 它。

Angular

Angular 中組件之間通訊的方式

Props down

  1. 調用子組件,經過自定義屬性傳值
  2. 子組件內部經過Input 來接收屬性的值

Events up

  1. 在父組件中定義一個有參數的方法
  2. 調用子組件時,綁定自定義事件和上一步方法
  3. 子組件內部經過Output 和EventEmitter 來觸發事件並傳值.

Angualr 的八大組成部分並簡單描述

model 是Angular 開發中的基本單位,是一個容器,能夠包含組件、指令、管道等
Components 是可被反覆使用的帶有特定功能的視圖
Templates 是通過指令和管道、組件等加強過的html
Bindings 結合着事件綁定屬性綁定雙向數據綁定等擴展html 的功能
Directives 分爲結構性和屬性型指令還有其餘模塊中好比路由模塊中的指令等,
主要是加強html.
Pipes 能夠對數據作一個篩選、過濾、格式化從而獲得目的數據
Service 將組件、應用中的可共用的部分,好比數據或者方法等封裝成服務以方便服用
DependencyInjection 依賴注入
複製代碼

Angular 中常見的生命週期的鉤子函數

ngOnChanges:當Angular 設置其接收當前和上一個對象值的數據綁定屬性時響應。
ngOnInit:在第一個ngOnChange 觸發器以後,初始化組件/指令。這是最經常使用的方法,
用於從後端服務檢索模板的數據。
ngDoCheck:檢測並在Angular 上下文發生變化時執行。
每次更改檢測運行時,會被調用。
ngOnDestroy:在Angular 銷燬指令/組件以前消除。取消訂閱可觀察的對象並脫離
事件處理程序,以免內存泄漏。
組件特定的hooks:
ngAfterContentInit:組件內容已初始化完成
ngAfterContentChecked:在Angular 檢查投影到其視圖中的綁定的外部內容以後。
ngAfterViewInit:Angular 建立組件的視圖後。
ngAfterViewChecked:在Angular 檢查組件視圖的綁定以後
複製代碼

Angular 中路由的工做原理

Angular 應用程序具備路由器服務的單個實例,而且每當URL 改變時,相應的路由就與路 由配置數組 進行匹配。在成功匹配時,它會應用重定向,此時路由器會構建ActivatedRoute 對象的樹, 同時包含路由器的當前狀態。在重定向以前,路由器將經過運行保護(CanActivate) 來檢查是否容許新的狀態。Route Guard 只是路由器運行來檢查路由受權的接口方法。 保護運行後,它將解析路由數據並經過將所需的組件實例化到 <router-outlet></router-outlet> 來激活路由器狀態。

解釋rjx 在Angular 中的使用場景

Rxjs 是在微軟所提供的一種的異步處理數據的方式,在Angular 中處理網絡通訊時用到了。
建立一個Observable 並subsribe
好比:this.http.get('').subscribe((data)=>{ })
複製代碼

到這裏基本完成了還有哪裏沒有講述到的歡迎各位大佬指正批評。建議點贊+收藏

基礎篇連接點擊跳轉

相關文章
相關標籤/搜索