初中级前端面试题—完整版
前言
從前端學習到找一份合適的工作,大大小小的面試必不可少,所以我對初級前端面試題進行了初步整理,也方便自己查閱,也希望對小伙伴們有所幫助!
HTML
HTML語義化
HTML語義化就是讓頁面內容結構化,它有如下優(yōu)點
1、易于用戶閱讀,樣式丟失的時候能讓頁面呈現(xiàn)清晰的結構。 2、有利于SEO,搜索引擎根據(jù)標簽來確定上下文和各個關鍵字的權重。 3、方便其他設備解析,如盲人閱讀器根據(jù)語義渲染網頁 4、有利于開發(fā)和維護,語義化更具可讀性,代碼更好維護,與CSS3關系更和諧如:
<header>代表頭部 <nav>代表超鏈接區(qū)域 <main>定義文檔主要內容 <article>可以表示文章、博客等內容 <aside>通常表示側邊欄或嵌入內容 <footer>代表尾部HTML5新標簽
有<header>、<footer>、<aside>、<nav>、<video>、<audio>、<canvas>等...CSS
盒子模型
盒模型分為標準盒模型和怪異盒模型(IE模型)
box-sizing:content-box //標準盒模型 box-sizing:border-box //怪異盒模型
標準盒模型:元素的寬度等于style里的width+margin+border+padding寬度
如下代碼,整個寬高還是120px
div{box-sizing: content-box;margin: 10px;width: 100px;height: 100px;padding: 10px; }怪異盒模型:元素寬度等于style里的width寬度
如下代碼,整個寬高還是100px
div{box-sizing: border-box;margin: 10px;width: 100px;height: 100px;padding: 10px; }注意:如果你在設計頁面中,發(fā)現(xiàn)內容區(qū)被撐爆了,那么就先檢查一下border-sizing是什么,最好在引用reset.css的時候,就對border-sizing進行統(tǒng)一設置,方便管理
rem與em的區(qū)別
rem是根據(jù)根的font-size變化,而em是根據(jù)父級的font-size變化
rem:相對于根元素html的font-size,假如html為font-size:12px,那么,在其當中的div設置為font-size:2rem,就是當中的div為24px
em:相對于父元素計算,假如某個p元素為font-size:12px,在它內部有個span標簽,設置font-size:2em,那么,這時候的span字體大小為:12*2=24px
CSS選擇器
css常用選擇器
通配符:* ID選擇器:#ID 類選擇器:.class 元素選擇器:p、a 等 后代選擇器:p span、div a 等 偽類選擇器:a:hover 等 屬性選擇器:input[type="text"] 等css選擇器權重
!important -> 行內樣式 -> #id -> .class -> 元素和偽元素 -> * -> 繼承 -> 默認
CSS新特性
transition:過渡 transform:旋轉、縮放、移動或者傾斜 animation:動畫 gradient:漸變 shadow:陰影 border-radius:圓角行內元素和塊級元素
行內元素(display: inline)
寬度和高度是由內容決定,與其他元素共占一行的元素,我們將其叫行內元素,例如:<span> 、 <i> 、 <a>等
塊級元素(display: block)
默認寬度由父容器決定,默認高度由內容決定,獨占一行并且可以設置寬高的元素,我們將其叫做塊級元素,例如:<p> 、<div> 、<ul>等
在平時,我們經常使用CSS的display: inline-block,使它們擁有更多的狀態(tài)
絕對定位和相對定位的區(qū)別
position: absolute
絕對定位:是相對于元素最近的已定位的祖先元素
position: relative
相對定位:相對定位是相對于元素在文檔中的初始位置
Flex布局
https://juejin.im/post/5d428c5451882556dc30535c
BFC
什么是BFC?
BFC格式化上下文,它是一個獨立的渲染區(qū)域,讓處于 BFC 內部的元素和外部的元素相互隔離,使內外元素的定位不會相互影響
如何產生BFC?
display: inline-block
position: absolute/fixed
BFC作用
BFC最大的一個作用就是:在頁面上有一個獨立隔離容器,容器內的元素和容器外的元素布局不會相互影響
解決上外邊距重疊;重疊的兩個box都開啟bfc; 解決浮動引起高度塌陷;容器盒子開啟bfc 解決文字環(huán)繞圖片;左邊圖片div,右邊文字容器p,將p容器開啟bfc水平垂直居中
Flex布局
display: flex //設置Flex模式 flex-direction: column //決定元素是橫排還是豎著排 flex-wrap: wrap //決定元素換行格式 justify-content: space-between //同一排下對齊方式,空格如何隔開各個元素 align-items: center //同一排下元素如何對齊 align-content: space-between //多行對齊方式水平居中
行內元素:display: inline-block; 塊級元素:margin: 0 auto; Flex: display: flex; justify-content: center垂直居中
行高 = 元素高:line-height: height flex: display: flex; align-item: centerless,sass,styus三者的區(qū)別
變量
Sass聲明變量必須是『$』開頭,后面緊跟變量名和變量值,而且變量名和變量值需要使用冒號:分隔開。Less 聲明變量用『@』開頭,其余等同 Sass。
Stylus 中聲明變量沒有任何限定,結尾的分號可有可無,但變量名和變量值之間必須要有『等號』。
作用域
Sass:三者最差,不存在全局變量的概念
Less:最近的一次更新的變量有效,并且會作用于全部的引用!
Stylus:Sass 的處理方式和 Stylus 相同,變量值輸出時根據(jù)之前最近的一次定義計算,每次引用最近的定義有效;
嵌套
三種 css 預編譯器的「選擇器嵌套」在使用上來說沒有任何區(qū)別,甚至連引用父級選擇器的標記 & 也相同繼承
Sass和Stylus的繼承非常像,能把一個選擇器的所有樣式繼承到另一個選擇器上。使用『@extend』開始,后面接被繼承的選擇器。Stylus 的繼承方式來自 Sass,兩者如出一轍。 Less 則又「獨樹一幟」地用偽類來描述繼承關系;導入@Import
Sass 中只能在使用 url() 表達式引入時進行變量插值 $device: mobile; @import url(styles.#{$device}.css); Less 中可以在字符串中進行插值 @device: mobile; @import "styles.@{device}.css"; Stylus 中在這里插值不管用,但是可以利用其字符串拼接的功能實現(xiàn) device = "mobile" @import "styles." + device + ".css"總結
Sass和Less語法嚴謹、Stylus相對自由。因為Less長得更像 css,所以它可能學習起來更容易。
Sass 和 Compass、Stylus 和 Nib 都是好基友。
Sass 和 Stylus 都具有類語言的邏輯方式處理:條件、循環(huán)等,而 Less 需要通過When等關鍵詞模擬這些功能,這方面 Less 比不上 Sass 和 Stylus
Less 在豐富性以及特色上都不及 Sass 和 Stylus,若不是因為 Bootstrap 引入了 Less,可能它不會像現(xiàn)在這樣被廣泛應用(個人愚見)
link與@import區(qū)別與選擇
<style type="text/css">@import url(CSS文件路徑地址); </style> <link href="CSSurl路徑" rel="stylesheet" type="text/css" / link功能較多,可以定義 RSS,定義 Rel 等作用,而@import只能用于加載 css;當解析到link時,頁面會同步加載所引的 css,而@import所引用的 css 會等到頁面加載完才被加載;
@import需要 IE5 以上才能使用;
link可以使用 js 動態(tài)引入,@import不行
多行元素的文本省略號
overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: verticalJavaScript
JS的幾條基本規(guī)范
1、不要在同一行聲明多個變量 2、請使用===/!==來比較true/false或者數(shù)值 3、使用對象字面量替代new Array這種形式 4、不要使用全局變量 5、Switch語句必須帶有default分支 6、函數(shù)不應該有時候有返回值,有時候沒有返回值 7、For循環(huán)必須使用大括號 8、IF語句必須使用大括號 9、for-in循環(huán)中的變量 應該使用var關鍵字明確限定作用域,從而避免作用域污染JS引用方法
行內引入
<body><input type="button" onclick="alert('行內引入')" value="按鈕"/><button onclick="alert(123)">點擊我</button> </body>內部引入
<script>window.onload = function() {alert("js 內部引入!");} </script>外部引入
<body><div></div><script type="text/javascript" src="./js/index.js"></script> </body>注意
1,不推薦寫行內或者HTML中插入<script>,因為瀏覽器解析順序緣故,如果解析到死循環(huán)之類的JS代碼,會卡住頁面 2,建議在onload事件之后,即等HTML、CSS渲染完畢再執(zhí)行代碼JS的基本數(shù)據(jù)類型
Undefined、Null、Boolean、Number、String、新增:Symbol數(shù)組操作
在 JavaScript 中,用得較多的之一無疑是數(shù)組操作,這里過一遍數(shù)組的一些用法
map: 遍歷數(shù)組,返回回調返回值組成的新數(shù)組 forEach: 無法break,可以用try/catch中throw new Error來停止 filter: 過濾 some: 有一項返回true,則整體為true every: 有一項返回false,則整體為false join: 通過指定連接符生成字符串 push / pop: 末尾推入和彈出,改變原數(shù)組, 返回推入/彈出項【有誤】 unshift / shift: 頭部推入和彈出,改變原數(shù)組,返回操作項【有誤】 sort(fn) / reverse: 排序與反轉,改變原數(shù)組 concat: 連接數(shù)組,不影響原數(shù)組, 淺拷貝 slice(start, end): 返回截斷后的新數(shù)組,不改變原數(shù)組 splice(start, number, value...): 返回刪除元素組成的數(shù)組,value 為插入項,改變原數(shù)組 indexOf / lastIndexOf(value, fromIndex): 查找數(shù)組項,返回對應的下標 reduce / reduceRight(fn(prev, cur), defaultPrev): 兩兩執(zhí)行,prev 為上次化簡函數(shù)的return值,cur 為當前值(從第二項開始)JS有哪些內置對象
Object是JavaScript中所有對象的父對象數(shù)據(jù)封裝對象:Object、Array、Boolean、Number和String 其他對象:Function、Arguments、Math、Date、RegExp、Errorget請求傳參長度的誤區(qū)
誤區(qū):我們經常說get請求參數(shù)的大小存在限制,而post請求的參數(shù)大小是無限制的
實際上HTTP 協(xié)議從未規(guī)定 GET/POST 的請求長度限制是多少。對get請求參數(shù)的限制是來源與瀏覽器或web服務器,瀏覽器或web服務器限制了url的長度。為了明確這個概念,我們必須再次強調下面幾點:
1、HTTP 協(xié)議 未規(guī)定 GET 和POST的長度限制
2、GET的最大長度顯示是因為 瀏覽器和 web服務器限制了 URI的長度
3、不同的瀏覽器和WEB服務器,限制的最大長度不一樣
4、要支持IE,則最大長度為2083byte,若只支持Chrome,則最大長度 8182byte
補充get和post請求在緩存方面的區(qū)別
-
get請求類似于查找的過程,用戶獲取數(shù)據(jù),可以不用每次都與數(shù)據(jù)庫連接,所以可以使用緩存。
-
post不同,post做的一般是修改和刪除的工作,所以必須與數(shù)據(jù)庫交互,所以不能使用緩存。因此get請求適合于請求緩存。
閉包
什么是閉包?
函數(shù)A 里面包含了 函數(shù)B,而 函數(shù)B 里面使用了 函數(shù)A 的變量,那么 函數(shù)B 被稱為閉包。
又或者:閉包就是能夠讀取其他函數(shù)內部變量的函數(shù)
function A() {var a = 1;function B() {console.log(a);}return B(); }閉包的特征
- 函數(shù)內再嵌套函數(shù)
- 內部函數(shù)可以引用外層的參數(shù)和變量
- 參數(shù)和變量不會被垃圾回收制回收
對閉包的理解
使用閉包主要是為了設計私有的方法和變量。閉包的優(yōu)點是可以避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易造成內存泄露。在js中,函數(shù)即閉包,只有函數(shù)才會產生作用域的概念
閉包 的最大用處有兩個,一個是可以讀取函數(shù)內部的變量,另一個就是讓這些變量始終保持在內存中
閉包的另一個用處,是封裝對象的私有屬性和私有方法
閉包的好處
能夠實現(xiàn)封裝和緩存等
閉包的壞處
就是消耗內存、不正當使用會造成內存溢出的問題
使用閉包的注意點
由于閉包會使得函數(shù)中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露
解決方法是:在退出函數(shù)之前,將不使用的局部變量全部刪除
閉包的經典問題
for(var i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000); }這段代碼輸出
答案:3個3 解析:首先,for 循環(huán)是同步代碼,先執(zhí)行三遍 for,i 變成了 3;然后,再執(zhí)行異步代碼 setTimeout,這時候輸出的 i,只能是 3 個 3 了有什么辦法依次輸出0 1 2
第一種方法
使用let
for(let i = 0; i < 3; i++) {setTimeout(function() {console.log(i);}, 1000); }在這里,每個 let 和代碼塊結合起來形成塊級作用域,當 setTimeout() 打印時,會尋找最近的塊級作用域中的 i,所以依次打印出 0 1 2
如果這樣不明白,我們可以執(zhí)行下邊這段代碼
for(let i = 0; i < 3; i++) {console.log("定時器外部:" + i);setTimeout(function() {console.log(i);}, 1000); }此時瀏覽器依次輸出的是:
定時器外部:0 定時器外部:1 定時器外部:2 0 1 2即代碼還是先執(zhí)行 for 循環(huán),但是當 for 結束執(zhí)行到了 setTimeout 的時候,它會做個標記,這樣到了 console.log(i) 中,i 就能找到這個塊中最近的變量定義
第二種方法
使用立即執(zhí)行函數(shù)解決閉包的問題
for(let i = 0; i < 3; i++) {(function(i){setTimeout(function() {console.log(i);}, 1000);})(i) }JS作用域及作用域鏈
作用域
在JavaScript中,作用域分為 全局作用域 和 函數(shù)作用域
全局作用域
代碼在程序的任何地方都能被訪問,window 對象的內置屬性都擁有全局作用域
函數(shù)作用域
在固定的代碼片段才能被訪問
例子:
作用域有上下級關系,上下級關系的確定就看函數(shù)是在哪個作用域下創(chuàng)建的。如上,fn作用域下創(chuàng)建了bar函數(shù),那么“fn作用域”就是“bar作用域”的上級。
作用域最大的用處就是隔離變量,不同作用域下同名變量不會有沖突。
變量取值:到創(chuàng)建 這個變量 的函數(shù)的作用域中取值
作用域鏈
一般情況下,變量取值到 創(chuàng)建 這個變量 的函數(shù)的作用域中取值。
但是如果在當前作用域中沒有查到值,就會向上級作用域去查,直到查到全局作用域,這么一個查找過程形成的鏈條就叫做作用域鏈
原型和原型鏈
原型和原型鏈的概念
每個對象都會在其內部初始化一個屬性,就是prototype(原型),當我們訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那么他就會去prototype里找這個屬性,這個prototype又會有自己的prototype,于是就這樣一直找下去
原型和原型鏈的關系
instance.constructor.prototype = instance.__proto__原型和原型鏈的特點
JavaScript對象是通過引用來傳遞的,我們創(chuàng)建的每個新對象實體中并沒有一份屬于自己的原型副本。當我們修改原型時,與之相關的對象也會繼承這一改變
當我們需要一個屬性的時,Javascript引擎會先看當前對象中是否有這個屬性, 如果沒有的
就會查找他的Prototype對象是否有這個屬性,如此遞推下去,一直檢索到 Object 內建對象
組件化和模塊化
組件化
為什么要組件化開發(fā)
有時候頁面代碼量太大,邏輯太多或者同一個功能組件在許多頁面均有使用,維護起來相當復雜,這個時候,就需要組件化開發(fā)來進行功能拆分、組件封裝,已達到組件通用性,增強代碼可讀性,維護成本也能大大降低
組件化開發(fā)的優(yōu)點
很大程度上降低系統(tǒng)各個功能的耦合性,并且提高了功能內部的聚合性。這對前端工程化及降低代碼的維護來說,是有很大的好處的,耦合性的降低,提高了系統(tǒng)的伸展性,降低了開發(fā)的復雜度,提升開發(fā)效率,降低開發(fā)成本
組件化開發(fā)的原則
-
專一
-
可配置性
-
標準性
-
復用性
-
可維護性
模塊化
為什么要模塊化
早期的javascript版本沒有塊級作用域、沒有類、沒有包、也沒有模塊,這樣會帶來一些問題,如復用、依賴、沖突、代碼組織混亂等,隨著前端的膨脹,模塊化顯得非常迫切
模塊化的好處
-
避免變量污染,命名沖突
-
提高代碼復用率
-
提高了可維護性
-
方便依賴關系管理
模塊化的幾種方法
- 函數(shù)封裝
- 立即執(zhí)行函數(shù)表達式(IIFE)
圖片的預加載和懶加載
- 預加載:提前加載圖片,當用戶需要查看時可直接從本地緩存中渲染
- 懶加載:懶加載的主要目的是作為服務器前端的優(yōu)化,減少請求數(shù)或延遲請求數(shù)
mouseover和mouseenter的區(qū)別
mouseover:當鼠標移入元素或其子元素都會觸發(fā)事件,所以有一個重復觸發(fā),冒泡的過程。對應的移除事件是mouseout
mouseenter:當鼠標移除元素本身(不包含元素的子元素)會觸發(fā)事件,也就是不會冒泡,對應的移除事件是mouseleave
解決異步回調地獄
promise、generator、async/await
對This對象的理解
this總是指向函數(shù)的直接調用者(而非間接調用者)如果有new關鍵字,this指向new出來的那個對象
在事件中,this指向觸發(fā)這個事件的對象,特殊的是,IE中的attachEvent中的this總是指向全局對象Window
Vue
vue生命周期
什么是Vue生命周期?
Vue 實例從創(chuàng)建到銷毀的過程,就是生命周期。也就是從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是 Vue 的生命周期
Vue生命周期的作用是什么?
它的生命周期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯
Vue生命周期總共有幾個階段?
它可以總共分為8個階段:創(chuàng)建前/后, 載入前/后,更新前/后,銷毀前/銷毀后
第一次頁面加載會觸發(fā)哪幾個鉤子?
第一次頁面加載時會觸發(fā) beforeCreate, created, beforeMount, mounted 這幾個鉤子
DOM渲染在哪個周期中就已經完成?
DOM 渲染在 mounted 中就已經完成了
每個生命周期適合哪些場景?
生命周期鉤子的一些使用方法:
beforecreate : 可以在這加個loading事件,在加載實例時觸發(fā)
created : 初始化完成時的事件寫在這里,如在這結束loading事件,異步請求也適宜在這里調用
mounted : 掛載元素,獲取到DOM節(jié)點
updated : 如果對數(shù)據(jù)統(tǒng)一處理,在這里寫上相應函數(shù)
beforeDestroy : 可以做一個確認停止事件的確認框
nextTick : 更新數(shù)據(jù)后立即操作dom
v-show與v-if區(qū)別
v-show是css切換,v-if是完整的銷毀和重新創(chuàng)建使用 頻繁切換時用v-show,運行時較少改變時用v-if
v-if=‘false’ v-if是條件渲染,當false的時候不會渲染
開發(fā)中常用的指令有哪些
v-model :一般用在表達輸入,很輕松的實現(xiàn)表單控件和數(shù)據(jù)的雙向綁定v-html: 更新元素的 innerHTML
v-show 與 v-if: 條件渲染, 注意二者區(qū)別
綁定class的數(shù)組用法
對象方法 v-bind:class="{'orange': isRipe, 'green': isNotRipe}"數(shù)組方法 v-bind:class="[class1, class2]"
行內 v-bind:style="{color: color, fontSize: fontSize+‘px’ }"
組件之間的傳值通信
父組件給子組件傳值
使用props,父組件可以使用props向子組件傳遞數(shù)據(jù)
父組件vue模板father.vue
<template><child :msg="message"></child> </template><script> import child from './child.vue'; export default {components: {child},data () {return {message: 'father message';}} } </script>子組件vue模板child.vue:
<template><div>{{msg}}</div> </template><script> export default {props: {msg: {type: String,required: true}} } </script>子組件向父組件通信
父組件向子組件傳遞事件方法,子組件通過$emit觸發(fā)事件,回調給父組件
父組件vue模板father.vue:
<template><child @msgFunc="func"></child> </template><script> import child from './child.vue'; export default {components: {child},methods: {func (msg) {console.log(msg);}} } </script>子組件vue模板child.vue:
<template><button @click="handleClick">點我</button> </template><script> export default {props: {msg: {type: String,required: true}},methods () {handleClick () {//........this.$emit('msgFunc');}} } </script>非父子,兄弟組件之間通信
可以通過實例一個vue實例Bus作為媒介,要相互通信的兄弟組件之中,都引入Bus,然后通過分別調用Bus事件觸發(fā)和監(jiān)聽來實現(xiàn)通信和參數(shù)傳遞
Bus.js可以是這樣:
import Vue from 'vue' export default new Vue()在需要通信的組件都引入Bus.js:
<template><button @click="toBus">子組件傳給兄弟組件</button> </template><script> import Bus from '../common/js/bus.js' export default{methods: {toBus () {Bus.$emit('on', '來自兄弟組件')}} } </script>另一個組件也import Bus.js 在鉤子函數(shù)中監(jiān)聽on事件
import Bus from '../common/js/bus.js' export default {data() {return {message: ''}},mounted() {Bus.$on('on', (msg) => {this.message = msg})}}路由跳轉方式
1,<router-link to='home'> router-link標簽會渲染為<a>標簽,咋填template中的跳轉都是這種;2,另一種是編程是導航 也就是通過js跳轉 比如 router.push('/home')MVVM
M - Model,Model 代表數(shù)據(jù)模型,也可以在 Model 中定義數(shù)據(jù)修改和操作的業(yè)務邏輯V - View,View 代表 UI 組件,它負責將數(shù)據(jù)模型轉化為 UI 展現(xiàn)出來VM - ViewModel,ViewModel 監(jiān)聽模型數(shù)據(jù)的改變和控制視圖行為、處理用戶交互,簡單理解就是一個同步 View 和 Model 的對象,連接 Model 和 Viewcomputed和watch有什么區(qū)別?
computed:
1. computed是計算屬性,也就是計算值,它更多用于計算值的場景 2. computed具有緩存性,computed的值在getter執(zhí)行后是會緩存的,只有在它依賴的屬性值改變之后,下一次獲取computed的值時才會重新調用對應的getter來計算 3. computed適用于計算比較消耗性能的計算場景watch:
1. 更多的是「觀察」的作用,類似于某些數(shù)據(jù)的監(jiān)聽回調,用于觀察props $emit或者本組件的值,當數(shù)據(jù)變化時來執(zhí)行回調進行后續(xù)操作 2. 無緩存性,頁面重新渲染時值不變化也會執(zhí)行小結:
1. 當我們要進行數(shù)值計算,而且依賴于其他數(shù)據(jù),那么把這個數(shù)據(jù)設計為computed 2. 如果你需要在某個數(shù)據(jù)變化時做一些事情,使用watch來觀察這個數(shù)據(jù)變化key
key是為Vue中的vnode標記的唯一id,通過這個key,我們的diff操作可以 更準確、更快速
準確:
如果不加key,那么vue會選擇復用節(jié)點(Vue的就地更新策略),導致之前節(jié)點的狀態(tài)被保留下來,會產生一系列的bug
快速:
key的唯一性可以被Map數(shù)據(jù)結構充分利用
組件中的data為什么是函數(shù)?
為什么組件中的data必須是一個函數(shù),然后return一個對象,而new Vue實例里,data可以直接是一個對象?
// data data() {return {message: "子組件",childName:this.name} }// new Vue new Vue({el: '#app',router,template: '<App/>',components: {App} })因為組件是用來復用的,JS里對象是引用關系,這樣作用域沒有隔離,而new Vue的實例,是不會被復用的,因此不存在引用對象問題
Class 與 Style 如何動態(tài)綁定?
Class 可以通過對象語法和數(shù)組語法進行動態(tài)綁定:
對象語法
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>data: {isActive: true,hasError: false }數(shù)組語法
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>data: {activeClass: 'active',errorClass: 'text-danger' }Style 也可以通過對象語法和數(shù)組語法進行動態(tài)綁定:
對象語法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>data: {activeColor: 'red',fontSize: 30 }數(shù)組語法
<div v-bind:style="[styleColor, styleSize]"></div>data: {styleColor: {color: 'red'},styleSize:{fontSize:'23px'} }vue的單項數(shù)據(jù)流
所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態(tài),從而導致你的應用的數(shù)據(jù)流向難以理解
額外的,每次父級組件發(fā)生更新時,子組件中所有的 prop 都將會刷新為最新的值。這意味著你不應該在一個子組件內部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制臺中發(fā)出警告。子組件想修改時,只能通過 $emit 派發(fā)一個自定義事件,父組件接收到后,由父組件修改
有兩種常見的試圖改變一個 prop 的情形 :
這個 prop 用來傳遞一個初始值;這個子組件接下來希望將其作為一個本地的 prop 數(shù)據(jù)來使用
在這種情況下,最好定義一個本地的 data 屬性并將這個 prop 用作其初始值:
props: ['initialCounter'], data: function () {return {counter: this.initialCounter} }這個 prop 以一種原始的值傳入且需要進行轉換
在這種情況下,最好使用這個 prop 的值來定義一個計算屬性
props: ['size'], computed: {normalizedSize: function () {return this.size.trim().toLowerCase()} }keep-alive
keep-alive 是 Vue 內置的一個組件,可以使被包含的組件保留狀態(tài),避免重新渲染 ,其有以下特性:
- 一般結合路由和動態(tài)組件一起使用,用于緩存組件;
- 提供 include 和 exclude 屬性,兩者都支持字符串或正則表達式, include 表示只有名稱匹配的組件會被緩存,exclude 表示任何名稱匹配的組件都不會被緩存 ,其中 exclude 的優(yōu)先級比 include 高;
- 對應兩個鉤子函數(shù) activated 和 deactivated ,當組件被激活時,觸發(fā)鉤子函數(shù) activated,當組件被移除時,觸發(fā)鉤子函數(shù) deactivated。
v-model 的原理
vue 項目中主要使用 v-model 指令在表單 input、textarea、select 等元素上創(chuàng)建雙向數(shù)據(jù)綁定,我們知道 v-model 本質上不過是語法糖,v-model 在內部為不同的輸入元素使用不同的屬性并拋出不同的事件:
- text 和 textarea 元素使用 value 屬性和 input 事件;
- checkbox 和 radio 使用 checked 屬性和 change 事件;
- select 字段將 value 作為 prop 并將 change 作為事件;
以 input 表單元素為例:
<input v-model='something'>相當于
<input v-bind:value="something" v-on:input="something = $event.target.value">如果在自定義組件中,v-model 默認會利用名為 value 的 prop 和名為 input 的事件,如下所示:
父組件: <ModelChild v-model="message"></ModelChild>子組件: <div>{{value}}</div>props:{value: String }, methods: {test1(){this.$emit('input', '小紅')}, },nextTick()
在下次DOM更新循環(huán)結束之后執(zhí)行延遲回調。在修改數(shù)據(jù)之后,立即使用的這個回調函數(shù),獲取更新后的DOM
// 修改數(shù)據(jù) vm.msg = 'Hello' // DOM 還未更新 Vue.nextTick(function () {// DOM 更新 })vue插槽
個人覺得這篇文章寫的還可以:https://www.cnblogs.com/chinabin1993/p/9115396.html
單個插槽
當子組件模板只有一個沒有屬性的插槽時, 父組件傳入的整個內容片段將插入到插槽所在的 DOM 位置, 并替換掉插槽標簽本身命名插槽
solt元素可以用一個特殊的特性name來進一步配置如何分發(fā)內容。 多個插槽可以有不同的名字。 這樣可以將父組件模板中 slot 位置, 和子組件 slot 元素產生關聯(lián),便于插槽內容對應傳遞作用域插槽
可以訪問組件內部數(shù)據(jù)的可復用插槽(reusable slot) 在父級中,具有特殊特性 slot-scope 的<template> 元素必須存在, 表示它是作用域插槽的模板。slot-scope 的值將被用作一個臨時變量名, 此變量接收從子組件傳遞過來的 prop 對象vue-router有哪幾種導航鉤子
第一種:是全局導航鉤子:router.beforeEach(to,from,next),作用:跳轉前進行判斷攔截
第二種:組件內的鉤子
第三種:單獨路由獨享組件
vuex
vuex是什么?
vuex 就是一個倉庫,倉庫里放了很多對象。其中 state 就是數(shù)據(jù)源存放地,對應于一般 vue 對象里面的 datastate 里面存放的數(shù)據(jù)是響應式的,vue 組件從 store 讀取數(shù)據(jù),若是 store 中的數(shù)據(jù)發(fā)生改變,依賴這相數(shù)據(jù)的組件也會發(fā)生更新它通過 mapState 把全局的 state 和 getters 映射到當前組件的 computed 計算屬性Vuex有5種屬性: 分別是 state、getter、mutation、action、module;
state
Vuex 使用單一狀態(tài)樹,即每個應用將僅僅包含一個store 實例,但單一狀態(tài)樹和模塊化并不沖突。存放的數(shù)據(jù)狀態(tài),不可以直接修改里面的數(shù)據(jù)
mutations
mutations定義的方法動態(tài)修改Vuex 的 store 中的狀態(tài)或數(shù)據(jù)
getters
類似vue的計算屬性,主要用來過濾一些數(shù)據(jù)
action
actions可以理解為通過將mutations里面處里數(shù)據(jù)的方法變成可異步的處理數(shù)據(jù)的方法,簡單的說就是異步操作數(shù)據(jù)。view 層通過 store.dispath 來分發(fā) action
總結
vuex 一般用于中大型 web 單頁應用中對應用的狀態(tài)進行管理,對于一些組件間關系較為簡單的小型應用,使用 vuex 的必要性不是很大,因為完全可以用組件 prop 屬性或者事件來完成父子組件之間的通信,vuex 更多地用于解決跨組件通信以及作為數(shù)據(jù)中心集中式存儲數(shù)據(jù)
你有對 Vue 項目進行哪些優(yōu)化?
代碼層面的優(yōu)化
v-if 和 v-show 區(qū)分使用場景 computed 和 watch 區(qū)分使用場景 v-for 遍歷必須為 item 添加 key,且避免同時使用 v-if 長列表性能優(yōu)化 事件的銷毀 圖片資源懶加載 路由懶加載 第三方插件的按需引入 優(yōu)化無限列表性能 服務端渲染 SSR or 預渲染Webpack 層面的優(yōu)化
Webpack 對圖片進行壓縮 減少 ES6 轉為 ES5 的冗余代碼 提取公共代碼 模板預編譯 提取組件的 CSS 優(yōu)化 SourceMap 構建結果輸出分析 Vue 項目的編譯優(yōu)化基礎的 Web 技術的優(yōu)化
開啟 gzip 壓縮 瀏覽器緩存 CDN 的使用 使用 Chrome Performance 查找性能瓶頸ES6
var、let、const之間的區(qū)別
var聲明變量可以重復聲明,而let不可以重復聲明var是不受限于塊級的,而let是受限于塊級
var會與window相映射(會掛一個屬性),而let不與window相映射
var可以在聲明的上面訪問變量,而let有暫存死區(qū),在聲明的上面訪問變量會報錯
const聲明之后必須賦值,否則會報錯
const定義不可變的量,改變了就會報錯
const和let一樣不會與window相映射、支持塊級作用域、在聲明的上面訪問變量會報錯
解構賦值
數(shù)組解構
let [a, b, c] = [1, 2, 3] //a=1, b=2, c=3 let [d, [e], f] = [1, [2], 3] //嵌套數(shù)組解構 d=1, e=2, f=3 let [g, ...h] = [1, 2, 3] //數(shù)組拆分 g=1, h=[2, 3] let [i,,j] = [1, 2, 3] //不連續(xù)解構 i=1, j=3 let [k,l] = [1, 2, 3] //不完全解構 k=1, l=2對象解構
let {a, b} = {a: 'aaaa', b: 'bbbb'} //a='aaaa' b='bbbb' let obj = {d: 'aaaa', e: {f: 'bbbb'}} let {d, e:{f}} = obj //嵌套解構 d='aaaa' f='bbbb' let g; (g = {g: 'aaaa'}) //以聲明變量解構 g='aaaa' let [h, i, j, k] = 'nice' //字符串解構 h='n' i='i' j='c' k='e'函數(shù)參數(shù)的定義
一般我們在定義函數(shù)的時候,如果函數(shù)有多個參數(shù)時,在es5語法中函數(shù)調用時參數(shù)必須一一對應,否則就會出現(xiàn)賦值錯誤的情況,來看一個例子:
function personInfo(name, age, address, gender) {console.log(name, age, address, gender) } personInfo('william', 18, 'changsha', 'man')上面這個例子在對用戶信息的時候需要傳遞四個參數(shù),且需要一一對應,這樣就會極易出現(xiàn)參數(shù)順序傳錯的情況,從而導致bug,接下來來看es6解構賦值是怎么解決這個問題的:
function personInfo({name, age, address, gender}) {console.log(name, age, address, gender) } personInfo({gender: 'man', address: 'changsha', name: 'william', age: 18})這么寫我們只知道要傳聲明參數(shù)就行來,不需要知道參數(shù)的順序也沒關系
交換變量的值
在es5中我們需要交換兩個變量的值需要借助臨時變量的幫助,來看一個例子:
var a=1, b=2, c c = a a = b b = c console.log(a, b)來看es6怎么實現(xiàn):
let a=1, b=2; [b, a] = [a, b] console.log(a, b)是不是比es5的寫法更加方便呢
函數(shù)默認參數(shù)
在日常開發(fā)中,經常會有這種情況:函數(shù)的參數(shù)需要默認值,如果沒有默認值在使用的時候就會報錯,來看es5中是怎么做的:
function saveInfo(name, age, address, gender) {name = name || 'william'age = age || 18address = address || 'changsha'gender = gender || 'man'console.log(name, age, address, gender) } saveInfo()在函數(shù)離 main先對參數(shù)做一個默認值賦值,然后再使用避免使用的過程中報錯,再來看es6中的使用的方法:
function saveInfo({name= 'william', age= 18, address= 'changsha', gender= 'man'} = {}) {console.log(name, age, address, gender) } saveInfo()在函數(shù)定義的時候就定義了默認參數(shù),這樣就免了后面給參數(shù)賦值默認值的過程,是不是看起來簡單多了
forEach、for in、for of三者區(qū)別
forEach更多的用來遍歷數(shù)for in 一般常用來遍歷對象或json
for of數(shù)組對象都可以遍歷,遍歷對象需要通過和Object.keys()
for in循環(huán)出的是key,for of循環(huán)出的是value
使用箭頭函數(shù)應注意什么?
1、用了箭頭函數(shù),this就不是指向window,而是父級(指向是可變的)
2、不能夠使用arguments對象
3、不能用作構造函數(shù),這就是說不能夠使用new命令,否則會拋出一個錯誤
4、不可以使用yield命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)
Set、Map的區(qū)別
應用場景Set用于數(shù)據(jù)重組,Map用于數(shù)據(jù)儲存
Set:
1,成員不能重復
2,只有鍵值沒有鍵名,類似數(shù)組
3,可以遍歷,方法有add, delete,has
Map:
1,本質上是健值對的集合,類似集合
2,可以遍歷,可以跟各種數(shù)據(jù)格式轉換
promise對象的用法,手寫一個promise
promise是一個構造函數(shù),下面是一個簡單實例
var promise = new Promise((resolve,reject) => {if (操作成功) {resolve(value)} else {reject(error)} }) promise.then(function (value) {// success },function (value) {// failure })Ajax
如何創(chuàng)建一個ajax
(1)創(chuàng)建XMLHttpRequest對象,也就是創(chuàng)建一個異步調用對象
(2)創(chuàng)建一個新的HTTP請求,并指定該HTTP請求的方法、URL及驗證信息
(3)設置響應HTTP請求狀態(tài)變化的函數(shù)
(4)發(fā)送HTTP請求
(5)獲取異步調用返回的數(shù)據(jù)
(6)使用JavaScript和DOM實現(xiàn)局部刷新
同步和異步的區(qū)別
同步:
瀏覽器訪問服務器請求,用戶看得到頁面刷新,重新發(fā)請求,等請求完,頁面刷新,新內容出現(xiàn),用戶看到新內容,進行下一步操作
異步:
瀏覽器訪問服務器請求,用戶正常操作,瀏覽器后端進行請求。等請求完,頁面不刷新,新內容也會出現(xiàn),用戶看到新內容
ajax的優(yōu)點和缺點
ajax的優(yōu)點
1、無刷新更新數(shù)據(jù)(在不刷新整個頁面的情況下維持與服務器通信)
2、異步與服務器通信(使用異步的方式與服務器通信,不打斷用戶的操作)
3、前端和后端負載均衡(將一些后端的工作交給前端,減少服務器與寬度的負擔)
4、界面和應用相分離(ajax將界面和應用分離也就是數(shù)據(jù)與呈現(xiàn)相分離)
ajax的缺點
1、ajax不支持瀏覽器back按鈕
2、安全問題 Aajax暴露了與服務器交互的細節(jié)
3、對搜索引擎的支持比較弱
4、破壞了Back與History后退按鈕的正常行為等瀏覽器機制
get和post的區(qū)別
1、get和post在HTTP中都代表著請求數(shù)據(jù),其中get請求相對來說更簡單、快速,效率高些
2、get相對post安全性低
3、get有緩存,post沒有
4、get體積小,post可以無限大
5、get的url參數(shù)可見,post不可見
6、get只接受ASCII字符的參數(shù)數(shù)據(jù)類型,post沒有限制
7、get請求參數(shù)會保留歷史記錄,post中參數(shù)不會保留
8、get會被瀏覽器主動catch,post不會,需要手動設置
9、get在瀏覽器回退時無害,post會再次提交請求
什么時候使用post?
post一般用于修改服務器上的資源,對所發(fā)送的信息沒有限制。比如
1、無法使用緩存文件(更新服務器上的文件或數(shù)據(jù)庫)
2、向服務器發(fā)送大量數(shù)據(jù)(POST 沒有數(shù)據(jù)量限制)
3、發(fā)送包含未知字符的用戶輸入時,POST 比 GET 更穩(wěn)定也更可靠
如何解決跨域問題
跨域的概念:協(xié)議、域名、端口都相同才同域,否則都是跨域
解決跨域問題:
1、使用JSONP(json+padding)把數(shù)據(jù)內填充起來
2、CORS方式(跨域資源共享),在后端上配置可跨域
3、服務器代理,通過服務器的文件能訪問第三方資源
什么是Ajax和JSON,它們的優(yōu)點和缺點
Ajax:
Ajax是異步JavaScript和XML,用于在Web頁面中實現(xiàn)異步數(shù)據(jù)交互
Ajax優(yōu)點:
異步請求響應快,用戶體驗好;頁面無刷新、數(shù)據(jù)局部更新;按需取數(shù)據(jù),減少了冗余請求和服務器的負擔;
Ajax缺點:
異步回調問題、this指向問題、路由跳轉back問題;對搜索引擎的支持比較弱,對于一些手機還不是很好的支持
JSON:
是一種輕量級的數(shù)據(jù)交換格式,看著像對象,本質是字符串
JSON優(yōu)點:
輕量級、易于人的閱讀和編寫,便于js解析,支持復合數(shù)據(jù)類型
JSON缺點:
沒有XML格式這么推廣的深入人心和使用廣泛, 沒有XML那么通用性
Github
git常用的命令
從遠程庫克隆到本地:git clone 網站上的倉庫地址新增文件的命令:git add .
提交文件的命令:git commit –m或者git commit –a
查看工作區(qū)狀況:git status –s
拉取合并遠程分支的操作:git fetch/git merge或者git pull
查看提交記錄命令:git reflog
webpack
webpack打包原理
webpack只是一個打包模塊的機制,只是把依賴的模塊轉化成可以代表這些包的靜態(tài)文件。webpack就是識別你的 入口文件。識別你的模塊依賴,來打包你的代碼。至于你的代碼使用的是commonjs還是amd或者es6的import。webpack都會對其進行分析。來獲取代碼的依賴。webpack做的就是分析代碼。轉換代碼,編譯代碼,輸出代碼。webpack本身是一個node的模塊,所以webpack.config.js是以commonjs形式書寫的(node中的模塊化是commonjs規(guī)范的)
模塊熱更新
模塊熱更新是webpack的一個功能,他可以使代碼修改過后不用刷新就可以更新,是高級版的自動刷新瀏覽器
devServer中通過hot屬性可以控制模塊的熱替換
通過配置文件
const webpack = require('webpack'); const path = require('path'); let env = process.env.NODE_ENV == "development" ? "development" : "production"; const config = {mode: env,devServer: {hot:true} }plugins: [new webpack.HotModuleReplacementPlugin(), //熱加載插件], module.exports = config;通過命令行
"scripts": {"test": "echo \"Error: no test specified\" && exit 1","start": "NODE_ENV=development webpack-dev-server --config webpack.develop.config.js --hot",},如何提高webpack構建速度
1、通過externals配置來提取常用庫
2、利用DllPlugin和DllReferencePlugin預編譯資源模塊 通過DllPlugin來對那些我們引用但是絕對不會修改的npm包來進行預編譯,再通過DllReferencePlugin將預編譯的模塊加載進來
3、使用Happypack 實現(xiàn)多線程加速編譯
要注意的第一點是,它對file-loader和url-loader支持不好,所以這兩個loader就不需要換成happypack了,其他loader可以類似地換一下
4、使用Tree-shaking和Scope Hoisting來剔除多余代碼
5、使用fast-sass-loader代替sass-loader
6、babel-loader開啟緩存
babel-loader在執(zhí)行的時候,可能會產生一些運行期間重復的公共文件,造成代碼體積大冗余,同時也會減慢編譯效率
可以加上cacheDirectory參數(shù)或使用 transform-runtime 插件試試
不需要打包編譯的插件庫換成全局"script"標簽引入的方式
比如jQuery插件,react, react-dom等,代碼量是很多的,打包起來可能會很耗時
可以直接用標簽引入,然后在webpack配置里使用 expose-loader 或 externals 或 ProvidePlugin 提供給模塊內部使用相應的變量
8、優(yōu)化構建時的搜索路徑
在webpack打包時,會有各種各樣的路徑要去查詢搜索,我們可以加上一些配置,讓它搜索地更快
比如說,方便改成絕對路徑的模塊路徑就改一下,以純模塊名來引入的可以加上一些目錄路徑
還可以善于用下resolve alias別名 這個字段來配置
還有exclude等的配置,避免多余查找的文件,比如使用babel別忘了剔除不需要遍歷的
webpack的優(yōu)點
專注于處理模塊化的項目,能做到開箱即用,一步到位可通過plugin擴展,完整好用又不失靈活
使用場景不局限于web開發(fā)
社區(qū)龐大活躍,經常引入緊跟時代發(fā)展的新特性,能為大多數(shù)場景找到已有的開源擴展
良好的開發(fā)體驗
webpack的缺點
webpack的缺點是只能用于采用模塊化開發(fā)的項目
微信小程序
文件主要目錄及文件作用
- component —————————————————— 組件文件夾- navBar —— 底部組件- navBar.js —— 底部組件的 JS 代碼- navBar.json —— 底部組件的配置文件- navBar.wxml —— 底部組件的 HTML 代碼- navBar.wxss —— 底部組件的 CSS 代碼 - pages ————————————————————— 頁面文件夾- index —— 首頁- index.js —— 首頁的 JS 代碼- index.json —— 首頁的配置文件- index.wxml —— 首頁的 HTML 代碼- index.wxss —— 首頁的 CSS 代碼 - public ————————————————————— 圖片文件夾 - utils —————————————————————— 工具文件夾- api.js —— 控制 API 的文件- md5.js —— 工具 - MD5 加密文件- timestamp.js —— 工具 - 時間戳文件 - app.json ——————————————————— 設置全局的基礎數(shù)據(jù)等 - app.wxss ——————————————————— 公共樣式,可通過 import 導入更多 - project.config.json ———————— 項目配置文件微信小程序生命周期
onLoad():頁面加載時觸發(fā)。 onShow():頁面顯示/切入前臺時觸發(fā)。 onReady():頁面初次渲染完成時觸發(fā)。 onHide():頁面隱藏/切入后臺時觸發(fā)。 onUnload():頁面卸載時觸發(fā)。如何封裝數(shù)據(jù)請求
1,封裝接口
項目/utils/api.js
// 將請求進行 Promise 封裝 const fetch = ({url, data}) => {// 打印接口請求的信息console.log(`【step 1】API 接口:${url}`);console.log("【step 2】data 傳參:");console.log(data);// 返回 Promisereturn new Promise((resolve, reject) => {wx.request({url: getApp().globalData.api + url,data: data,success: res => {// 成功時的處理 if (res.data.code == 0) {console.log("【step 3】請求成功:");console.log(res.data);return resolve(res.data);} else {wx.showModal({title: '請求失敗',content: res.data.message,showCancel: false});}},fail: err => {// 失敗時的處理console.log(err);return reject(err);}})})}/*** code 換取 openId* @data {* jsCode - wx.login() 返回的 code* }*/ export const wxLogin = data => {return fetch({url: "tbcUser/getWechatOpenId",data: data}) }2,調用接口
項目/pages/login/login.js
import {wxLogin, } from '../../utils/api.js'3,使用接口
項目/pages/login/login.js
wxLogin({jsCode: this.data.code }).then(res => {console.log("【step 4】返回成功處理:");console.log(res.data);},err => {console.log("【step 4】返回失敗處理:");console.log(err);} )頁面數(shù)據(jù)傳遞
通過 url 攜帶參數(shù),在 onLoad() 中通過 options 獲取 url 上的參數(shù):
<navigator url="../index/index?userId={{userId}}"></navigator><!-- 這兩段是分別在 HTML 和 JS 中的代碼 -->onLoad: function(options) {console.log(options.userId); }通過 Storage 來傳遞參數(shù):
wx.setStorageSync('userId', 'jsliang'); wx.getStorageSync('userId');WXML傳遞數(shù)據(jù)到 JS
login.wxml
<text bindtap="clickText" data-labelId="{{userId}}">點擊傳遞數(shù)據(jù)到 JS</text>login.js
clickText(e) {console.log(e.currentTarget.labelid) }組件調用傳參
組件接收數(shù)據(jù):component-tag-name
Component({properties: {// 這里定義了innerText屬性,屬性值可以在組件使用時指定innerText: {type: String,value: 'default value',}} })使用組件的頁面定義 json
{"usingComponents": {"component-tag-name": "../component/component"} }使用組件的頁面 HTML 代碼
<view><!-- 以下是對一個自定義組件的引用 --><component-tag-name inner-text="Some text"></component-tag-name> </view>通過接口調用傳遞參數(shù)
加載性能優(yōu)化方法
1、通過 this.$preload() 預加載用戶可能點擊的第二個頁面2、組件化頁面,出現(xiàn)兩次以上的部分都進行封裝成組件
3、提取共用的 CSS 樣式
4、優(yōu)化圖片:TinyPNG
微信小程序與原生APP、Vue、H5差異
微信小程序優(yōu)勢
1、無需下載
2、打開速度較快
3、開發(fā)成本低于原生APP
微信小程序劣勢
1、限制多。頁面大小不能超過 1M,不能打開超過 5 個層級的頁面
2、樣式單一。小程序內部組件已經成宿,樣式不可以修改
3、推廣面窄。跑不出微信,還不能跑入朋友圈
微信小程序 VS 原生APP
微信小程序有著低開發(fā)成本、低獲客成本、無需下載的優(yōu)勢
微信小程序 VS H5
1、依賴環(huán)境不同。一個能在多種手機瀏覽器運行。一個只能在微信中的非完整的瀏覽器
2、開發(fā)成本不同。一個可能在各種瀏覽器出問題。一個只能在微信中運行
微信小程序 VS Vue
微信小程序看似就是閹割版的 Vue
微信小程序原理
本質上就是一個單頁面應用,所有的頁面渲染和事件處理,都在一個頁面中進行
架構為數(shù)據(jù)驅動的模式,UI 和數(shù)據(jù)分離,所有頁面的更新,都需要通過對數(shù)據(jù)的更改來實現(xiàn)
微信小程序分為兩個部分:webview 和 appService。其中 webview 主要用來展示 UI,appServer 用來處理業(yè)務邏輯、數(shù)據(jù)及接口調用。它們在兩個進程中進行,通過系統(tǒng)層 JSBridge 實現(xiàn)通信,實現(xiàn) UI 的渲染、事件的處理
wxml與標準的html的異同
wxml基于xml設計,標簽只能在微信小程序中使用,不能使用html的標簽
網絡協(xié)議
網絡分層
目前網絡分層可分為兩種:OSI 模型和 TCP/IP 模型
OSI模型
應用層(Application)
表示層(Presentation)
會話層(Session)
傳輸層(Transport)
網絡層(Network)
數(shù)據(jù)鏈路層(Data Link)
物理層(Physical)
TCP/IP模型
應用層(Application)
傳輸層(Host-to-Host Transport)
互聯(lián)網層(Internet)
網絡接口層(Network Interface)
HTTP/HTTPS
1、https協(xié)議需要到ca申請證書,一般免費證書較少,因而需要一定費用
2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443
4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構建的可進行加密傳輸、身份認證的網絡協(xié)議,比http協(xié)議安全。
HTTP狀態(tài)碼
區(qū)分狀態(tài)碼
1××開頭 - 信息提示
2××開頭 - 請求成功
3××開頭 - 請求被重定向
4××開頭 - 請求錯誤
5××開頭 - 服務器錯誤
常見狀態(tài)碼
200 - 請求成功,Ajax 接受到信息了
400 - 服務器不理解請求
403 - 服務器拒絕請求
404 - 請求頁面錯誤
500 - 服務器內部錯誤,無法完成請求
性能優(yōu)化
HTML優(yōu)化
1、避免 HTML 中書寫 CSS 代碼,因為這樣難以維護。 2、使用 Viewport 加速頁面的渲染。 3、使用語義化標簽,減少 CSS 代碼,增加可讀性和 SEO。 4、減少標簽的使用,DOM 解析是一個大量遍歷的過程,減少不必要的標簽,能降低遍歷的次數(shù)。 5、避免 src、href 等的值為空,因為即時它們?yōu)榭?#xff0c;瀏覽器也會發(fā)起 HTTP 請求。 6、減少 DNS 查詢的次數(shù)CSS優(yōu)化
1、優(yōu)化選擇器路徑:使用 .c {} 而不是 .a .b .c {}。 2、選擇器合并:共同的屬性內容提起出來,壓縮空間和資源開銷。 3、精準樣式:使用 padding-left: 10px 而不是 padding: 0 0 0 10px。 4、雪碧圖:將小的圖標合并到一張圖中,這樣所有的圖片只需要請求一次。 5、避免通配符:.a .b * {} 這樣的選擇器,根據(jù)從右到左的解析順序在解析過程中遇到通配符 * {} 6、會遍歷整個 DOM,性能大大損耗。 7、少用 float:float 在渲染時計算量比較大,可以使用 flex 布局。 8、為 0 值去單位:增加兼容性。 9、壓縮文件大小,減少資源下載負擔。JavaScript優(yōu)化
1、盡可能把 <script> 標簽放在 body 之后,避免 JS 的執(zhí)行卡住 DOM 的渲染,最大程度保證頁面盡快地展示出來 2、盡可能合并 JS 代碼:提取公共方法,進行面向對象設計等…… 3、CSS 能做的事情,盡量不用 JS 來做,畢竟 JS 的解析執(zhí)行比較粗暴,而 CSS 效率更高。 4、盡可能逐條操作 DOM,并預定好 CSs 樣式,從而減少 reflow 或者 repaint 的次數(shù)。 5、盡可能少地創(chuàng)建 DOM,而是在 HTML 和 CSS 中使用 display: none 來隱藏,按需顯示。 6、壓縮文件大小,減少資源下載負擔。面試常見的其他問題
常問
1、自我介紹
2、你的項目中技術難點是什么?遇到了什么問題?你是怎么解決的?
3、你認為哪個項目做得最好?
4、平時是如何學習前端開發(fā)的?
5、你最有成就感的一件事
6、你是怎么學習前端的
人事面
1、面試完你還有什么問題要問的嗎
2、你有什么愛好?
3、你最大的優(yōu)點和缺點是什么?
4、你為什么會選擇這個行業(yè),職位?
5、你覺得你適合從事這個崗位嗎?
6、你有什么職業(yè)規(guī)劃?
7、你對工資有什么要求?
8、如何看待前端開發(fā)?
9、未來三到五年的規(guī)劃是怎樣的?
其他
談談你對重構的理解?
網絡重構:在不改變外部行為的前提下,簡化結構、添加可讀性,而在網站前端保持一致的行為。也就是說是在不改變UI的情況下,對網站進行優(yōu)化, 在擴展的同時保持一致的UI
對于傳統(tǒng)的網站來說重構通常是:
- 表格(table)布局改為DIV+CSS
- 使網站前端兼容于現(xiàn)代瀏覽器(針對于不合規(guī)范的CSS、如對IE6有效的)
- 對于移動平臺的優(yōu)化
- 針對于SEO進行優(yōu)化
什么樣的前端代碼是好的?
高復用低耦合,這樣文件小,好維護,而且好擴展
對前端工程師這個職位是怎么樣理解的?它的前景會怎么樣?
前端是最貼近用戶的程序員,比后端、數(shù)據(jù)庫、產品經理、運營、安全都近
- 實現(xiàn)界面交互
- 提升用戶體驗
- 有了Node.js,前端可以實現(xiàn)服務端的一些事情
前端是最貼近用戶的程序員,前端的能力就是能讓產品從 90分進化到 100 分,甚至更好,
與團隊成員,UI設計,產品經理的溝通;
做好的頁面結構,頁面重構和用戶體驗;
你覺得前端工程的價值體現(xiàn)在哪?
1、為簡化用戶使用提供技術支持(交互部分)
2、為多個瀏覽器兼容性提供支持
3、為提高用戶瀏覽速度(瀏覽器性能)提供支持
4、為跨平臺或者其他基于webkit或其他渲染引擎的應用提供支持
5、為展示數(shù)據(jù)提供支持(數(shù)據(jù)接口)
平時如何管理你的項目?
-
先期團隊必須確定好全局樣式(globe.css),編碼模式(utf-8) 等;
-
編寫習慣必須一致(例如都是采用繼承式的寫法,單樣式都寫成一行);
-
標注樣式編寫人,各模塊都及時標注(標注關鍵樣式調用的地方);
-
頁面進行標注(例如 頁面 模塊 開始和結束);
-
CSS跟HTML 分文件夾并行存放,命名都得統(tǒng)一(例如style.css);
-
JS 分文件夾存放 命名以該JS功能為準的英文翻譯。
-
圖片采用整合的 images.png png8 格式文件使用 - 盡量整合在一起使用方便將來的管理
移動端(Android IOS)怎么做好用戶體驗?
清晰的視覺縱線、
信息的分組、極致的減法、
利用選擇代替輸入、
標簽及文字的排布方式、
依靠明文確認密碼、
合理的鍵盤利用
最后
如果本文對你有幫助得話,給本文點個贊??????
歡迎大家加入,一起學習前端,共同進步!
總結
以上是生活随笔為你收集整理的初中级前端面试题—完整版的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编程故事很长,慢慢书写
- 下一篇: 第一次前端实习所学内容