前端面試題 :) 來源--知乎
作者:錘子
連結:(https://zhuanlan.zhihu.com/p/158797820
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
目錄- 作者:錘子連結:(https://zhuanlan.zhihu.com/p/158797820來源:知乎著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
- vue —— 資料驅動檢視
- react
- JS
- 微信小程式開發
- 移動端熱點問題
vue —— 資料驅動檢視
-
什麼是vue生命週期
vue每個元件都是獨立的,每個元件都有一個屬於它的生命週期,從一個元件建立、資料初始化、掛載、更新、銷燬,這就是一個元件所謂的生命週期。這給了使用者在不同階段新增自己的程式碼的機會。在元件中具體的方法有:
beforeCreate
> 在new一個vue例項後,只有一些預設的生命週期鉤子和預設事件,其他的東西都還沒建立;在beforeCreate生命週期執行的時候,data和methods中的資料都還沒有初始化。 不要created
> data和methods都已經初始化OK,如要需要,最早可以再這個階段操作beforeMount
> 執行到這個鉤子的時候,在記憶體中已經編譯好了模板了,但是還沒有掛在到頁面中mounted
> 表示vue例項已經初始化完成,此時元件脫離建立階段,進入執行階段,如果我們想要通過外掛操作頁面上的DOM節點,最早可以在這個階段進行beforeUpdate
> data中資料已更新,頁面還未同步updated
> 頁面顯示的資料和data中的資料已經保持同步activited
deadctivated
> keep-alive專屬,元件被銷燬時呼叫beforeDestroy
> vue例項從執行階段進入到會階段, but此時所有的data和methods, 指令, 過濾器... 都還處於可用狀態destroyed
> 此時所有的data, methods, 指令, 過濾器...都是處於不可用狀態, 元件正式被銷燬拓展: vue中內建方法, 屬性和生命週期的執行順序(methods、computed、data、watch、props)
data的初始化是在created時已經完成資料觀測(data observe), 並且諸如
methods
、computed
、props
等都已經初始化
props -> methods -> data -> computed -> watch
-
vue生命週期的作用是什麼
簡單總結就是可以在生命週期的不同階段呼叫對應的鉤子函式
-
第一次頁面載入會觸發哪些鉤子
beforeCreate,created,beforeMount,mounted
-
簡述每個週期具體適合那些場景
beforeCreate
: loading事件, 在載入例項時觸發created
: 初始化完成時的事件寫在這裡, 例如資料(非同步)請求, 也可以在此結束loading事件mounted
: 掛載元素, 獲取DOM節點updated
: 對資料統一處理, 在此寫響應函式beforeDestroy
: 可以做阻斷, 例如確認停止事件的確認框, 因為此時例項還未銷燬 -
created和mounted的區別
created
: 在模板渲染成HTML前呼叫,即通常初始化某些屬性值, 然後再渲染成檢視mounted
: 在模板渲染成HTML後呼叫, 通常是初始化頁面完成後, 在對HTML的DOM節點進行一些需要的操作(例如echart
這裡的操作可以放在這裡進行, 而不是created
裡) -
vue獲取資料在那個周期函式
一般建議放在
created
中, 如果有DOM操作就需要放在mounted
中 -
請詳細說下你對vue生命週期的理解
簡述生命週期的概念, 表明它可以讓使用者在對應的階段進行需要的操作, 列舉八大基礎鉤子, 也可以對常用的
created
和mounted
進行拓展補充
vue路由面試題
-
MVVM框架是什麼
MVVM > Model-View-ViewModel, 也就是把MVC中的controller演變成ViewModel.
Model : 資料模型, 可以再Model中定義資料修改和操作的業務邏輯. 我們也可以稱它為資料稱, 因為它僅關注資料本身, 不關心任何行為
View : 使用者操作介面(UI), 當ViewModel對Model進行更新的時候, 會通過資料繫結更新到View
ViewModel : 業務邏輯層, View需要什麼資料, ViewModel要提供這個資料; View有某些操作, ViewModel就要對其響應, 所以, 也可以說它是 Model for View
總結 : MVVM模式簡化了介面與業務的依賴, 解決了資料頻繁更新. MVVM在使用當中, 利用雙向繫結技術, 使得Model變化時, ViewModel會自動更新, 而ViewModel變化時, View也會自動變化
-
vue-router是什麼? 它有哪些元件
它是vue官方推薦使用的路由框架. 路由跳轉都需要vue-router. 它有三個基本的概念: route, routes, router
route
> 指一條路由, 由單詞也可以看出來, 它是單數routes
> 指一組路由, 把route組合起來, 形成一個數組, 即為routesrouter
> 是一個機制, 相當於一個管理者, 它管理著路由. 因為routes只是定義了一組路由, 他放在哪裡都是靜止的, router的作用就是當用戶點選路由對應的按鈕時, 它會到routes中去查詢, 從而實現頁面上的跳轉它有哪些元件?
<router-link :to='' active-class="active">//路由宣告式跳轉 ,active-class是標籤被點選時的樣式 <router-view> //渲染路由的容器 <keep-alive> //快取元件
-
active-class是哪個元件的屬性?
router-link
是用來做選中樣式的切換
使用方式:
// 1. 直接在路由js檔案中配置linkActiveClass export default new Router({ linkActiveClass: 'active' // 可以自定義類名~ }) // 2. 直接在router-link中寫入active-class <router-link :to='' active-class="active">
-
怎麼定義vue-router的動態路由?怎麼獲取傳過來的值
兩種方式 :
query
和params
基礎用法 : 都可以通過this.$router.push 跳轉
-
query :
// 點選事件中寫法; 推薦用path this.$router.push({ path: 'detail', query: { id: '1' } }) // 用name也不報錯 this.$router.push({ name: 'detail', query: { id: '1' } }) // router-link中寫法 <router-link to='/detail?id=1'> handleToDetail </router-link> // 傳參接收 this.pageId = this.$route.query.id // 注意此處為route // 注意: 若使用name跳轉動態路由, 需要在router中配置route的 'name' 屬性 /** router/index.js **/ { path: '/detail', name: 'detail', component: () => import('@/view/detail') }
-
params :
// 只能使用name this.$router.push({ name: 'detail', params: { id: '2' } }) // router-link中寫法 <router-link to="/detail/" + item.id></router-link> // 或者 <router-link to="{name: 'test', params: { id: this.pageId }}"></router-link> // 接收引數 this.pageId = this.$route.params.id /** router/index.js **/ { path: '/detail/:id', // 容易出問題的地方, :xx 必須和傳參時使用相同欄位 name: 'detail', // 一定要設定name,才可以傳params! component: ... }
區別 :
- query通過url傳參, 沒有也沒關係, params是路由的一部分, 必須在路由後面新增引數名
- params是路由的一部分, 如果這個路由配置中要求params傳參, 但是跳轉的時候沒有傳這個引數, 就會導致失敗或頁面無內容
- query 使用path傳參, params 使用name傳參
- 二者傳參的區別直白點可以理解為: query相當於get請求, 引數顯示在位址列; params相當於post請求, 引數不會在位址列中顯示
-
-
vue-router有哪幾種導航鉤子
vue-router的導航鉤子又叫導航守衛;導航表示路由正在發生改變,vue-router提供的導航守衛主要用來:通過跳轉或取消的方式守衛導航。有多種機會植入路由導航過程:全域性的,單個路由獨享的,元件級的。
注意:引數或查詢的改變並不會觸發進入/離開的導航守衛。你可以通過觀察$route物件來應對這些變化,或使用beforeRouteUpdate的元件內導航
-
全域性守衛: router.beforeEach
使用router.beforeEach 註冊一個全域性前置守衛
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { ... })
當一個導航觸發時,全域性前置守衛按照建立順序呼叫. 守衛是非同步解析執行, 此時導航在所有守衛resolve完之前一直處於等待中
每個守衛方法都接收三個引數
to: Route > 即將要進入的目標路由物件
from: Route > 當前導航正在離開的路由
next: Function > 一定要呼叫該方法來resolve這個鉤子. 執行結果依賴next方法的呼叫引數
next()
: 進行管道中下一個鉤子. 如果全部鉤子都執行完了, 則導航的狀態就是confirmed(確認的)next(false)
: 中斷當前的導航. 如果瀏覽器的url改變了(可能是使用者手動點選瀏覽器的後退按鈕), 那麼url地址會重置到from路由
對應的地址next( '/' )
或者next({ path: '/' })
: 跳轉到一個不同的地址. 當前的導航被中斷, 然後進行一個新的導航. 你可以向next傳遞任意位置物件
, 且允許設定諸如
replace: true, name: 'home' 之類的選項以及任何用在router-link
的to prop
或router.push
中的選項next(error)
: (2.4.0+) 如果傳入 next 的引數是一個 Error 例項,則導航會被終止
且該錯誤會被傳遞給router.onError()
註冊過的回撥。
-
全域性解析守衛: router.beforeResolve
2.5.0 新增
在
2.5.0+
你可以用router.beforeResolve
註冊一個全域性守衛
。這和router.beforeEach
類似,區別是:
在導航被確認之前
,同時在所有元件內守衛
和非同步路由元件
被解析之後
,解析守衛就被呼叫
。 -
全域性後置鉤子: router.afterEach
你也可以註冊
全域性後置鉤子
,然而和守衛不同的是
,這些鉤子不會接受 next 函式
也不會改變導航本身
:router.afterEach((to, from) => { // ... })
-
路由獨享的守衛: beforeEnter
你可以在路由配置上直接定義
beforeEnter
守衛:const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
這些守衛
與全域性前置守衛
的方法引數是一樣的
。 -
元件內的守衛: beforeRouteEnter、beforeRouteUpdate(2.2新增)、beforeRouteLeave
最後,你可以在
路由元件內
直接定義以下路由導航守衛
:beforeRouteEnter
、beforeRouteUpdate
(2.2 新增) 、beforeRouteLeave
const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染該元件的對應路由被 confirm 前呼叫 // 不!能!獲取元件例項 `this` // 因為當守衛執行前,元件例項還沒被建立 }, //不過,你可以通過傳一個回撥給 next來訪問元件例項。 //在導航被確認的時候執行回撥,並且把元件例項作為回撥方法的引數。 beforeRouteEnter (to, from, next) { next(vm => { // 通過 `vm` 訪問元件例項 }) }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,但是該元件被複用時呼叫 // 舉例來說,對於一個帶有動態引數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 由於會渲染同樣的 Foo 元件,因此元件例項會被複用。而這個鉤子就會在這個情況下被呼叫。 // 可以訪問元件例項 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該元件的對應路由時呼叫 // 可以訪問元件例項 `this` } }
注意:
beforeRouteEnter
是支援給next傳遞迴調
的唯一守衛。對於beforeRouteUpdate
和beforeRouteLeave
來說,this
已經可用了,所以不支援傳遞迴調
,因為沒有必要了:beforeRouteUpdate (to, from, next) { // just use `this` this.name = to.params.name next() }
離開守衛beforeRouteLeave:
通常用來禁止使用者在還未儲存修改前突然離開。該導航可以通過next(false)
來取消:beforeRouteLeave (to, from , next) { const answer = window.confirm('Do you really want to leave? you have unsaved changes!') if (answer) { next() } else { next(false) } }
-
-
route和router的區別
$router物件
-
$router 是全域性路由的例項, 是router構造方法的例項
-
路由例項方法:
-
push :
// 字串 this.$router.push('xxx') // 物件 this.$router.push({ path: 'xxx' }) // params this.$router.push({ name: 'xxx', params: { id: '1' } }) // query this.$router.push({ path: 'xxx', query: { id: '2' } })
注意:push方法的跳轉會向history棧新增一個新的記錄, 當我們點選瀏覽器的返回按鈕時可以看到之前的頁面
-
go :
頁面路由跳轉, 前進或者後退
this.$router.go(-1) // 後退1步 this.$router.go(1) // 前進1步
-
replact :
替換當前頁面, 不會向history棧新增新紀錄, 一般用來做404頁面
-
$route物件
-
$route物件表示當前啟用的路由物件, 包含了當前的路由資訊: 當前的路徑, 引數, query物件等等.
-
$route的屬性
-
$route.path > 字串,對應當前路由的路徑,總是解析為絕對路徑,如"/foo/bar"。
-
$route.params > 一個 key/value 物件,包含了 動態片段 和 全匹配片段, 如果沒有路由引數,就是一個空物件。
-
$route.query > 一個 key/value 物件,表示 URL 查詢引數。 例如,對於路徑 /foo?user=1,則有$route.query.user == 1, 如果沒有查詢引數,則是個空物件。
-
$route.hash > 當前路由的hash值 (不帶#) ,如果沒有 hash 值,則為空字串。
-
$route.fullPath > 完成解析後的 URL,包含查詢引數和hash的完整路徑。
-
$route.matched > 陣列,包含當前匹配的路徑中所包含的所有片段所對應的配置引數物件。
-
$route.name > 當前路徑名字
-
$route.meta > 路由元資訊
-
-
-
vue-router傳參
- 命名路由搭配params,重新整理頁面引數會丟失
- 查詢引數搭配query,重新整理頁面資料不會丟失
- 接受引數使用this.$router後面就是搭配路由的名稱就能獲取到引數的值
-
vue-router的兩種模式
-
一種是利用url的hash,就是通常所說的錨點#,javascript通過hashChange事件來監聽url的變化,IE7以下需要輪詢。
比如這個 URL:
http://www.abc.com/#/hello
,hash 的值為#/hello
。它的特點在於:hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對後端完全沒有影響,因此改變 hash 不會重新載入頁面。 -
另一種是HTML5的History模式,它使url看起來像普通網站那樣,以“/”分割,沒有#,單頁面並沒有跳轉。不過使用這種模式需要服務端支援,服務端在接收到所有請求後,都只想同一個html檔案,不然會出現404。因此單頁面應用只有一個html,整個網站的內容都在這一個html裡,通過js來處理。
history 模式利用了 HTML5 History Interface 中新增的
pushState()
和replaceState()
方法。(需要特定瀏覽器支援)
這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的back
、forward
、go
的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向後端傳送請求。hash 模式和 history 模式都屬於瀏覽器自身的特性,Vue-Router 只是利用了這兩個特性(通過呼叫瀏覽器提供的介面)來實現前端路由。
-
-
vue-router實現路由懶載入(動態載入路由)
懶載入: 也叫延遲載入,即在需要的時候進行載入,隨用隨載
推薦使用ES7的寫法 —— import
component: () => import('@/components/profile')
vue常見面試題
-
vue的優點
Vue.js
是一個構建資料驅動的web介面的漸進式框架. Vue.js的目標是通過儘可能簡單的API實現響應的資料繫結和組合的檢視元件. 核心是一個響應式的資料繫結系統.優點 : (這裡也可以理解為SPA的好處)當前端和資料做一些操作的時候, 可以通過AJAX請求對後端做資料持久化, 不需要重新整理整個頁面, 只需要改動DOM裡需要該懂得那部分資料. 特別是移動端應用場景下, 重新整理頁面太昂貴, 會重新載入很多資源, 雖然有些會被快取, 但是頁面DOM, JS, CSS都會被頁面重新解析一遍, 因此移動端頁面通常會做出SPA單頁面應用; 此外從多方面列舉, vue的優點 :
- MVVM框架 : 資料驅動檢視
- 元件化(提高開發效率,方便複用,簡化除錯,提升專案可維護性,便於協同開發)
- 輕量、簡潔、高效、快速(壓縮之後20kb左右大小)
- 學習成本較其他(
Angular
,React
)低
那麼vue的不足有哪些呢?
- vue不缺入門教程,可是很缺乏高階教程&文件&書籍
- vue不支援IE8(這應該算是個優點吧..../汗)
- 生態環境差不如
Angular
和React
- 社群不大(網上聽的)
-
vue父元件向子元件傳遞資料
使用props /** parent **/ <child :parentResult = 'result' /> // 標準寫法其實是 :parent-result data() { result: { ... } } /** child **/ <div>{{ parentResult.xxx }}</div> props: { parentResult: { type: Object, default() { return {} } } } // 也可以呼叫子元件的方法傳參, 不過實用性不高
-
子元件向父元件傳遞事件
概括:
- 子元件需要使用
this.$emit
將子元件的事件進行上級傳遞 - 父元件需要使用@事件名的方式, 接收子元件的事件
/** parent **/ <child @c-click = 'handleClick' /> // 自定義事件名與子元件發射的事件名統一 methods: { handleClick(arg) { console.log('父元件事件呼叫') } } /** child **/ <button @click = 'emitClick' /> methods: { emitClick() { this.$emit('c-click', arg) } }
- 子元件需要使用
-
v-show和v-if指令的共同點和不同點
二者都是用來控制元素的顯示的
v-if
是真正的條件渲染, 因為它會確保在切換過程中條件塊內的事件監聽器和子元件適當地被銷燬和重建. 但同時它也是惰性的: 如果在初始渲染時條件為false, 則什麼也不做, 直到條件第一次變為true, 才開始渲染條件塊v-show
不管初始條件是什麼, 元素總是會被渲染, 並只是簡單的CSS進行切換來控制顯示**使用規則 : **
v-if
有更高的切換開銷, 而v-show
有更高的初始渲染開銷. 因此, 如果需要非常頻換地切換元素顯示, 那麼使用v-show
更優, 如果是在執行時條件很少改變, 則使用v-if
較好 -
如何讓CSS只在當前元件中起作用
style
標籤上新增scoped
<style scoped> </style>
scoped
: 實現元件私有化, 不對全域性造成樣式汙染 -
如何獲取DOM
首先, 因為vue鉤子函式每個階段的特性, 獲取DOM的操作不能直接放在
created
中, 如果要寫在created
和mounted
中, 應寫在this.nextTick()
的回撥函式中-
可以直接使用原生js
document.getElementById()
, ... -
給標籤中加上ref='dom', 然後在程式碼中this.$refs.dom就可以拿到頁面元素
ref
繫結在一般元素上時,$refs
指向DOM元素, 繫結在元件上時,$refs
指向元件例項
-
-
說出幾種vue的指令和它的用法
指令的職責是,當表示式的值改變時,將其產生的連帶影響,響應式地作用於 DOM
-
v-if :根據表示式的值來有條件地渲染元素。在切換時元素及它的資料繫結 / 元件被銷燬並重建。如果元素是
<template>
,將提出它的內容作為條件塊。當條件變化時該指令觸發過渡效果。
當和
v-if
一起使用時,v-for
的優先順序比v-if
更高。 -
v-else : 不需要表示式
限制:前一兄弟元素必須有
v-if
或v-else-if
。 -
v-else-if :表示
v-if
的“else if 塊”。可以鏈式呼叫。限制:前一兄弟元素必須有
v-if
或v-else-if
-
v-show :根據表示式之真假值,切換元素的
display
。當條件變化時該指令觸發過渡效果。
-
v-text :更新元素的
textContent
。如果要更新部分的textContent
,需要使用{{ Mustache }}
插值。 -
v-html :更新元素的
innerHTML
。注意:內容按普通 HTML 插入 - 不會作為 Vue 模板進行編譯。如果試圖使用
v-html
組合模板,可以重新考慮是否通過使用元件來替代。在網站上動態渲染任意 HTML 是非常危險的,因為容易導致
XSS 攻擊
。只在可信內容上使用v-html
,永不用在使用者提交的內容上。在``單檔案元件
裡,
scoped的樣式不會應用在
v-html` 內部,因為那部分 HTML 沒有被 Vue 的模板編譯器處理。 -
v-bind : 簡寫 --
:
; 繫結動態引數動態地繫結一個或多個 attribute,或一個元件 prop 到表示式。
在繫結 prop 時,prop 必須在子元件中宣告。可以用修飾符指定不同的繫結型別。
修飾符:
.prop
- 作為一個 DOM property 繫結而不是作為 attribute 繫結。.camel
- (2.1.0+) 將 kebab-case attribute 名轉換為 camelCase。(從 2.1.0 開始支援).sync
(2.3.0+) 語法糖,會擴充套件成一個更新父元件繫結值的v-on
偵聽器。
-
**v-on : ** 簡寫 --
@
; 繫結動態事件用在普通元素上時,只能監聽原生 DOM 事件。用在自定義元素元件上時,也可以監聽子元件觸發的自定義事件。
修飾符:
.stop
- 呼叫event.stopPropagation()
。.prevent
- 呼叫event.preventDefault()
。.capture
- 新增事件偵聽器時使用 capture 模式。.self
- 只當事件是從偵聽器繫結的元素本身觸發時才觸發回撥。.{keyCode | keyAlias}
- 只當事件是從特定鍵觸發時才觸發回撥。.native
- 監聽元件根元素的原生事件。.once
- 只觸發一次回撥。.left
- (2.2.0) 只當點選滑鼠左鍵時觸發。.right
- (2.2.0) 只當點選滑鼠右鍵時觸發。.middle
- (2.2.0) 只當點選滑鼠中鍵時觸發。.passive
- (2.3.0) 以{ passive: true }
模式新增偵聽器
-
v-for :基於源資料多次渲染元素或模板塊。此指令之值,必須使用特定語法
alias in expression
,為當前遍歷的元素提供別名:<div v-for="item in items"> {{ item.text }} </div>
另外也可以為陣列索引指定別名 (或者用於物件的鍵):
<div v-for="(item, index) in items"></div> <div v-for="(val, key) in object"></div> <div v-for="(val, name, index) in object"></div>
-
**v-model : **在表單控制元件或者元件上建立雙向繫結。
修飾符:
.lazy
- 取代input
監聽change
事件.number
- 輸入字串轉為有效的數字.trim
- 輸入首尾空格過濾
-
v-slot : 簡寫 --
#
提供具名插槽或需要接收 prop 的插槽。
<!-- 具名插槽 --> <base-layout> <template v-slot:header> Header content </template> Default slot content <template v-slot:footer> Footer content </template> </base-layout> <!-- 接收 prop 的具名插槽 --> <infinite-scroll> <template v-slot:item="slotProps"> <div class="item"> {{ slotProps.item.text }} </div> </template> </infinite-scroll> <!-- 接收 prop 的預設插槽,使用瞭解構 --> <mouse-position v-slot="{ x, y }"> Mouse position: {{ x }}, {{ y }} </mouse-position>
-
v-pre : 跳過這個元素和它的子元素的編譯過程。可以用來顯示原始 Mustache 標籤。跳過大量沒有指令的節點會加快編譯。
<span v-pre>{{ this will not be compiled }}</span>
-
v-cloak :這個指令保持在元素上直到關聯例項結束編譯。和 CSS 規則如
[v-cloak] { display: none }
一起用時,這個指令可以隱藏未編譯的 Mustache 標籤直到例項準備完畢。 -
v-once :只渲染元素和元件一次。隨後的重新渲染,元素/元件及其所有的子節點將被視為靜態內容並跳過。這可以用於優化更新效能。
拓展 :Mustache語法: (雙大括號) 的文字插值 --
{{ msg }}
; 每個繫結都只能包含單個表示式 -
-
vue-loader是什麼? 使用它的用途有哪些?
簡單的說,他就是基於webpack的一個的loader,解析和轉換 .vue 檔案,提取出其中的邏輯程式碼 script、樣式程式碼 style、以及 HTML 模版 template,再分別把它們交給對應的 Loader 去處理,核心的作用,就是提取,劃重點。
至於什麼是webpack的loader,其實就是用來打包、轉譯js或者css檔案,簡單的說就是把你寫的程式碼轉換成瀏覽器能識別的,還有一些打包、壓縮的功能等。
vue-loader 的作用(引用自官網)
允許為 Vue 元件的每個部分使用其它的 webpack loader,例如在 style 的部分使用 Sass 和在 template 的部分使用 Pug;
允許在一個 .vue 檔案中使用自定義塊,並對其運用自定義的 loader 鏈;
使用 webpack loader 將 style 和 template 中引用的資源當作模組依賴來處理;
為每個元件模擬出 scoped CSS;
在開發過程中使用熱過載來保持狀態。 -
為什麼使用key?
key
的特殊 attribute 主要用在 Vue 的虛擬 DOM 演算法,在新舊 nodes 對比時辨識 VNodes。如果不使用 key,Vue 會使用一種最大限度減少動態元素並且儘可能的嘗試就地修改/複用相同型別元素的演算法。而使用 key 時,它會基於 key 的變化重新排列元素順序,並且會移除 key 不存在的元素。有相同父元素的子元素必須有獨特的 key。重複的 key 會造成渲染錯誤。
最常見的用例是結合
v-for
:<ul> <li v-for="item in items" :key="item.id">...</li> </ul>
它也可以用於強制替換元素/元件而不是重複使用它。當你遇到如下場景時它可能會很有用:
- 完整地觸發元件的生命週期鉤子
- 觸發過渡
例如:
<transition> <span :key="text">{{ text }}</span> </transition>
當
text
發生改變時,<span>
總是會被替換而不是被修改,因此會觸發過渡。 -
axios及安裝
axios
是一個基於Promise的http庫, 簡單的講就是可以傳送get、post請求特性
- 可以在瀏覽器中傳送
XMLHttpRequest
- 可以在node.js傳送http請求
- 支援PromiseAPI
- 攔截請求和響應
- 轉換請求資料和響應資料
- 能夠取消請求
- 自動轉換json資料
- 客戶端支援保護安全免受XSRF攻擊
安裝
// 安裝模組 npm install axios --save
使用
<!-- 直接script標籤應用 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
// ES6 import引用 import axios from 'axios' // 如果要全域性使用axios就要在main.js中將其載入到Vue的原型上 /** main.js **/ Vue.prototype.$axios = axios
- 可以在瀏覽器中傳送
-
axios解決跨域
跨域
出於瀏覽器的同源策略限制。同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。同源策略會阻止一個域的javascript指令碼和另外一個域的內容進行互動。所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和埠號(port)
當一個請求url的協議、域名、埠三者之間任意一個與當前頁面url不同即為跨域
跨域配置 cli-3+ 使用
proxy
配置/** vue.config.js **/ module.exports = { devServer: { proxy: { '/api': { target: 'https://www.xx.com', // 目標路徑 changeOrigin: true, // 是否跨域 ws: true, pathRewrite: { '^/api': '' // 重寫路徑 } } } } }
-
v-modal的使用
**v-model **是用來對錶單元素中input、textarea、select這些標籤進行雙向繫結的,它會根絕空間型別自動選取正確的方法來更新元素。
它本質上是一個語法糖。
<input v-model="test" /> // 等價於 <input :value="test" @input="test = $event.target.value" />
**在input不同元件中的應用 **
- 在複選框中使用時,
v-model
在data中應該由陣列與其對應 - 在單選框、複選框、或是下拉框中,要為選項例如
<option>
設定value
屬性
v-model的修飾符
.lazy
失去焦點時觸發事件.trim
清除前後空格.number
限制當前輸入格式為數字型別
- 在複選框中使用時,
-
scss的安裝及使用
在
Vue-CLI
中, 首先要安裝sass
依賴:npm install node-sass --save-dev npm install sass-loader --save-dev
在專案(元件)中使用:
<style lang="scss" scoped> To Do Something </style>
(待完善; 答非Vue-CLI中, sass的安裝, 使用, 規範更好)
-
請說出vue-cli專案中src目錄中每個資料夾和檔案的用法
滿配(
vue-router
,vuex
)自帶的:- **assets **存放靜態資源
- **components **元件資料夾
- **router **路由資料夾, 定義路由相關的配置
- **store **vuex資料夾
- **views **檢視(路由對應的頁面所在)資料夾
- **App.vue **根元件
- **main.js **入口檔案
專案規範中"潛規則"資料夾:
- **api/network/serve/http **網路請求資料夾(如果將請求封裝統一管理)
- **style **樣式資料夾
- **mixin **"混入"資料夾
- **utils **工具方法資料夾(例如過濾器, 全域性方法, 全域性變數)
- **icons **專案所用icon資料夾(看需求和習慣)
-
分別簡述computed和watch的使用場景
二者有明顯的區別:
watch
中的函式是不需要呼叫的computed
內部的函式呼叫的時候不需要加()watch
屬性監聽, 監聽屬性的變化computed
計算屬性, 通過屬性計算而得來的屬性watch
需要在資料變化時執行非同步或開銷較大的操作時使用對於任何複雜邏輯或一個數據屬性在它所依賴的屬性發生變化時, 也要發生變化, 這種情況下, 推薦使用
computed
computed
屬性的結果會被快取(不同於methods
), 除非以來的響應式屬性變化才會重新計算. 主要當做屬性來使用;computed
中的函式必須用return
返回最終的結果watch
(監聽)一個物件, 鍵是需要觀察的表示式, 值是對應的毀掉函式. 主要用來監聽某些特定資料的變化, 從而進行某些具體的業務邏輯操作所以二者的使用場景也不同:
**computed **當一個屬性受多個屬性影響時, 就需要用到
computed
最典型的例子: 購物車商品結算時的價格計算
**watch **當一條資料影響多條資料的時候就需要用
watch
搜尋資料
-
v-on可以監聽多個方法嗎
可以
<input type="text" v-on="{ input: handleInput, focus: handleFocus, blur: handleBlur }" />
-
$nextTick的使用
this.$nextTick()
將回調延遲到下次DOM
更新迴圈之後執行. 在修改資料之後立即使用它, 然後等待DOM
更新. 它跟全域性方法Vue.nextTick一樣, 不同的是會掉的this
自動繫結到呼叫它的例項上.this.$nextTick()
在頁面互動, 尤其是從後臺獲取資料後重新生成DOM
物件之後的操作有很大優勢, 舉一個簡單的例子: 在鉤子函式created
執行的時候DOM
其實並未進行任何渲染, 而此時進行DOM
操作並無作用, 而在created
中使用this.$nextTick()
可以等待DOM
生成以後再來獲取DOM
物件 -
vue元件中data為什麼必須是一個函式
因為對於元件來說有一個很明顯的特性石在於它是可以被複用的, 所以只有元件的
data
是一個函式的時候, 每一個例項的data
才是獨立的(每個例項可以維護一份被返回物件的獨立的拷貝), 就不會互相影響. 這是因為js本身的特性帶來的, 跟vue
本身設計無關 -
vue事件物件的使用
事件物件就是指
event
物件, 在vue
中, 繫結事件時, 可以有小括號, 也可以沒有-
在繫結事件時, 如果沒有小括號, name第一個引數就是事件物件
-
如果有小括號, 但是沒有引數, 那麼
e
預設就是undefined
-
如果需要事件物件, 並且需要傳參, 那麼需要在繫結時使用
$event
進行佔位<input type="text" @keyup.13="fn($event, 100)" />
-
-
元件間的通訊
元件可以有以下幾種關係:
如上圖所示: A和B、B和C、B和D都是父子關係,C和D是兄弟關係,A和C是隔代關係(可能隔多代)
元件間的通訊方式(六種) :
-
props
/$emit
父元件向子元件傳值 : 父元件通過props向下傳遞資料給子元件。注:元件中的資料共有三種形式:data、props、computed
子元件向父元件傳值(通過事件形式): 子元件通過events給父元件傳送訊息,實際上就是子元件把自己的資料傳送到父元件
-
$emit
/$on
這種方法通過一個空的Vue例項作為中央事件匯流排(事件中心),用它來觸發事件和監聽事件,巧妙而輕量地實現了任何元件間的通訊,包括父子、兄弟、跨級。當我們的專案比較大時,可以選擇更好的狀態管理解決方案vuex。
具體實現方式:
let Event=new Vue(); Event.$emit(事件名,資料); Event.$on(事件名,data => {});
$on
監聽了自定義事件 data-a和data-b,因為有時不確定何時會觸發事件,一般會在 mounted 或 created 鉤子中來監聽。 -
vuex
vuex 是 vue 的狀態管理器,儲存的資料是響應式的。但是並不會儲存起來,重新整理之後就回到了初始狀態,具體做法應該在vuex裡資料改變的時候把資料拷貝一份儲存到localStorage裡面,重新整理之後,如果localStorage裡有儲存的資料,取出來再替換store裡的state。
-
$attrs
/$listeners
多級元件巢狀需要傳遞資料時,通常使用的方法是通過vuex。但如果僅僅是傳遞資料,而不做中間處理,使用 vuex 處理,未免有點大材小用。為此Vue2.4 版本提供了另一種方法----
$attrs
/$listeners
$attrs
:包含了父作用域中不被 prop 所識別 (且獲取) 的特性繫結 (class 和 style 除外)。當一個元件沒有宣告任何 prop 時,這裡會包含所有父作用域的繫結 (class 和 style 除外),並且可以通過 v-bind="$attrs" 傳入內部元件。通常配合 interitAttrs 選項一起使用。$listeners
:包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器。它可以通過 v-on="$listeners" 傳入內部元件
-
provide
/inject
Vue2.2.0新增API,這對選項需要一起使用,以允許一個祖先元件向其所有子孫後代注入一個依賴,不論元件層次有多深,並在起上下游關係成立的時間裡始終生效。一言而蔽之:祖先元件中通過provider來提供變數,然後在子孫元件中通過inject來注入變數。
provide / inject API 主要解決了跨級元件間的通訊問題,不過它的使用場景,主要是子元件獲取上級元件的狀態,跨級元件間建立了一種主動提供與依賴注入的關係。需要注意的是:provide 和 inject 繫結並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的物件,那麼其物件的屬性還是可響應的----vue官方文件
-
$parent
/$children
與ref
ref
:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子元件上,引用就指向元件例項$parent
/$children
:訪問父 / 子例項
需要注意的是:這兩種都是直接得到元件例項,使用後可以直接呼叫元件的方法或訪問資料。
**總結 **
常見使用場景可以分為三類:
- 父子通訊:
父向子傳遞資料是通過 props,子向父是通過 events(
$emit
);通過父鏈 / 子鏈也可以通訊($parent
/$children
);ref 也可以訪問元件例項;provide / inject API;$attrs/$listeners
- 兄弟通訊:
Bus;Vuex
- 跨級通訊:
Bus;Vuex;provide / inject API、
$attrs/$listeners
還有個插槽傳值
- 插槽之間的傳值,插槽要顯示的內容是寫在父元件中的,也就是父元件中的資料是寫在自己的元件裡。
- 而父子元件之間的傳值,是在當前元件拿到了資料之後,然後才在當自己的元件中顯示。
- 如果說他們之間有什麼聯絡的話,插槽傳值,其實類似於父元件向子元件傳值。而插槽預設值的寫法又像是子元件向父元件傳值,只是如果父元件有傳值過來,會被覆蓋掉了而已。
-
-
漸進式框架的理解
就是一開始不需要你完全掌握它的全部功能特性,可以後續逐步增加功能。沒有多做職責之外的事情
Vue與React、Angular的不同是,但它是漸進的
-
vue.js只提供了vue-cli生態中最核心的元件系統和雙向資料繫結
-
就好像 vuex、vue-router都屬於圍繞vue.js開發的庫
使用Angular,必須接受以下東西
- 必須使用它的模組機制
- 必須使用它的依賴注入
- 必須使用它的特殊形式定義元件
所以Angular是帶有比較強的排它性的,如果你的應用不是從頭開始,而是要不斷考慮是否跟其他東西整合,這些主張會帶來一些困擾
使用React,你必須理解
- 函數語言程式設計的理念
- 需要知道它的副作用
- 什麼是純函式
- 如何隔離、避免副作用
它的侵入性看似沒有Angular那麼強,主要因為它是屬於軟性侵入的
參考資料 :
-
-
vue中雙向資料繫結是如何實現的
所謂雙向資料繫結, 無非就是資料層和檢視層中的資料同步, 在寫入資料時檢視層實時的跟著更新
實現mvvm的雙向繫結,是採用資料劫持結合釋出者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在資料變動時釋出訊息給訂閱者,觸發相應的監聽回撥。就必須要實現以下幾點:
- 實現一個數據監聽器Observer,能夠對資料物件的所有屬性進行監聽,如有變動可拿到最新值並通知訂閱者
- 實現一個指令解析器Compile,對每個元素節點的指令進行掃描和解析,根據指令模板替換資料,以及繫結相應的更新函式
- 實現一個Watcher,作為連線Observer和Compile的橋樑,能夠訂閱並收到每個屬性變動的通知,執行指令繫結的相應回撥函式,從而更新檢視
- mvvm入口函式,整合以上三者
getter函式裡面執行的任務就是watcher訂閱者, 而setter函式執行的任務就是釋出者; 相信很多人看過了這個也是一知半解, 下面我來解釋一波:
ECMAScript中有兩種屬性: 資料屬性和訪問器屬性, 資料屬性一般用於儲存資料數值, 訪問器屬性對應的是set/get操作, 不能直接儲存資料值, 每種屬性下面又都含有四個特性.下面介紹一下:
資料屬性
1.[[Configurable]]: 表示能否通過delete將屬性刪除,能否把屬性修改為訪問器屬性, 預設為false。當把屬性Configurable設定為false後,該屬性不能通過delete刪除,並且也無法再將該屬性的Configurable設定回true
2.[[Enumerable]]: 表示屬性可否被列舉(即是否可以通過for in迴圈返回),預設false
3.[[Writable]]: 表示屬性是否可寫(即是否可以修改屬性的值),預設false
4.[[Value]]: 該屬性的資料值, 預設是undefined訪問器屬性
1.[[Configurable]]: 表示能否通過delete將屬性刪除,能否把屬性修改為資料屬性, 預設為false。當把屬性Configurable設定為false後,該屬性不能通過delete刪除,並且也無法再將該屬性的Configurable設定回true
2.[[Enumerable]]: 表示屬性可否被列舉(即是否可以通過for in迴圈返回),預設false
3.[[Get]]: 讀取屬性時呼叫的函式, 預設為undefined
4.[[Set]]: 寫入屬性時呼叫的函式, 預設是undefined在修改屬性的特性或者定義訪問器屬性的時候, 需要藉助ECMAScript 5中的一個方法: Object.defineProperty(), 這個方法接收三個引數: 屬性所在物件, 屬性的名字, 描述符物件; 為物件定義多個屬性的話, 就用函式的複數寫法:Object.defineProperties();
那麼通過這個ES5的方法就可以直接很簡單粗暴的說明雙向繫結的原理:
<input type="text" id="inp" /> <div id="box"></div> <script> let obj = {}; let oInp = document.getElementById('inp'); let oBox = document.getElementById('box'); Object.defineProperty(obj, 'name', { configurable: true, enumerable: true, get: function() { console.log(111) return val; }, set: function(newVal) { oInp.value = newVal; oBox.innerHTML = newVal; } }); oInp.addEventListener('input', function(e) { obj.name = e.target.value; }); obj.name = 'xx';
那麼實現資料雙向繫結的核心就是利用為每一個屬性都建立了訂閱者的例項物件, 以便觀察, getter函式裡面返回一個value值,在setter函式中寫入修改後的值並呼叫update方法更新檢視的資料值, Configurable和Enumerable這兩個特性描述符預設是true, 因此不用寫
function defineReactive (obj, key, val) { var dep = new Dep(); //這是一個建構函式 其原型是為屬性新增訂閱者 Object.defineProperty(obj, key, { get: function() { if(Dep.target) { dep.addSub(Dep.target); //新增訂閱者到Dep例項物件 } return val; // 返回監聽到的value值 }, set: function (newVal) { if(newVal === val) return; val = newVal; // 寫入新的value值 dep.notify(); // 作為釋出者發出通知 然後dep會迭代呼叫各自的update方法來更新檢視 } }); } function observe(obj, vm) { Object.keys(obj).forEach(function(key) { defineReactive(vm, key, obj[key]); }); }
-
單頁面應用和多頁面應用區別及優缺點
單頁面應用(SinglePage Web Application,SPA)
通俗一點說就是指只有一個主頁面的應用, 瀏覽器一開始要載入所有必須的html, js, css. 所有的頁面內部都包含在這個所謂的主頁面中. 但在codeing的時候,還是會分開寫, 然後在互動的時候由路由程式動態載入, 單頁面的頁面跳轉, 僅重新整理區域性資源. 多用於pc端官網, 購物等網站
多頁面(MultiPage Application,MPA)
就是指一個應用中有多個頁面, 頁面跳轉時是整頁重新整理, 多用於app或客戶端等
具體對比分析
單頁面應用(SinglePage Web Application,SPA) 多頁面應用(MultiPage Application,MPA) 組成 一個外殼頁面和多個頁面片段組成 多個完整頁面構成 資源共用(css,js) 共用,只需在外殼部分載入 不共用,每個頁面都需要載入 重新整理方式 頁面區域性重新整理或更改 整頁重新整理 url 模式 a.com/#/pageone a.com/#/pagetwo a.com/pageone.html a.com/pagetwo.html 使用者體驗 頁面片段間的切換快,使用者體驗良好 頁面切換載入緩慢,流暢度不夠,使用者體驗比較差 轉場動畫 容易實現 無法實現 資料傳遞 容易 依賴 url傳參、或者cookie 、localStorage等 搜尋引擎優化(SEO) 需要單獨方案、實現較為困難、不利於SEO檢索 可利用伺服器端渲染(SSR)優化 實現方法簡易 試用範圍 高要求的體驗度、追求介面流暢的應用 適用於追求高度支援搜尋引擎的應用 開發成本 較高,常需藉助專業的框架 較低 ,但頁面重複程式碼多 維護成本 相對容易 相對複雜 單頁面的優點
- 使用者體驗好, 快, 內容的改變不許要重新載入整個頁面, 基於這一點
SPA
對伺服器壓力較小 - 前後端分離
- 頁面效果會比較炫酷(比如切換頁面內容時的過場動畫)
單頁面的缺點
-
不利於
SEO
-
導航不可用, 如果一定要導航需要自行實現前進、後退(由於是單頁面不能用瀏覽器的前進後退功能,所以需要自己建立堆疊管理)
-
初次載入開銷耗時多
-
頁面複雜度高
- 使用者體驗好, 快, 內容的改變不許要重新載入整個頁面, 基於這一點
-
vue中過濾器有什麼作用及詳解
過濾器是一個通過輸入資料,能夠及時對資料進行處理並返回一個數據結果的簡單函式。Vue有很多很便利的過濾器,可以參考官方文件,http://cn.vuejs.org/api/#過濾器,過濾器通常會使用管道標誌 “ | ”, 比如:
{{ msg | uppercase }} // 'abc' => 'ABC'
-
v-if和v-for的優先順序
當
v-for
和v-if
一起使用時,v-for
的優先順序比v-if
更高 -
assets和static的區別
**相同點: **資源在
html
中使用, 都是可以的**區別: **使用
assets
下面的資源, 在js
中使用的話, 路徑要經過webpack
中file-loader
編譯, 路徑不能直接寫.assets
中的檔案會經過webpack
打包, 重新編譯, 推薦該方式. 而static
中的檔案, 不會經過編譯. 專案在經過打包後, 會生成dist
資料夾,static
中的檔案只是複製一遍而已. 簡單來說,static
中建議放一些外部第三方, 自己的放在assets
, 別人的放在static
中.注意 : 如果把圖片放在
assets
與static
中, html頁面可以使用; 但在動態繫結中,assets
路徑的圖片會載入失敗, 因為webpack
使用的是commonJS
規範, 必須使用require
才可以 -
列舉常用的指令
{{ msg }} 大鬍子(
Mustache
)插值語法v-bind 動態屬性繫結
v-on 動態事件繫結
v-model (表單)雙向繫結
v-for 列表渲染(需提供
key
)v-show 根據條件表示式控制元素展示/隱藏
v-if 根據條件表示式控制元素是否渲染
-
vue常用的修飾符
- v-model修飾符
- .lazy 失去焦點才更新資料
- .trim 去除首尾空格
- .number 限制錄入的為數字(可以輸字母, 但是不顯示)
- v-on修飾符
- .stop 組織事件冒泡, 相當於呼叫了
event.stopPropagation()
- .prevent 阻止預設行為, 詳單與呼叫了
event.preventDefault()
, 比如表單提交,<a>
標籤 - .once 事件只觸發一次
- .stop 組織事件冒泡, 相當於呼叫了
- v-model修飾符
-
陣列更新檢測
vue
包含兩種觀察陣列的方法-
變異方法
呼叫後原始陣列改變, 從而觸發檢視更新
push | pop | shift | unshift | splice | sort | reverse
-
非變異方法
呼叫後不會改變原始陣列, 總是返回一個新陣列
filter | concat | slice
解決: 可以使用新陣列替換舊陣列
**由於JS限制, vue不能檢測一下變動的陣列: **
- 當你利用索引直接設定一個項時, 例如:
vm.items[index] = newValue
- 當你修改陣列的長度時, 例如:
vm.items.length = newLength
vue
針對這兩個問題給出了相應的解決方法, 使用這兩種方法, 也會觸發狀態更新1. 使用`vue`全域性方法: Vue.set() 或者使用`vm.$set()`例項方法 2. 使用`splice`, `concat`等修改陣列
-
-
vue.set檢視更新
Vue.set(target, key, value)
**target: **要更改的資料來源(可以使物件或者陣列)
**key: **要更改的具體資料
**value: **重新賦的值
data() { return { items: [ { message: "test1" }, { message: "test2" } ] } }, methods: { handleClick() { Vue.set(this.items, 0, { message: "newTest" }) } }
**總結: **如果例項建立之後新增新的屬性到例項上, 它不會觸發檢視更新; 資料發生變化檢視不更新, 那就要使用Vue.set方法來設定
-
自定義指令詳解
全域性註冊
// 註冊一個全域性自定義指令 -- "v-focus" Vue.directive('focus', { // 當被繫結的元素插入到DOM中時 inserted: function (el) { el.focus() } })
區域性註冊
directives: { focus: { inserted: function (el) { el.focus() } } }
-
vue的兩個核心點
-
資料驅動
在vue中, 資料的改變會
-
元件
元件化開發, 有點很多, 可以很好的降低資料之間的耦合度. 將常用的程式碼封裝成元件之後, 就能高度的複用, 提高程式碼的可重用性. 一個頁面/模組可以由多個元件所組成.
-
-
vue和JQuery的區別
- jQuery是使用選擇器(
$
)選取DOM
物件, 對其進行賦值、取值、事件繫結等操作, 其實和原生的html
的區別只在於可以更方便的選取和操作DOM
物件, 而資料和介面是在一起的. - vue則是通過
Vue
物件將資料和View
完全分離開來了. 對資料進行操作不再需要引用響應的DOM
物件, 可以說資料和View
是分離的, 通過Vue
物件實現相互的繫結, 這就是MVVM
.
從編寫習慣和規範上來說我認為是宣告式(函式式)程式設計 和 指令式程式設計的區別
- jQuery是使用選擇器(
-
引用元件的步驟
// 1. 引入元件 import NormalComps from '@/components/NormalComps' // 2. 註冊元件 ... components: { NormalComps }, ...
<!-- 3. 使用元件 --> ... <normal-comps></normal-comps> ...
-
vue-cli打包命令是什麼?打包後會導致路徑問題,應該在哪裡修改
npm run build
建立
vue.config.js
... module.exports = { publicPath: './', ... // outputDir: 'dist', // assetsDir: 'static' } ...
-
三大框架的對比
React
框架是起源於Facebook
的專案, 可以輕易的解決跨瀏覽器相容的問題, 主要是通過對DOM
的模擬減少與DOM
的互動做到的.React
的模組化把元件進行了隔離, 出現問題的時候更方便程式設計師對其進行修改, 而且由於JavaScript
, 因策更有利於搜尋引擎的優化.(能記多少是多少, 沒屌用)**特性: **
- 宣告式設計 :
React
採用聲明範式, 可以輕鬆描述應用 - 高效 :
React
通過對DOM
的模擬, 最大限度的減少與DOM
的互動 - 靈活 :
React
可以與已知的庫或框架很好地配合
**優點: **
- 速度快 : 在UI渲染過程中,
React
通過在虛擬DOM
中的微操作來實現對實際DOM
的區域性更新 - 跨瀏覽器相容 :
虛擬DOM
幫助我們解決了跨瀏覽器問題, 它為我們提供了標準化的API
, 甚至在IE8
中也是沒問題的 - 模組化 : 為你程式編寫獨立的模組化UI元件, 這樣當某個或某些元件出現問題時, 可以方便地進行隔離
- 單向資料流 :
Flux
是一個用在JavaScript
應用中建立單向資料層的架構, 它隨著React
檢視庫的開發而被Facebook
概念化 - 同構、純粹的
JavaScript
: 因為搜尋引擎的爬蟲程式依賴的是服務端響應而不是JavaScript
的執行, 預渲染你的應用有助於搜尋引擎優化 - 相容性好 : 比如使用
RequireJS
來載入和打包, 而Browserify
和Webpack
適用於構建大型應用, 他們那些艱難的任務不在讓人望而生畏
**缺點: **
React
本身只是一個V
而已(MVC
中的V
), 並不是一個完整的框架, 所以如果是大型專案想要一套完整的框架的話, 基本都需要加上ReactRouter
和Flux
才能寫大型應用.Vue
是尤雨溪(牛逼)編寫的一個構建資料驅動的web介面的庫, 準確來說不是一個框架, 他聚焦在V
(view)檢視層特性:
- 輕量級的框架
- 雙向資料繫結
- 指令
- 外掛化
優點:
- 簡單 : 官方文件清晰, 較
Angular
更簡單易學 - 快速 : 非同步批處理方式更新
DOM
- 組合 : 用解耦的、可複用的元件組合你的應用程式
- 緊湊 : ~18kb min+gzip, 且無依賴
- 強大 : 表示式, 無需宣告依賴的可推導屬性(
computed properties
) - 對模組友好 : 可以通過
NPM
、yarn
安裝, 不強迫你所有的程式碼都遵循Angular
的各種規定, 使用場景更加靈活
缺點:
- 新生兒 : 對比
React
和Angular
, 略顯年輕 - 影響不是很大(... ???) : Google有關
Vue.js
多樣性或者說豐富性少於其他一些有名的庫 - 不支援IE8(這也算缺點?)
Angular
是有一款優秀的前端框架, 已經被用於Google
的多款產品當中特性:
- 良好的應用程式結構
- 雙向資料繫結
- 指令
- HTML模板
- 可嵌入、注入和測試
優點:
- 模板功能強大豐富, 自帶了集齊豐富的
Angular
指令 - 是一個比較完善的前端框架, 包好服務, 模板, 資料雙向繫結, 模組化, 路由, 過濾器, 依賴注入等所有功能
- 自定義指令, 自定義指令後可以在專案中多次使用
ng
模組化比較大膽的引入了Java
的一些東西(依賴注入), 能夠很容易的寫出可複用的程式碼, 對於敏感開發的團隊來說非常用幫助Angular
是由網際網路巨人谷歌開發, 這意味著它有一個堅實的基礎和社群支援
缺點:
- 學習成本較高
- 驗證功能錯誤資訊顯示比較薄弱, 需要很多模板標籤
ngView
只能有一個, 不能巢狀多個檢視- 比較笨重, 沒有讓使用者選擇一個輕量級的版本
- 宣告式設計 :
-
跨元件雙向資料繫結
好難整理
-
delete和vue.delete刪除資料的區別
delete只是被刪除的元素變成了
empty
/undefined
, 其他的元素的鍵值還是不變Vue.delete直接刪除了陣列, 改變了陣列的鍵值(splice 也是)
let a = [1, 2, 3, 4] let b = [1, 2, 3, 4] delete a[1] console.log(a) this.$delete(b, 1) console.log(b)
結果 :
-
SPA首屏載入慢如何解決
單頁面應用的好處在於一次載入所有頁面資源, 利用本地計算能力渲染頁面, 提高頁面切換速度與使用者體驗. 但缺點在於所有頁面資源將被一次性下載完, 此時封裝出來的靜態資源包體積較大, 使得第一次開啟SPA頁面時候需要的載入時間較長.
- 將公用的
js
庫用script
標籤引入(CDN
), 然瀏覽器並行下載資源 - 配置路由, 元件, 頁面. 使用
懶載入
, 在呼叫某個元件時, 再下載某個js - 首屏loading圖, 可以提高使用者體驗
- 將公用的
-
vue-router跳轉和location.href有什麼區別
-
vue slot
-
你們vue專案是打包了一個js檔案,一個css檔案,還是多個檔案?
-
router-link在電腦上有用,在安卓上沒反應怎麼解決?
-
router-link在IE和Firefox中不起左右(路由不跳轉)的問題
-
axios的她點有哪些
-
請說下封裝vue元件的過程
-
vue各種組建通訊方法
-
params和query的區別
-
vue mock
-
vue封裝通用元件
-
vue初始化頁面山東問題
-
vue禁止彈窗後的螢幕滾動
-
vue更新陣列時觸發檢視更新的方法
-
vue常用的UI元件庫
-
vue如何引進本地背景圖片
-
vue如何引進sass
-
vue修改打包後靜態資源路徑的修改
vuex常見面試題
- vuex是什麼?怎麼使用?哪種功能場景使用它?
- vuex有哪幾種屬性?
- 不適用vuex會帶來什麼問題
- vue.js中ajax請求程式碼應該寫在元件的methods中還是vuex的actions中?
- vuex中如何一步修改狀態
- vuex中actions和mutaions的區別
vue專案實戰
- 頂部懸停效果
- 電話本列表效果(右邊祖母分類,上下滑動,旁邊字母顯示高亮)
- vue做代理
- vue路由切換時的左滑和優化效果示例
react
react生命週期面試題
- react生命週期函式
- react生命週期中,最適合與服務端進行資料互動的是哪個函式
- 執行階段生命週期呼叫順序
- shouldComponentUpdate是做什麼的(react效能優化是哪個周期函式)
- 指出(元件)生命週期方法的不同
react基礎面試題
- react中keys的作用
- react中refs的作用
- react中三種構建元件的方式
- 呼叫setState之後發生了什麼?
- react diff原理
- 為什麼建議傳遞給setState的引數是一個callback而不是一個物件
- 除了在建構函式中繫結this,還有其他方式嗎
- setState第二個引數的作用
- (在建構函式中)呼叫super(props)的目的是什麼
- 件數flux思想
- 在react當中element 和 component 有什麼區別
- 描述事件在react中的處理方式
- createElement和cloneElement有什麼區別?
- 如何告訴react它應該編譯生產環境版本
- controlled Component 與 Uncontrolled Component 之間的區別是什麼
react元件面試題
- 展示元件(Presentational component)和容器元件(Container component)之間有何不同
- 類元件(Class component)和函式式元件(Functional component)之間有何不同
- (元件的)狀態(state)和屬性(props)之間有何不同
- 何為受控元件(controlled component)
- 何為高階元件(higher order component)
- 應該在React元件的何處發起ajax請求
- react中元件傳值
- 什麼時候在功能元件(Class Component)上使用類元件(Functional Component)?
- 受控元件(controlled component)與不受控制的元件(Uncontrolled component)有什麼區別?
- react元件的劃分業務元件、技術元件?
redux面試題
- redux中介軟體
- redux有什麼缺點
- 簡單說一下redux
react效能比較面試題
- vue和react的區別
- react效能優化的方案
- react專案用過什麼腳手架
- 介紹一下webpack
- 為什麼我們需要使用react提供的children API而不是JavaScript的map?
JS
-
簡述同步和非同步的區別
在js程式設計中有兩種思想: 同步, 非同步. 有些人會分不清什麼是同步和非同步
想要分清它們, 我們首先要知道js的特性--單執行緒. 所謂單執行緒就是: 在沒有完成這件事情的之前不會去做下一件事情.
那麼同步就好理解了. 上件事情沒完成, 就繼續做上件事情, 等上件事情完成後才會去做下一件事情, js的大部分程式設計都是同步的
非同步就完全不同了, 每個任務都有一個或多個毀掉函式(callback), 上一個任務執行完成後, 不是立刻執行下一個任務, 而是執行毀掉函式, 後一個任務則是不等前一個任務結束就執行, 所以程式的執行順序與任務的排列順序是不一致的(非同步的), 非同步是可以提高執行效率的
非同步的執行機制:
- 所有同步任務都在主執行緒上執行, 形成一個執行棧(execution context stack)
- 主執行緒之外, 還存在一個"任務佇列"(task queue). 只要非同步任務有了執行結果, 就在"任務佇列"之中放置一個事件
- 一旦"執行棧"中的所有同步任務執行完畢, 系統就會讀取"任務佇列", 看看裡面有那些事件, 哪些對應的非同步任務, 於是結束等待狀態, 進入執行棧, 開始執行.
- 主執行緒不斷重複上面的第三步
同步
和非同步
本身是相對的同步就相當於是: 當客戶端傳送請求給服務端, 在等待服務端響應的請求時, 客戶端不做其他的事情, 要等待服務端響應, 這會導致客戶端要一直等待
非同步: 當客戶端傳送服務端請求時, 在等待響應的同時, 客戶端可以做其他的事情
-
怎麼新增、移除、複製、建立和查詢節點
-
實現一個函式clone可以對JavaScript中的五種主要資料型別(Number、String、Object、Array、Boolean)進行復制
-
如何消除一個數組中重複的元素
-
寫一個返回閉包的函式
-
使用遞迴完成1到100的累加
-
JavaScript有哪幾種資料型別
-
如何判斷資料型別
-
console.log(1 + '2')和console.log(1 - '2')的列印結果
-
JS的事件委託是什麼,原理是什麼
-
如何改變函式內部的this指標的只想
-
列舉集中解決跨域問題的方式,且說明原理
-
談談垃圾回收機制的方式及記憶體管理
-
寫一個function, 清除字串前後的空格
-
JS事項整合的方法有哪些
-
判斷一個變數是否是陣列, 有哪些辦法
-
箭頭函式與普通函式有什麼區別
-
隨機取1 - 10之間的證書
-
new 操作符具體幹了什麼
-
ajax原理
-
模組化開發怎麼做
-
非同步載入JS的方式有哪些
-
xml和json的區別
-
webpack如何實現打包
-
常見web安全及防護原理
-
用過哪些設計模式
-
為什麼要有同源限制
-
offsetWidth/offsetHeight, clientWidth/clientHeight與scrollWidth/scrollHeight的區別
-
JavaScript有哪些方法定義物件
-
談談你對AMD, CMD的裂解
-
web開發中回話跟中的方法有哪些
-
介紹js有哪些內建物件
-
說幾條寫JavaScript的基本規範
-
eval是做什麼的
-
null, undefined 的區別
-
["1", "2", "3"].map(parseInt) 列印是多少
-
JavaScript程式碼中的"use strict"
-
js延遲載入的方式有哪些?
-
defer和async
-
說說嚴格模式的限制
-
attribute和property的區別是什麼?
-
ECMAScript6 class
-
常見相容性問題
-
函式防抖節流
-
原始型別有哪幾種?null是物件嗎
-
為什麼console.log(0.2 + 0.1 == 0.3) // false
-
說一下js中型別轉換的規則
-
深拷貝和淺拷貝的區別?如何實現
-
如何判斷this?箭頭函式的this是什麼
-
== 和 === 的區別
-
什麼是閉包
-
JavaScript原型, 原型鏈
-
typeof() 和 instanceof() 的用法區別
-
什麼是變數提升
-
all、apply以及bind函式內部實現是什麼樣的
-
為什麼會出現setTimeout倒計時誤差?如何減少
-
談談你對JS執行上下文棧和作用域鏈的理解
-
new的原理, 通過new 的方式建立物件和通過字面量建立有什麼區別
-
prototype和proto區別是什麼?
-
使用ES5實現一個繼承
-
取陣列的最大值(ES5, ES6)
-
ES6新的特性有哪些?
-
Promise有幾種狀態, Promise 有什麼優缺點?
-
Promise建構函式是同步還是非同步執行, then呢?Promise如何實現then處理?
-
Promise和setTimeout的區別
-
如何實現Promise.all?
-
如何實現Promise.finally?
-
如何判斷img載入完成
-
如何組織冒泡
-
如何組織預設事件
-
ajax請求時,如何解析json資料
-
json和jsonp的區別
-
如何用原生js給一個按鈕繫結兩個onclick事件
-
拖拽會用到那些事件
-
document.write和innerHTML的區別
-
jQuery的事件委託方法bind, live, delegate, on之間有什麼區別?
-
瀏覽器是如何渲染頁面的
-
$(document).ready()方法和window.onload有什麼區別
-
jQuery中.get()提交和post()提交有區別嗎
-
對前端路由的理解? 前後端路由的區別
-
手寫一個類的繼承
-
XMLHttpRequest: XMLHttpRequest.readyState 狀態碼的意思
正則表示式常見面試題
- 建一個字串: get-element-by-id轉化為駝峰形勢
- 匹配二進位制數字
- 非零的十進位制數字(有至少一位數字,但是不能以0開頭)
- 匹配一年中的12個月
- 匹配常見的固定電話號碼
- 匹配ip地址
- 匹配用尖括號括起來的以a開頭的字串
- 分割數字每三個以一個逗號劃分
- 判斷字串是否包含數字
- 判斷電話號碼
- 判斷是否符合指定格式
- 判斷是否符合USD格式
- JS實現千位分隔符
- 獲取url引數
- 驗證郵箱
- 驗證身份證號碼
- 匹配漢字
- 去除首尾的'/'
- 判斷日期格式是否符合'yyyy-MM-dd'的形式,簡單判斷,只判斷格式
- 判斷日期格式是否符合'yyyy-MM-dd'的形式,嚴格判斷
- IPv4地址正則
- 十六進位制顏色正則
- 車牌號正則
- 過濾HTML標籤
- 密碼強度正則, 最少6位,包括至少一個大寫字母,一個小寫字母,一個數字,一個特殊字元
- 匹配浮點數
瀏覽器/HTML/CSS面試題
- 什麼是盒模型
- 行內元素有哪些?塊級元素有哪些?空(void)元素有哪些?行內元素和塊級元素有什麼區別?
- 簡述src和href的區別
- 什麼css Hack
- 優雅降級 和 漸進增強
- px和em的區別
- Http的狀態碼有哪些
- 一次完整的HTTP請求是怎麼一個過程
- HTTPS是如何實現加密的
- 瀏覽器是如何渲染頁面的
- 瀏覽器的核心? 分別有什麼代表的瀏覽器
- 頁面匯入時,使用link和@import有什麼區別
- 如何優化影象,影象格式的區別
- 列舉你瞭解HTML5, CSS3的新特性
- 可以通過哪些方法優化css3 animation渲染
- 列舉幾個前端效能方面的優化
- 如何實現同一個瀏覽器多個標籤頁之間的通訊
- 瀏覽器的儲存技術有哪些
- css定位方式
- 儘可能多的寫出瀏覽器相容性問題
- 垂直上下居中的方法
- 響應式佈局原理
- 清除浮動的方法
- http協議和tcp協議
- 重新整理頁面,js請求一般會有哪些地方有快取處理
- 如何對網站的檔案和資源進行優化
- 你對網頁標準和W3C重要性的理解
- http和https的區別
- data-屬性的作用
- 如何讓Chrome瀏覽器顯示小於12px的文字
- 那些操作會引起頁面迴流(Reflow)
- CSS前處理器的比較: less, sass
- 如何實現頁面每次開啟時清除本頁快取
- 什麼事Virtual DOM,為何要使用Virtual DOM
- 偽元素和偽類的區別
- http的集中請求方法和區別
- 前端需要注意哪些SEO
- img的title和alt有什麼區別
- 從瀏覽器地址輸入url到顯示頁面的過程發生了什麼
- 如何進行網站效能優化
- 語義化的理解
- HTML5的離線儲存怎麼使用,工作原理能不能解釋一下
- 瀏覽器是怎麼對HTML5的離線儲存資源進行管理和載入的呢
- iframe有哪些缺點
- web標準以及W3C標準是什麼
- DOCTYPE的作用,嚴格模式與混雜模式如何區分?他們有何意義
- HTML全域性屬性(global attribute)有哪些
- Canvas和SVG有什麼區別
- 如何在頁面上實現一個圓形的可點選區域
- 網頁驗證碼是幹嘛的,是為了解決什麼安全問題
- 請描述一下cookies, sessionStorage和localStorage的區別
- CSS選擇器有哪些?那些屬性可以繼承
- CSS優先順序演算法如何計算
- CSS3有哪些新特性
- 請解釋一下CSS3的flexbox(彈性盒佈局模型),以及使用場景?
- 用純CSS建立一個三角形的原理是什麼?
- 常見的相容性問題
- 為什麼要初始化CSS樣式
- absolute和containing block計算方式跟正常流有什麼不同
- css中的visibility屬性有個collapse屬性值? 在不同瀏覽器下有什麼區別
- display: none與visibility: hidden 的區別
- position跟display、overflow、float這些屬性相互疊加後會怎樣
- 對BFC規範(塊級格式化上下文: block formatting context)的理解
- 為什麼會出現浮動和什麼時候需要清除浮動?清除浮動的方式
- 上下margin重合的問題
- 設定元素浮動後,該元素的display值是多少
- 移動端的佈局用過媒體查詢嗎
- CSS優化/提高效能的方法有哪些
- 瀏覽器是怎麼樣解析CSS選擇器的
- 在網頁中應該使用奇數還是偶數畫素的字型
- margin和padding分別適合什麼場景使用
- 元素屬相的百分比設定是相對於容器的高度嗎
- 全屏滾動的原理是什麼?用到了CSS的那些屬性
- 什麼是響應式設計, 響應式設計的基本原理是什麼,如何相容低版本的IE
- 詩句滾動效果
- ::before和:after中雙冒號和單冒號有什麼區別?解釋一下這兩個偽元素的作用
- 讓頁面裡的字型變清晰,變細用CSS怎麼做
- position: fixed; 在Android下無效怎麼處理
- 如果需要動手些動畫, 你認為最小時間間隔是多久,為什麼
- li和li之間又看不見的空白間隔是什麼原因引起的?有什麼解決辦法
- display:inline-block什麼時候會顯示間隙
- 有一個高度自適應的div,裡面有兩個div,一個高度100ox,希望另一個天馬剩下的高度
- png, jpg, gif這些圖片格式解釋一下,分別什麼時候用,有沒有了解過webp
- style標籤解除安裝body後和body前有什麼區別
- CSS屬性overflow屬性定義溢位元素內容區的內容會如何處理
- 闡述一下CSS Sprites
ES6面試題
- let const var 比較
- 反引號(``)標識
- 函式預設引數
- 箭頭函式
- 屬性簡寫
- 方法簡寫
- Object.keys()方法,獲取物件的所有屬性名或方法名
- Object.assign()原物件的屬性和方法都合併到了目標物件
- for...of迴圈
- import和export
- Promise物件
- 解構賦值
- set資料結構(可用於快速去重)
- Spread Operator展開運算子(...)
- 字串新增方法
ES6陣列面試題
- forEach()
- map()
- filter()
- reduce()
- some()
- every()
- all()
ES6程式設計題
- 使用解構,實現兩個變數的值得交換
- 利用陣列推到,計算出陣列[1, 2, 3, 4]每一個元素的平方並組成新的陣列
微信小程式開發
- 註冊小程式
- 微信開發者工具
- 小程式與普通網頁開發的區別
- 小程式尺寸單位rpx
- 樣式匯入(WeUI for)
- 選擇器
- 小程式image高度自適應及裁剪問題
- 微信小程式長按識別二維碼
- 給頁面加背景色
- 微信小程式獲取使用者資訊
- 程式碼稽核和釋出
- 小程式微信認證
- 小程式申請微信支付
- 小程式的目錄結構及四中檔案型別
- 小程式檔案的作用於
- 小程式常用元件
- view
- scroll-view
- swiper
- movable-view
- cover-view
- cover-image
小程式基礎
- 授權得到使用者資訊
- 資料繫結
- 列表渲染
- 條件渲染
- 公共模板簡歷
- 事件及事件繫結
- 引用
- 頁面跳轉
- wx.switchTab
- wx.reLaunch
- wx.redirectTo
- x.navigateTo
- wx.navigateBack
- 設定tabBar
- 頁面生命週期
- 轉發分享
小程式高階
- request請求後臺介面
- http-promise封裝
- webview
- 獲取使用者收貨地址
- 獲取地理位置
- 自定義元件
- 微信小程式支付問題
小程式專案實戰
- 微信小程式本地資料快取
- 下拉重新整理和下拉載入
- 列表頁向詳情頁跳轉(動態修改title)
- 客服電話
- 星級評分元件
- 小程式插槽的使用slot
- 模糊查詢
- wxs過濾
- 小程式動畫
- 列表根據所引致渲染
- 小程式動態修改class
- 小程式常用框架
- 引數傳值的方法
- 提高小程式的應用速度
- 微信小程式的優劣勢
- 小程式的雙向繫結和vue的區別
- 微信小程式給按鈕新增動畫
- 微信小程式的tab按鈕的轉化
- 為小程式引進echarts
- app開啟小程式流程
- 小程式解析富文字編輯器
小程式常見bug
- 域名必須是HTTPS
- input元件placeholder字型顏色
- wx.navigateTo無法跳轉到tabbar的頁面
- tabbar在切換時頁面資料無法重新整理
- 如何去掉自定義button灰色的圓角邊框
- input textarea是APP的原生元件, z-index層級最高
- 一段文字如何換行
- 設定最外成標籤的margin-bottom在IOS下不生效
- 小程式中canvas的圖片不支援base64格式
- 回到頁面頂部
- wx.setStorageSync和wx.getStorageSync報錯問題
- 如何獲取微信群名稱
- new Date跨平臺相容性問題
- wx.getSystemInfoSyns獲取windowHeight不準確
- 圖片本地資源名稱,儘量使用小寫命名
移動端熱點問題
- px border問題
- 2X圖 3X圖適配
- 圖片在安卓上, 有些裝置模糊問題
- 固定定位佈局, 鍵盤擋住輸入框內容
- click的300ms延遲問題和點選穿透問題
- phone以及ipad下輸入框預設內陰影
- 防止手機中頁面放大和縮小
- px, em, rem, %, vw, vh, vm這些單位的區別
- 移動端適配 - dpr淺析
- 移動端擴充套件點選區域
- 上下拉動滾動條時 卡頓、慢
- 長時間按住頁面出現閃退
- iOS和Android下觸控元素時出現半透明灰色遮罩
- active相容處理 即偽類 :active失效
- webkit mask相容處理
- pc端與移動端字型大小的問題
- transition閃屏
- 圓角bug
- 如何解決禁用表單後移動端樣式不統一問題