Vue3自考題
1,如何使用vue3的組合式api
答:
- 在普通的前端項(xiàng)目工程中,在script標(biāo)簽中增加setup即可使用api
- 使用setup()鉤子函數(shù)
2,computed 與各個(gè)watch之間和method的區(qū)別
答:
注意:
- 不要在計(jì)算屬性中進(jìn)行異步請求或者更改DOM
- 不要直接修改computed的值
區(qū)別:
- 計(jì)算屬性值基于其響應(yīng)式依賴被緩存,意思就是只要他之前的依賴不發(fā)生變化,那么調(diào)用他只會返回之前緩存的結(jié)果,而watch是監(jiān)聽的對象發(fā)生變化,則會被觸發(fā),方法則是每次重新渲染或者手動調(diào)用就會發(fā)生變化
3,如何進(jìn)行樣式綁定
答:
-
使用 :class 進(jìn)行綁定
<div :class="{ active: isActive }"></div> //綁定一個(gè)對象 編譯后: <div class="hello"></div> <div :class="[activeClass, errorClass]"></div> //綁定一個(gè)數(shù)組 編譯后: <div class="activeValue errorValue"></div> let isActive = "hello" let activeClass = "activeValue" let errorClass = "errorValue"
-
使用內(nèi)聯(lián)樣式進(jìn)行綁定
<div :style="{ 'font-size': fontSize + 'px' }"></div>
4,v-if 與 v-show 的應(yīng)用場景和區(qū)別
答
應(yīng)用場景:如果切換不是太頻繁,則應(yīng)該使用v-if,反之使用v-show
區(qū)別:v-if是銷毀后在新建,v-show則是通過display:none來控制,v-show的性能比v-if的性能要高一些
5,v-if,v-for的優(yōu)先級問題
答: vue2中v-for優(yōu)先于v-if,vue3相反。不建議在同一節(jié)點(diǎn)同時(shí)使用vif,與v-for,如果想過濾一些數(shù)據(jù)的話,可以這樣做
<div v-for="item in computedItems" :key="item.id" /> //computedItems是經(jīng)過處理后的數(shù)據(jù)列表。
6,vue3 修改了數(shù)組的哪些方法,使其能監(jiān)聽響應(yīng)式數(shù)組的變更方法
答:push(),pop(),shift(),unshift(),splice(),sort(),reverse()
7,vue3修飾符
- 事件修飾符
修飾符 | 說明 |
---|---|
.stop | 事件停止冒泡 |
.prevent(坡蕊溫特) | 阻止標(biāo)簽?zāi)J(rèn)行為 |
.capture | 使用事件捕獲模式,即元素自身觸發(fā)的事件先在此處處理,然后才交由內(nèi)部元素進(jìn)行處理 |
.self | 只當(dāng)在event.target 是當(dāng)前元素自身時(shí)觸發(fā)處理函數(shù) |
.once | 事件將只會觸發(fā)一次 |
.passive([?p?s?v]) | 不阻止事件默認(rèn)行為 |
- 按鍵修飾符
修飾符 | 說明 |
---|---|
.enter | 按回車 |
.tab | TAB鍵 |
.delete | 刪除鍵 |
.esc | ESC |
.space ([spe?s]) | 空格 |
.up||.down||.left||.right | 上下左右方向鍵 |
- v-model修飾符
修飾符 | 說明 |
---|---|
.lazy | 在每次 change 事件后更新數(shù)據(jù) |
.number | 用戶輸入自動轉(zhuǎn)換為數(shù)字,如果parseFloat()無法解析,那么則返回原始值 |
.trim | 去除用戶輸入值兩端的空格 |
8,vue的生命周期
- vue2:
生命周期(頁面) | 說明 |
---|---|
beforeCreate | 組件實(shí)例被創(chuàng)建之前,此時(shí)data還未生成。 |
created | 實(shí)例創(chuàng)建后,此時(shí)vm已經(jīng)生成,但是還未掛載到頁面上,el還未生成 |
beforeMount | 實(shí)例掛載前,此時(shí)vm即將要掛載到dom上,el還不生成 |
mounted | 實(shí)例掛載后,此時(shí)頁面已經(jīng)渲染成功,可以訪問到el |
beforeUpdate | 實(shí)例數(shù)據(jù)更新前, |
updataed | 數(shù)據(jù)更新后 |
beforedestory | 實(shí)例銷毀前,此時(shí)實(shí)例還未銷毀 |
destoryed | 實(shí)例銷毀后 |
生命周期(組件) | 說明 |
---|---|
actived | 被 keep-alive 緩存的組件激活時(shí)調(diào)用。 |
deactivated | 被 keep-alive 緩存的組件失活時(shí)調(diào)用。 |
- vue3:
生命周期(組合式API) | 說明 |
---|---|
onMounted | 在組件掛載完成后執(zhí)行。ssr渲染不會被調(diào)用 |
onUpdated | 在組件因?yàn)?strong>響應(yīng)式狀態(tài)變更而更新其 DOM 樹之后調(diào)用。ssr渲染不會被調(diào)用 |
onUnmounted | 在組件實(shí)例被卸載之后調(diào)用。ssr渲染不會被調(diào)用 |
onBeforeMount | 在組件被掛載之前被調(diào)用 |
onBeforeUpdate | 在組件即將因?yàn)?strong>響應(yīng)式狀態(tài)變更而更新其 DOM 樹之前調(diào)用。 |
onBeforeUnmount | 在組件實(shí)例被卸載之前調(diào)用。 |
onErrorCaptured | 在捕獲了后代組件傳遞的錯(cuò)誤時(shí)調(diào)用 |
生命周期(組件) | 說明 |
---|---|
onActivated | 若組件實(shí)例是 KeepAlive 緩存樹的一部分,當(dāng)組件被插入到 DOM 中時(shí)調(diào)用 |
onDeactivated | 注冊一個(gè)回調(diào)函數(shù),若組件實(shí)例是 KeepAlive 緩存樹的一部分,當(dāng)組件從 DOM 中被移除時(shí)調(diào)用。 |
生命周期(選項(xiàng)式API) | 說明 |
---|---|
beforeCreate | 在組件實(shí)例初始化完成之后立即調(diào)用。 |
created | 在組件實(shí)例處理完所有與狀態(tài)相關(guān)的選項(xiàng)后調(diào)用。 |
beforeMount | 在組件被掛載之前調(diào)用。 |
mounted | 在組件被掛載之后調(diào)用。 |
beforeUpdate | 在組件即將因?yàn)橐粋€(gè)響應(yīng)式狀態(tài)變更而更新其 DOM 樹之前調(diào)用。 |
updated | 在組件因?yàn)橐粋€(gè)響應(yīng)式狀態(tài)變更而更新其 DOM 樹之后調(diào)用 |
beforeUnmount | 在一個(gè)組件實(shí)例被卸載之前調(diào)用。 |
unmounted | 在一個(gè)組件實(shí)例被卸載之后調(diào)用。 |
errorCaptured | 在捕獲了后代組件傳遞的錯(cuò)誤時(shí)調(diào)用。 |
9,組件注冊的方式
-
全局注冊:vue.component
//語法 vue.component(componentName:string,template:components)
-
局部注冊
- setup注冊:如果使用了setup函數(shù),則在組件引入后,即可直接使用,而無需注冊
- components:直接在里面注冊,然后在template模板中直接引用
10,組件接收prop的方式
-
組合式api:使用defineProps函數(shù)
let props = defineProps({ prop1 })
-
選項(xiàng)式api:props
props:{ prop1, }
11,vue哪個(gè)生命周期才能訪問dom,為什么
- vue在mounted實(shí)例掛載后才可以訪問dom,因?yàn)榇藭r(shí)vue實(shí)例已經(jīng)掛載到了el上
12,組件中的data為什么是個(gè)函數(shù)
答:因?yàn)関ue中組件是復(fù)用的,如果組件中的data返回的是個(gè)對象的話,那么在多個(gè)組件同用一個(gè)data的時(shí)候,往往這個(gè)組件中的data發(fā)生了改變,那么其他組件也會發(fā)生改變。為了避免這個(gè)問題,就必須返回一個(gè)函數(shù),這就相當(dāng)于為每個(gè)組件開辟了一個(gè)私有的data
13,什么是MVVM?
- MVVM是一種設(shè)計(jì)思想,M代表的是model,V代表的是視圖,VM代表的是控制器,負(fù)責(zé)的是視圖與數(shù)據(jù)模型的交互
- MVVM能實(shí)現(xiàn)前端開發(fā)和js邏輯層的分離
14,vue2組件的通信方式
答:
- 父傳子:父組件直接在子組件上綁定屬性,然后子組件用props來接收
- 子傳父:子組件使用**$emit(‘eventName’,params)**來向父組件傳遞信息,父組件使用on來監(jiān)聽子組件傳遞過來的事件,在methods中進(jìn)行處理
- 父傳子孫:使用provide 分發(fā) ,inject接收
- 使用eventBus.js
- 插件使用vuex
15,如何實(shí)現(xiàn)vue首屏加載優(yōu)化的?
- 把不常改變的庫放到index.html中,用cdn來引入
- 使用路由懶加載
- 一些較小的圖片使用base64格式返回
- 使用輕量型的工具庫
- vue組件盡量不要全局引入
- 使用雪碧圖(將多個(gè)小圖片合并成一張大圖,通過定位來控制位置)
16,vue項(xiàng)目性能優(yōu)化
- 壓縮代碼
- v-if和v-for區(qū)分使用場景
- 路由懶加載
- 單頁面使用keep-alive緩存
- 使用防抖節(jié)流
- 避免書寫行內(nèi)樣式,以免造成重繪
- 使用輕量型工具庫
- dll分包
17,watch與watchEffect的區(qū)別
答:
-
區(qū)別:
- watch只追蹤明確偵聽的數(shù)據(jù)源,僅在數(shù)據(jù)源確實(shí)改變時(shí)觸發(fā)回調(diào)
- watchEffect則會在副作用發(fā)生期間追蹤依賴,會在同步過程中,自動追蹤所有能訪問到的響應(yīng)式屬性
-
watchEffect的觸發(fā)時(shí)機(jī)
-
語法
watch(source, callback, options) watchEffect(callback, options)
-
post:能在偵聽器回調(diào)中訪問被 Vue 更新之后的 DOM,他的另一個(gè)別名函數(shù)叫做:watchPostEffect()
-
sync:有必要在響應(yīng)式依賴發(fā)生改變時(shí)立即觸發(fā)偵聽器的時(shí)候 別名:watchSyncEffect()
-
-
watch的options
watch (source: WatchSource<T>, callback: WatchCallback<T>, options?: WatchOptions) watchOptions:{ immediate ( [??mi?di?t] ):boolean, // 偵聽器創(chuàng)建時(shí)立即觸發(fā)回調(diào)。第一次調(diào)用時(shí)舊值是 undefined deep:boolean,//如果源是對象,強(qiáng)制深度遍歷,以便在深層級變更時(shí)觸發(fā)回調(diào) flush:post|sync,//觸發(fā)時(shí)機(jī) onTrack / onTrigger:調(diào)試偵聽器的依賴。 }
18,常用api參考
18.1,全局api
api | 說明 | 補(bǔ)充 |
---|---|---|
createApp(rootComponent:component,rootOptions:Object) | 創(chuàng)建一個(gè)vue實(shí)例 | Object是要傳遞給跟組件的props |
createSSRApp() | 從服務(wù)端創(chuàng)建一個(gè)實(shí)例 | 跟createApp一樣的,區(qū)別是ssr |
app.mount(rootContainer: Element||string) | 將應(yīng)用實(shí)例掛載在一個(gè)容器元素中。 | 對于每個(gè)應(yīng)用實(shí)例,mount() 僅能調(diào)用一次。 |
app.unmount() | 卸載一個(gè)已掛載的應(yīng)用實(shí)例。 | 卸載一個(gè)應(yīng)用會觸發(fā)該應(yīng)用組件樹內(nèi)所有組件的卸載生命周期鉤子。 |
app.provide(key:InjectionKey|symbol|string , value:T) | 提供一個(gè)值,可以在應(yīng)用中的所有后代組件中注入使用。 | |
app.component(name: string, component: Component): this app.component(name:string ): Component|undefined |
如果傳入一個(gè)組件名和一個(gè)組件,則代表全局注冊一個(gè)組件,只傳入一個(gè)組件名,那么返回一個(gè)組件或者undefined | this:指的是注冊的組件 |
app.directive(name:string): directive|undefined app.directive(name: string, directive: directive): this |
注冊指令 | this指的是指令 |
app.use(plugin: Plugin, …options: any[]): this | 安裝一個(gè)插件。 | Plugin:插件 options:要傳遞給插件的選項(xiàng)。 this:返回的是插件本身 |
app.mixin(mixin: ComponentOptions): this | 混入 | vue3不推薦用了,可以用組合式函數(shù)來代替 |
18.2,通用api
api | 說明 | 補(bǔ)充 |
---|---|---|
nextTick(callback?: () => void): Promise | 等待下一次 DOM 更新刷新的工具方法。 | 常用來解決同步失效的問題 |
defineComponent(component: ComponentOptions | ComponentOptions[‘setup’]):ComponentConstructor | 在定義 Vue 組件時(shí)提供類型推導(dǎo)的輔助函數(shù)。 | 最大的用處就是給ts提供更好的類型推導(dǎo) |
18.3,組合式api
api | 說明 | 補(bǔ)充 |
---|---|---|
setup(props,this) | 組合式api的入口 | props:組件的 props this:Setup 上下文對象 |
ref(value) | 把value變成一個(gè)ref代理對象,并把他返回來 | 默認(rèn)訪問屬性需要value.value才能訪問到 |
computed(getter:() => T) | 計(jì)算屬性 | |
reactive(Object) | 返回一個(gè)對象的響應(yīng)式代理。 | |
readonly(object) | 返回一個(gè)object的只讀代理 | |
watchEffect(effect: (onCleanup: OnCleanup) => void, options?: WatchEffectOptions): StopHandle | 立即運(yùn)行一個(gè)函數(shù),同時(shí)響應(yīng)式地追蹤其依賴,并在依賴更改時(shí)重新執(zhí)行。 | StopHandle:返回一個(gè)停止監(jiān)聽 |
watchPostEffect() |
watchEffect() 使用 flush: 'post' 選項(xiàng)時(shí)的別名。 |
設(shè)置 flush: 'post' 將會使偵聽器延遲到組件渲染之后再執(zhí)行 |
watchSyncEffect() |
watchEffect() 使用 flush: 'sync' 選項(xiàng)時(shí)的別名。 |
在某些特殊情況下 (例如要使緩存失效),可能有必要在響應(yīng)式依賴發(fā)生改變時(shí)立即觸發(fā)偵聽器。 |
watch (source: WatchSource, callback: WatchCallback, options?: WatchOptions) | 偵聽一個(gè)或多個(gè)響應(yīng)式數(shù)據(jù)源,并在數(shù)據(jù)源變化時(shí)調(diào)用所給的回調(diào)函數(shù)。 | WatchOptions: |
響應(yīng)式工具 | ||
isRef(r: Ref|unknown) | 檢查某個(gè)值是否為 ref。 | 請注意,返回值是一個(gè)類型判定 (type predicate),這意味著 isRef 可以被用作類型守衛(wèi) |
unref(ref: T | Ref): T | 如果參數(shù)是 ref,則返回內(nèi)部值,否則返回參數(shù)本身。這是 val = isRef(val) ? val.value : val 計(jì)算的一個(gè)語法糖 |
|
toRef(T extends object, K extends keyof T) | 基于響應(yīng)式對象上的一個(gè)屬性,創(chuàng)建一個(gè)對應(yīng)的 ref。 | |
toRefs(T) | 將一個(gè)響應(yīng)式對象轉(zhuǎn)換為一個(gè)普通對象, | |
isProxy(value: unknown): boolean | 檢查一個(gè)對象是不是proxy對象 | |
isReactive(value: unknown): boolean | 檢查一個(gè)對象是否是由 reactive() 或 shallowReactive() 創(chuàng)建的代理。 |
|
isReadonly(value: unknown): boolean | 檢查傳入的值是否為只讀對象。 | |
依賴注入 | ||
provide(key: InjectionKey | string, value: T): void | 提供一個(gè)值,可以被后代組件注入。 | key:要注入的 key value:要注入的值 |
inject() | 注入一個(gè)由祖先組件或整個(gè)應(yīng)用 (通過 app.provide() ) 提供的值。也可以理解為接收 |
19,keep-alive組件首次渲染,二次渲染觸發(fā)的生命周期
答:
- 第一次進(jìn)入觸發(fā)的生命周期是:created -> mounted -> activated,退出時(shí)觸發(fā)deactivated
- 第二次渲染時(shí):只觸發(fā)activated
20,如何實(shí)現(xiàn)動態(tài)添加keep-alive組件
通過路由中的meta對象下的keepAlive(boolean)屬性來控制緩存組件是否緩存
語句:this.$route.meta.keepAlive=true||false
21,vue的優(yōu)勢
- vue是一種基于MVVM軟件設(shè)計(jì)架構(gòu)的輕量型框架
- vue可以進(jìn)行組件化開發(fā)
- vue可以實(shí)現(xiàn)雙向數(shù)據(jù)綁定
- vue視圖和數(shù)據(jù)結(jié)構(gòu)分離,
- vue的生態(tài)好,有豐富的ui框架以及插件
- vue不直接操作dom,vue是先通過diff算法生成ast樹,然后通過pach算法比較差異,再生成dom樹
- vue是單項(xiàng)數(shù)據(jù)流
22,虛擬dom的優(yōu)缺點(diǎn)
- 保證性能下限
- 無需手動操作dom
- 跨平臺
- 缺點(diǎn)是無法進(jìn)行極致優(yōu)化
24,解決跨域的方法
- 在vue.config.js中的devserve.proxy:{url:“地址”}中可以解決跨域
- 跨域是指不在同源策略(域名,協(xié)議,端口一致)內(nèi),就會產(chǎn)生跨域
- 也可以設(shè)置nginx(恩急殼死)反向代理來解決跨域
- 也可以用jsonp來解決跨域,只支持get調(diào)用
26,插槽slot簡介
-
分類:
-
具名插槽:帶有名字的插槽
//組件內(nèi) <component> <heander> <slot name = "header"></slot> //這個(gè)name就是插槽的名字 </header> </component> //使用組件 <componentName> <template v-slot:header> //v-slot后面跟的就是剛才設(shè)定的插槽名字 插槽內(nèi)容 </template> </componentName>
-
匿名插槽:沒有名字的插槽,一個(gè)標(biāo)簽只能有一個(gè)匿名插槽
-
作用域插槽:
<MyComponent v-slot="{ text, count }"> {{ text }} {{ count }} </MyComponent>
-
動態(tài)插槽名:
<base-layout> <template v-slot:[dynamicSlotName]> ... </template> <!-- 縮寫為 --> <template #[dynamicSlotName]> ... </template> </base-layout>
-
-
縮寫形式:#
-
作用:可以擴(kuò)展組件,增加組件的靈活性
27,動態(tài)組件&異步組件
-
動態(tài)組件
動態(tài)組件需要用keep-alive標(biāo)簽
-
異步組件
異步組件需要使用vue.component(“組件名”,callback():promise),返回一個(gè)模板對象
28,vue雙向綁定原理
-
vue2:
使用了Object.defineProperty結(jié)合發(fā)布者/訂閱設(shè)計(jì)模式,遞歸遍歷對象的每個(gè)屬性,為每個(gè)屬性都設(shè)置了setter/getter,一旦屬性發(fā)生了變化,則通知相關(guān)的訂閱者,訂閱者調(diào)用setter直接改變對象的屬性
-
vue3:
使用Proxy代理對象來實(shí)現(xiàn)。
29,render()函數(shù)的使用
- 使用場景:當(dāng)場景中用template實(shí)現(xiàn)起來代碼繁瑣且有大量重復(fù)的時(shí)候
- render(contentHTML,htmlStyle,vNode),參數(shù)一:模板結(jié)構(gòu),參數(shù)二,模板樣式,參數(shù)三,設(shè)置分發(fā)內(nèi)容
30,父子組件的渲染過程,更新過程,銷毀過程
- 渲染過程:父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子beforeMount -> 子mounted ->父mounted
- 更新過程:
- 父beforeUpdate -> 子beforeUpdate -> 子updated ->父updated —
- 子組件更新過程
- beforeUpdate -> updated
- 銷毀過程:父beforeDestory -> 子beforeDestory -> 子destoryed ->父 destoryed
31,實(shí)現(xiàn)頁面刷新幾種方法,以及優(yōu)缺點(diǎn)
- 使用this.$route.go(0)
- 優(yōu)點(diǎn):簡單,方便,快,寫的代碼還少
- 缺點(diǎn):會有一秒鐘的白屏和閃爍。用戶體驗(yàn)機(jī)器不好
- 使用location.reload():頁面閃爍
- provide、inject和$nextTick:常用
- 新建空白頁,利用
$router.replace
路由跳轉(zhuǎn)到一個(gè)空白頁面,然后在空白頁面中立即執(zhí)行$router.replace
切換到原來的頁面
vuex 部分
1,vuex中狀態(tài)存儲在那里?如何去改變他?
答:存儲在state中,改變state的狀態(tài)只能通過mutation,或者通過Action使用commit觸發(fā)mutation來改變狀態(tài)111
2,vuex頁面刷新數(shù)據(jù)丟失怎么辦?
答:
- 把數(shù)據(jù)存到本地
- 使用vuex-persist (破爾色死特)插件
3,簡述vuex得數(shù)據(jù)傳遞流程
- 使用dispatch||commit來觸發(fā)action和mutition中得方法來改變state狀態(tài)
- 使用getter來向外暴露state
- 然后在頁面可以使用助手函數(shù)mapstate來獲取vuex中得state,或者使用this.$store.state來獲得數(shù)據(jù)
4,vuex中Mutation與Action得區(qū)別是什么?
- Mutation可以直接改變state得狀態(tài),這里進(jìn)行得是同步操作
- Action不可以直接改變state得狀態(tài),不過這里可以進(jìn)行異步操作
5,vuex嵌套的子模塊中可以重復(fù)嵌套嗎?
答:
可以,因?yàn)槊恳粋€(gè)子模塊中都有 state,namespaced,mutations,actions,getters,modules,而且模塊中多了一個(gè)屬性namespace(命名空間),當(dāng)模塊被注冊后,它的所有 getter、action 及 mutation 都會自動根據(jù)模塊注冊的路徑調(diào)整命名,
6,vuex和pinia(皮尼?。┑膮^(qū)別
- Pinia 對 vue2 和 vue3 都支持,尤其是 TypeScript 的項(xiàng)目
- 沒有模塊的嵌套結(jié)構(gòu)
- 不需要注入、導(dǎo)入函數(shù)、調(diào)用它們
- 無需手動添加 store ,它的模塊默認(rèn)情況下創(chuàng)建就自動注冊的
- 支持 Vue DevTools
- 支持服務(wù)端渲染
- Vuex: State、Gettes 、 Mutations (同步)、 Actions (異步),modules(子模塊)
Pinia: State、Gettes 、 Actions (同步異步都支持)
7,組合式api中如何使用vuex
答:
在組合式api中,需要先引入useStore函數(shù)import {userStore} form vuex
8,dispatch和commit的區(qū)別
- 相同點(diǎn):二者最終都是用來提交mutation來更改state的值的
- 不同點(diǎn):dispatch是異步提交,commit是同步提交
vue-router部分
1,怎么在組件中監(jiān)聽路由參數(shù)的變化
- 在watch直接監(jiān)聽$route(to,from)
- 在路由導(dǎo)航守衛(wèi)中監(jiān)聽,beforeRouterEnter
2,Vue-router是干什么得?他得原理是什么
答:
vue-router是vue官方指定的路由插件,是單頁面應(yīng)用的核心組成部分,vue-router用于設(shè)定訪問路徑,并將路徑和組件映射起來。傳統(tǒng)多頁面應(yīng)用中,頁面跳轉(zhuǎn)是用超鏈接來實(shí)現(xiàn)頁面切換和跳轉(zhuǎn)的,但在單頁面應(yīng)用中,頁面跳轉(zhuǎn)則是使用路徑的切換,路由的作用是建立url和頁面的映射關(guān)系
vue-router的實(shí)現(xiàn)主要靠url中的hash和history中新增的接口來實(shí)現(xiàn)的。
3,路由間是如何跳轉(zhuǎn)得?
- 在route-link中使用to屬性來進(jìn)行跳轉(zhuǎn)
- 在js中使用this. r o u t e r . p u s h ( ) 或者 t h i s . router.push()或者this. router.push()或者this.router.replace(),或this. r o u t e r . g o ( ) , t h i s . router.go(),this. router.go(),this.router.back()來進(jìn)行跳轉(zhuǎn)
4,vue-router怎么配置路由
新建一個(gè)router文件夾,建立一個(gè)index文件,然后引入router,創(chuàng)建一個(gè)routers路由表,實(shí)例化一個(gè)router對象,使用這個(gè)路由表,設(shè)定mode
5,vue-router有哪幾種路由守衛(wèi)
-
全局守衛(wèi):
- beforeEach(to,from,next)
- afterEach
-
獨(dú)享守衛(wèi):beforeEnter()
-
組件內(nèi)守衛(wèi)
- beforeRouterEnter
- beforeRouterUpdate
- beforeRouterLeave
6,路由傳值的方式有幾種?
-
編程式路由
- this.$router.push({name:“index”,params:{id:123}})
- 接收參數(shù),在路由頁面使用this.$route.params來接收
-
聲明式路由
-
獲取路由參數(shù)
this. r o u t e . p a r a m s , t h i s . route.params,this. route.params,this.route.query
7,route和router的區(qū)別
route是頁面路由對象,他里面會有query,params等屬性,router是全局路由對象mate路由元數(shù)據(jù)等
8,vue-router中常用的路由模式實(shí)現(xiàn)原理
- hash模式:利用window.hashChange來實(shí)現(xiàn)
- history:通過H5的history 新增的pushState和replaceState來實(shí)現(xiàn)
常用的庫
庫 | 說明 | 補(bǔ)充 |
---|---|---|
Lodash.js | Lodash 通過降低 array、number、objects、string 等等的使用難度從而讓 JavaScript 變得更簡單。非常適用于:遍歷 array、object 和 string 對值進(jìn)行操作和檢測 創(chuàng)建符合功能的函數(shù) | |
PDF.js | 由js編寫的pdf閱讀器 | 用來解決小程序安卓端的pdf閱讀問題 |
voca.js | 提供完整的函數(shù)集來操作、截?cái)?、格式化、轉(zhuǎn)義和查詢字符串 | |
video.js | 適用于vue的js視頻播放器 | |
bowser.js | 適用于瀏覽器和節(jié)點(diǎn)的小型、快速且豐富的 API 瀏覽器/平臺/引擎檢測器。 | |
moment.js | 解析、驗(yàn)證、操作和顯示日期。 | |
countdown.js | 倒計(jì)時(shí)插件 | |
dayjs | Day.js 是一款擁有和 Moment.js 一樣的現(xiàn)代化接口的日期庫,但它僅僅有 2kb 大小,可以用來替換 Moment.js。 | |
accounting.js | 對數(shù)字、金錢、貨幣進(jìn)行格式化的輕量庫,完全本地化和無依賴。 | 英文發(fā)音:鵝康聽 |
chance.js | JavaScript 隨機(jī)生成器,可以生成數(shù)字、字符串等。 | |
Vue I18n | 國際化vue插件 | 用來做中英適配 |
log | 瀏覽器日志插件 | 看日志更方便點(diǎn) |
qs.js | qs.js是用來處理url中參數(shù)的一個(gè)js庫 | |
js-cookie | 用于處理 cookie 的簡單、輕量級 JavaScript API | |
flv.js | 一個(gè)用純 JavaScript 編寫的 HTML5 Flash 視頻 (FLV) 播放器,沒有 Flash。 | 嗶哩嗶哩開源的 |
mpegts.js | flv.js的迭代品 | |
Animate.css | 一個(gè)跨瀏覽器的 css3 動畫庫,內(nèi)置了很多典型的 css3 動畫,兼容性好,使用方便。 | |
animejs | 一款功能強(qiáng)大的 Javascript 動畫庫??梢耘cCSS3屬性、SVG、DOM元素、JS對象一起工作,制作出各種高性能、平滑過渡的動畫效果。 | |
mescroll.js | 一款精致的、在H5端運(yùn)行的下拉刷新和上拉加載插件,主要用于列表分頁、刷新等場景。 |
axios
1,axios是什么,怎么使用他,怎么解決跨域問題
- axios是基于promise的http庫,是vue官方指定的http庫
- axios需要npm install axios 和npm install vue-axios
- axios解決跨域需要在請求頭加上content-type即可
移動端適配
1,解決方案
- postcss-px-to-viewport
- 使用rem+媒體查詢
- 使用flex布局
小程序相關(guān)
1,哪些函數(shù)擁有頁面跳轉(zhuǎn)的功能?
- uni. navigateTo (Object):保留當(dāng)前頁面到路由棧中,然后跳轉(zhuǎn)目標(biāo)頁面
- uni.redirectTo(Object): 關(guān)閉當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個(gè)頁面。
- uni.reLaunch(Object):關(guān)閉所有頁面,打開到應(yīng)用內(nèi)的某個(gè)頁面。
- uni.switchTab():跳轉(zhuǎn)到 tabBar 頁面,并關(guān)閉其他所有非 tabBar 頁面。
- uni.navigateBack(Object):關(guān)閉當(dāng)前頁面,返回上一頁面或多級頁面
2,uniapp如何進(jìn)行條件編譯?
**寫法:**以 #ifdef 或 #ifndef 加 **%PLATFORM%** 開頭,以 #endif 結(jié)尾。
- #ifdef:if defined 僅在某平臺存在
- #ifndef:if not defined 除了某平臺均存在
- %PLATFORM%:平臺名稱
3,如何進(jìn)行頁面滾動監(jiān)聽
使用onPageScroll 生命周期函數(shù)監(jiān)聽
4,小程序切換tabbar,不觸發(fā)onload怎么解決
在onTabItemTap()生命周期中寫入代碼
5,頁面獲取數(shù)據(jù),渲染閃爍
可能頁面上存在圖片,但是沒有指定高度。
6,小程序優(yōu)化方案
-
核心點(diǎn):
-
提高加載性能
-
加載流程:
-
代碼包準(zhǔn)備(下載代碼包)優(yōu)化措施:
- 分包加載
- 代碼重構(gòu)和優(yōu)化:減少不常用的庫引入和依賴
- 避免在代碼包中包含過多,過大的圖片,應(yīng)盡量采用網(wǎng)絡(luò)圖片
- 清理無用代碼
-
開發(fā)者代碼注入
-
減少啟動過程的同步調(diào)用
- 在小程序啟動流程中,會注入開發(fā)者代碼并順序同步執(zhí)行App.onLaunch(昂藍(lán)吃),App.onShow,Page.onLoad,Page.onShow。
- 在小程序初始化代碼(Page,App定義之外的內(nèi)容)和啟動相關(guān)的幾個(gè)生命周期中,應(yīng)避免執(zhí)行復(fù)雜的計(jì)算邏輯或過度使用以Sync結(jié)尾的同步API,如:wx.getStorageSync,wx.getSystemInfoSync等。
- 對于getSystemInfo,getSystemInfoSync的結(jié)果應(yīng)進(jìn)行緩存,避免重復(fù)調(diào)用。
-
使用懶注入
通常情況下,小程序啟動時(shí),啟動頁面所在分包和主包(獨(dú)立分包除外)的所有js代碼會全部合并注入,包括其他未訪問到的頁面和未用到的自定義組件。影響注入耗時(shí)和內(nèi)存占用-
開啟僅注入當(dāng)前頁面需要的自定義組件和當(dāng)前頁面代碼,在app.json中配置
{ "lazyCodeLoading":"requiredComponents" }
-
-
-
初次渲染
- 骨架屏:提升用戶等待意愿
- 提升首屏數(shù)據(jù)請求
- 數(shù)據(jù)預(yù)拉取
- 周期性更新
- 精簡首屏數(shù)據(jù):
- 數(shù)據(jù)懶加載
- 數(shù)據(jù)合并
- 減少請求次數(shù)
- 數(shù)據(jù)局部更新
- 緩存請求數(shù)據(jù):可以使用wx.setStorage,wx.getStorage等讀寫本地緩存的能力,來提升首屏數(shù)據(jù)渲染
-
-
-
提高渲染性能
- 及時(shí)清理定時(shí)器,因?yàn)樾〕绦蚬蚕硪粋€(gè)js運(yùn)行環(huán)境
- 謹(jǐn)慎使用onPageScorll
- 合理封裝組件:可以將一些高頻執(zhí)行setData的功能模塊封裝成組件,
- 圖片懶加載:渲染頁面時(shí),只渲染出現(xiàn)在視圖范圍內(nèi)的元素。
- 善用onload和onReady:
- onload是頁面加載階段,在onload階段請求頁面展示數(shù)據(jù),
- onready是頁面加載完成階段,對于頁面之后需要展示或者使用,但剛開始并不展示的數(shù)據(jù)可以在onReady階段進(jìn)行請求。
-
7,小程序登錄流程
- 通過wx.login()獲取code
- 向服務(wù)端發(fā)送code
- 服務(wù)端使用appid+appsecret+code登錄憑證來對接微信接口服務(wù)
- 后端返回seesion_key+openId,
- 后端自定義登錄態(tài),與openid,session_key關(guān)聯(lián)
- 后端返回給前端自定義登錄狀態(tài)
- 前端將登錄狀態(tài)存入本地(setStorageSync)
- 前端攜帶登錄態(tài)發(fā)起業(yè)務(wù)請求
- 后端校驗(yàn)登錄態(tài),
- 后端返回業(yè)務(wù)數(shù)據(jù)
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-2rO9rkJy-1676604621014)(https://res.wx.qq.com/wxdoc/dist/assets/img/api-login.2fcc9f35.jpg)]
原生js
1,檢測數(shù)據(jù)類型
- 基本類型:typeof
- 復(fù)雜類型:instanceof, Array.isArray() , object.prototype.toString.call( type )
2,call , apply 的區(qū)別以及功能
功能:對象A調(diào)用對象b的方法。改變this的指向,call的性能會更好一些。
不同的地方:傳遞參數(shù)不同,apply接收數(shù)組,call 接收參數(shù)1,2,3
3,== 和 === 的區(qū)別
==會進(jìn)行類型隱式轉(zhuǎn)換,===不會
4,什么是同源策略
同協(xié)議,同域名,同端口
5,js中的數(shù)據(jù)類型
基本類型:number,string ,boolean,null,undefined,symbol,
引用類型:array,object,
6,pormise的優(yōu)缺點(diǎn)
-
優(yōu)點(diǎn)
- 統(tǒng)一異步api:
- 可以鏈?zhǔn)秸{(diào)用。
- 解決回調(diào)地獄(回調(diào)函數(shù)里嵌套回調(diào)函數(shù))的問題
-
缺點(diǎn)
- 無法取消promise
- 如果不設(shè)置回調(diào)函數(shù),promise內(nèi)部拋出的錯(cuò)誤,不會反應(yīng)到外部
- 當(dāng)處于pending狀態(tài)時(shí)無法獲取狀態(tài)進(jìn)展到哪個(gè)階段。
- Promise 真正執(zhí)行回調(diào)的時(shí)候,定義 Promise 那部分實(shí)際上已經(jīng)走完了,所以 Promise的報(bào)錯(cuò)堆棧上下文不太友好。
7,瀏覽器的渲染過程
- 用戶輸入域名,然后dns解析成ip地址
- 瀏覽器根據(jù)ip地址請求服務(wù)器
- 服務(wù)器響應(yīng)http請求,并返回?cái)?shù)據(jù)給瀏覽器
- 瀏覽器開始渲染
- 根據(jù)html,生成dom樹
- 根據(jù)css,生成css樹
- 將html樹與css樹結(jié)合,生成render樹
- 根據(jù)render樹渲染頁面
- 遇到script,則暫停渲染,優(yōu)先執(zhí)行js,然后繼續(xù)渲染。
- 渲染完成。
8,哪些行為會造成內(nèi)存泄漏
- 意外的全局變量
- 沒有及時(shí)清除的定時(shí)器
- 脫離dom的元素引用(一個(gè)dom容器刪除之后,變量未置為null,則其內(nèi)部的dom元素則不會釋放。)
- 持續(xù)綁定的事件(函數(shù)中addEventListener綁定事件,函數(shù)多次執(zhí)行,綁定便會產(chǎn)生多次,產(chǎn)生內(nèi)存泄漏。)
- 閉包
- console.log不能被垃圾回收
9,async/await的優(yōu)缺點(diǎn),他和pormise的使用場景分別是
- **缺點(diǎn):**await可能會造成線程阻塞
-
優(yōu)點(diǎn):
- 閱讀性比較好。
- 可以直接寫在條件判斷里
- 使用場景:
- 并行的請求最好用pormise
- 不需要并行的時(shí)候,如果要傳遞參數(shù),最好用pormise
10,Object 于與Map的區(qū)別:
-
共同點(diǎn):都是鍵值對的動態(tài)集合,支持刪除和增加鍵值對
-
不同點(diǎn):
區(qū)別 Map Object 構(gòu)造方式 let Map = new Map([
[“key”,“value”]
])let obj = {
key:value
}key的類型 any string||symbol key的順序 有序(按照插入先后) 無序 size長度 通過訪問Map.size屬性 Object.keys() || for…in 訪問方式 判斷用has(),獲取用get(),刪除用delete(),獲取所有keys(),清空clear() .
或者[]
迭代 keys(),value(),entries() for…in JSON序列化 JSON.stringify(Array.from(map)) 通過JSON.stringify()
11,宏任務(wù)和微任務(wù)
- 宏任務(wù):
- 由宿主(瀏覽器或node)發(fā)起
- 包括:setTimeout,setInterval,MessageChannel I/O(消息通道),setImmediate(node環(huán)境),script(整體代碼塊)
- 微任務(wù):
- 由js自身發(fā)起
- MutationObserver(瀏覽器環(huán)境),pormise.[then/catch/finally],process.nextTick(node環(huán)境)
- 執(zhí)行順序:
- 首先必須先執(zhí)行所有的初始化同步任務(wù)
- 然后會檢查微任務(wù)隊(duì)列,并將其清空
- 接著取出第一個(gè)宏任務(wù)
- 當(dāng)該宏任務(wù)執(zhí)行完成,會檢查這個(gè)宏任務(wù)中還有沒有微任務(wù),如果沒有就執(zhí)行下一個(gè)宏任務(wù),如果有,則清空微任務(wù)。然后再執(zhí)行下一個(gè)宏任務(wù)。
12,簡述原型與原型鏈,原型鏈的作用有那些
- 原型:js聲明構(gòu)造函數(shù)時(shí),會在內(nèi)存中創(chuàng)建一個(gè)對應(yīng)的對象,這個(gè)對象就是原函數(shù)的原型,構(gòu)造函數(shù)中有個(gè)屬性prototype就指向原型對象,而實(shí)例化出來的對象會擁有一個(gè)proto屬性,也指向原型
- 原型鏈:當(dāng)實(shí)例化的對象查找一個(gè)屬性的時(shí)候,首先會在本身查找這個(gè)屬性,如果沒有,則去他的proto原型上去找,如果proto上沒有,那么就去proto的原型中去找,這種鏈狀過程就是原型鏈
- 作用:數(shù)據(jù)共享,節(jié)約空間,實(shí)現(xiàn)集成
13,什么是閉包?用途有那些?
-
如果一個(gè)函數(shù)訪問了此函數(shù)的父級及父級以上的作用域變量,那么這個(gè)函數(shù)就是一個(gè)閉包。
-
用途:防抖(在指定時(shí)間內(nèi),用戶多次觸發(fā)事件只觸發(fā)一次),節(jié)流(在指定間隔時(shí)間內(nèi),請求只發(fā)送一次)
-
例子
for(var i = 1;i<10;i++){ setTimeout(()=>{ console.log(i) },1000) } //11,11,11,11.... for(var i = 1;i<10;i++){ (setTimeout((j)=>{ console.log(i) }),1000)(i) } //1,2,3,4,5,6,7...
-
閉包的優(yōu)點(diǎn):
- 減少全局變量的定義數(shù)量,避免全局變量污染
- 讀取函數(shù)內(nèi)部變量
- 在內(nèi)存中維護(hù)一個(gè)變量,可以用作緩存
-
閉包的缺點(diǎn)
- 造成內(nèi)存泄露,消耗內(nèi)存,影響網(wǎng)頁性能,解決方法是用完他之后,把他設(shè)置成null
- 閉包可能在父函數(shù)外部改變父函數(shù)內(nèi)部的值
TypeScript部分
1,將對象轉(zhuǎn)化成數(shù)組
//type:類型別名 Record:用來定義對象的key和value 這句話的意思是定義一個(gè)key和value都是string類型的對象。
type Obj = Record<string,string>
//定義一個(gè)接口
interface FormatItem{
key:string,
op:string,
value:string,
}
function objToArray(obj:Record<string,Obj>) :FormatItem[]{
return Object.keys(obj).reduce((value:Array<FormatItem> , key:string)=>{
var op:string = Object.keys(obj[key])[0];
value.push({key:key,op:op,value:obj[key][op]});
return value;
},[])
}
console.log(
objToArray({
key1: {
op1: "value1",
},
key2: {
op2: "value2",
},
})
);
// result示例
// [
// {key: 'key1', op: 'op1', value: 'value1'},
// {key: 'key2', op: 'op2', value: 'value2'}
// ]
2,反轉(zhuǎn)句子
/**
* @file 反轉(zhuǎn)句子
*
* 同時(shí)滿足以下條件:1、去除首尾空格,2、單詞間隔中多個(gè)空格變成一個(gè);
* 注意console示例運(yùn)行結(jié)果
*/
function reverseWord(str: string) {
// 補(bǔ)全此處代碼
return (<string[]>str.match(/\S+/g)).reverse().join(" ");
}
console.log(reverseWord('the sky is blue')); // blue is sky the
// 去除首尾空格
console.log(reverseWord(" hello world ")); // world hello
// 單詞間隔中多個(gè)空格變成一個(gè)
console.log(reverseWord("a good example")); // example good a
export default {}
3,找出字符串中第一個(gè)只出現(xiàn)一次的字符
/**
* @file 找出字符串中第一個(gè)只出現(xiàn)一次的字符
*/
function firstSingleChar(str: string) {
// 參考答案
return str.split("").filter((item: string, index: number, arr: string[]) => {
arr.splice(index, 1);
return !arr.includes(item);
})[0];
}
// a 和 b 都出現(xiàn)了兩次,只有 c 出現(xiàn)了一次,返回 c
console.log(firstSingleChar("abcba")); // c
// b c d 都出現(xiàn)了一次,返回第一個(gè)
console.log(firstSingleChar("aabcdee")); // b
// a 和 b 都出現(xiàn)了多次,沒有只出現(xiàn)一次的元素,返回 undefined
console.log(firstSingleChar("aaaabbbb")); // undefined
console.log(firstSingleChar("dabvb"));
export default {};
4,合并兩個(gè)有序數(shù)組
/**
* @file 合并兩個(gè)有序數(shù)組
*/
function merge(arr: number[], arr2: number[]): number[] {
// 參考答案
return arr.concat(arr2).sort((a: number, b: number) => a - b);
}
// 參數(shù)數(shù)組從小到大排列
console.log(merge([1, 2, 3], [2, 5, 6])); // [ 1, 2, 2, 3, 5, 6 ]
export default {};
5,實(shí)現(xiàn)數(shù)組 map 方法
/**
* @file 實(shí)現(xiàn)數(shù)組 map 方法
*/
function myMap<T, R>(arr: T[], callbackFn: (v: T) => R): R[] {
// 參考答案
var arr1: R[] = [];
for (var i = 0; i < arr.length; i++) {
if (i in arr) arr1[i] = callbackFn(arr[i]);
}
return arr1;
}
// 測試
console.log(myMap([1, 2, 3], (v) => v * 2)); // [2, 4, 6]
export default {};
6, 二叉樹所有路徑
/**
* @file 二叉樹所有路徑
*/
type Tree = {
value: number;
left?: Tree;
right?: Tree;
};
const tree: Tree = {
value: 1,
left: {
value: 2,
right: { value: 5 },
},
right: { value: 3 },
};
function treePath(root: Tree): string[] {
// 補(bǔ)全此處代碼
// throw new Error('功能待實(shí)現(xiàn)');
const answer: [] = [];
let tmp: [][] = [];
const travel = (r: Tree) => {
if (r == null) {
return;
}
//@ts-ignore
tmp.push(r.value);
if (r.left == null && r.right == null) {
//@ts-ignore
answer.push(tmp);
tmp = [tmp[0]];
return;
}
if (r.left) travel(r.left);
if (r.right) travel(r.right);
};
travel(root);
//@ts-ignore
return answer.map((t) => t.join("->"));
}
console.log(treePath(tree)); // [ '1->2->5', '1->3' ]
export default {};
7,樹結(jié)構(gòu)映射
/**
* @file 樹結(jié)構(gòu)映射
* 數(shù)組 map 保持?jǐn)?shù)組長度相同,將對應(yīng)位置元素進(jìn)行映射。
* 與之類似,在二叉樹 Tree 上的映射我們稱為 mapTree,該函數(shù)返回一個(gè)結(jié)構(gòu)相同的新樹,對應(yīng)位置 value 字段經(jīng)過 fn 映射。
*/
type Tree = {
value: number;
left?: Tree;
right?: Tree;
};
function mapTree(tree: Tree, fn: (v: number) => number): Tree {
// 參考答案
if (tree == null) {
return tree;
}
tree.value = fn(tree.value);
if (tree.left) mapTree(tree.left, fn);
if (tree.right) mapTree(tree.right, fn);
return tree;
}
// 測試
const tree: Tree = {
value: 1,
left: { value: 2 },
right: { value: 3 },
};
console.log(mapTree(tree, (v) => v * 2)); // { value: 2, left: { value: 4 }, right: { value: 6 } }
export default {};
8,計(jì)算數(shù)組笛卡爾積
/**
* @file 計(jì)算數(shù)組笛卡爾積
*/
// 示例
console.log(product([1, 2], [3, 4])); // [[1, 3], [1, 4], [2, 3], [2, 4]]
function product(xList: number[], yList: number[]): [number, number][] {
// 參考答案
return xList.reduce((v, t) => {
return v.concat(yList.map((item) => [t, item]));
}, [] as [number, number][]);
}
export default {};
9,返回一個(gè) Promise,并在 ms 毫秒后 Promise 變?yōu)橥瓿蔂顟B(tài)
/**
* @file 返回一個(gè) Promise,并在 ms 毫秒后 Promise 變?yōu)橥瓿蔂顟B(tài)
*/
export function sleep(ms: number): Promise<undefined> {
// 參考答案
return new Promise(
(
resolve: (value: undefined) => void,
reject: (value: undefined) => void
) => {
setTimeout(() => {
resolve(undefined);
}, ms);
}
);
}
async function main() {
console.log("a");
await sleep(1000);
console.log("b");
await sleep(1000);
console.log("c");
}
main();
export default {};
10,實(shí)現(xiàn) PromiseAll 方法
/**
* @file 實(shí)現(xiàn) PromiseAll 方法
*/
import { sleep } from "./8.sleep";
async function myAll<T extends unknown[] | []>(
values: T
): Promise<{ [P in keyof T]: Awaited<T[P]> }> {
// 補(bǔ)全此處代碼,使用 Promise.all 以外的語法完成
// throw new Error('功能待實(shí)現(xiàn)');
var arr = [];
for (var i = 0; i < values.length; i++) {
arr.push(await values[i]);
}
return arr as { [P in keyof T]: Awaited<T[P]> };
}
// 一秒鐘后返回結(jié)果 value
async function request(value: string) {
await sleep(1000);
return value;
}
async function main() {
console.log("start");
const res = await myAll([request("a"), request("b"), request("c")]);
console.log(res); // 預(yù)期輸出 start 一秒后輸出 ['a', 'b', 'c']
}
main();
export default {};
11,假設(shè)加法是一個(gè)異步過程,如何計(jì)算多個(gè)數(shù)組之和?
/**
* @file 假設(shè)加法是一個(gè)異步過程,如何計(jì)算多個(gè)數(shù)組之和?
*/
function sleep(ms: number) {
return new Promise((r) => {
setTimeout(() => {
r(undefined);
}, ms);
});
}
async function asyncAdd(a: number, b: number) {
await sleep(1000);
return a + b;
}
async function sum(arr: number[]): Promise<number> {
// 參考答案
var s: number = arr[0];
for (var i = 1; i < arr.length; i++) {
s = await asyncAdd(s, arr[i]);
}
return s;
}
console.time("a");
sum([1, 2, 3, 4, 5, 6, 7, 8]).then((v) => {
console.log(v); // 36
console.timeEnd("a"); // a: <耗時(shí)>
});
export default {};
12,typescript的主要特點(diǎn)是什么?
- 跨平臺:ts編譯器可以安裝在任何平臺上
- es6特性:包含es6的大部分特性,如箭頭函數(shù)
- 是一種面向?qū)ο蟮恼Z言:如類,接口,模塊
- 可選的靜態(tài)類型
- DOM操作
13,使用ts有什么好處
- 代碼閱讀性更好
- 調(diào)試簡單:高級調(diào)試器專注于在編譯之前捕獲邏輯錯(cuò)誤。
- 跨平臺
14,ts的基本類型
- Number:let num1:number = 1;
- string:let str = “字符串”
- 布爾型:true||false
- null型:表示未定義的值
- any:任意類型
- unknown:類型安全的any
- [] || Array :數(shù)組類型
- 元組:元組類型用來表示已知元素?cái)?shù)量和類型的數(shù)組。各個(gè)元素類型可以不同,但是位置必須相同
- enum:枚舉類型用于定義數(shù)值集合 enum Color {“red”,“green”,“Blue"}
- void:用于表示方法的返回值類型,
- undefined:表示值未定義
- never:表示從不會出現(xiàn)的值
15,什么是any類型?在什么時(shí)候使用?
- any表示任何值,只要沾上了any就代表ts將不會對這個(gè)值進(jìn)行類型檢查。
- 當(dāng)一個(gè)變量需要賦值的數(shù)據(jù)類型不確定時(shí),可以使用any類型,他可以賦值任何類型
16,什么是void?適用于什么場景
- 以函數(shù)舉例,當(dāng)函數(shù)沒有返回值的時(shí)候,可以適用void。注意不能將null 返回給void
17,在ts中,聲明變量用哪些關(guān)鍵字
- type:只能聲明一次
- interface:可以聲明多次
- enum:聲明一個(gè)枚舉變量
- let const var
18,如何在ts中創(chuàng)建一個(gè)對象?
let obj:{x:number,y:string}={
x:1,
y:"字符串"
}
19,如何在ts中指定可選屬性?
使用變量名+?:類型即可
20,說說枚舉
enum枚舉用來定義一組常量
21,說說ts中for循環(huán)的幾種變體
- for(let i = 0;i<length;i++)
- array.forEach()
- for…of
22,接口(interface)和類型別名(type)的區(qū)別
-
接口基本使用
- 接口可以重名,可以合并,
- 用接口約束的對象 或者 類 要和接口里的一樣,不能多 不能少。
interface yourType{ name:string, age:number } iterface yourType{ height:number } let you:yourType = { name:"***", age:12, height:175 }
-
類型別名基本使用
- 描述一個(gè)對象的類型
- 特點(diǎn)是:名稱唯一 ,不能重復(fù),實(shí)例化出來的對象屬性不能多不能少。
-
區(qū)別:
- 接口名稱可以重復(fù),而type不可以
- 接口可以重復(fù)定義
- type可以使用in關(guān)鍵字生成映射類型,而接口不行
-
使用建議:優(yōu)先使用interface,公用的使用interface,其次再用type
23,談?wù)劮盒秃蚢ny的區(qū)別
- 相同點(diǎn):都是用來定義一個(gè)未知類型的變量
- 不同點(diǎn):
- any:ts將跳過對此變量的類型檢查
- 泛型:不預(yù)先指定具體的類型,而是在使用的時(shí)候再使用來指定指定具體類型。
24,泛型的使用
-
在函數(shù)中使用
function echo<T>(arg:T){ return arg; }
-
在類中使用
class Animal<T>{ name:T; constructor(name:T){ this.name = name; } action<T>(say:T){ console.log(say); } }
-
在接口中使用
interface Animall<T,U>{ key:T, value:U }
25,ts中的類型斷言是什么?
- 語法:
值 as 類型
他的意思是說,我認(rèn)為這個(gè)值是某個(gè)類型,編譯器 請?zhí)^檢查。 - 特點(diǎn):聯(lián)合類型可以斷言為其中一個(gè)類型,父類可以斷言為子類,任何類型都可以斷言成any。
- 注意:類型斷言只會影響ts編譯時(shí)的類型,編譯結(jié)果出來后,類型斷言會被刪除。
26,如何使用ts將字符串轉(zhuǎn)換為數(shù)字,
- 使用parseInt
- 使用parseFloat
- 使用+ 號
+3
27,ts中的類是什么?
- 類表示一組相關(guān)對象的共享行為和屬性
28,如何在node環(huán)境運(yùn)行ts文件
安裝ts-node, 然后使用命令ts-node fileName
29,解釋rest參數(shù)和聲明rest參數(shù)的規(guī)則
- 含義:其余參數(shù)允許你將不同數(shù)量的參數(shù)(零個(gè)或多個(gè))傳遞給函數(shù)。
- 語法:
function (arg1:string, ...names:string[]){}
,表示剩余參數(shù)存在了names數(shù)組里 - 注意:rest參數(shù)必須是參數(shù)定義的最后一個(gè),并且每個(gè)函數(shù)只能擁有一個(gè)rest參數(shù)
30,omit是什么?
- Omit允許你通過傳遞Type并選擇Keys在新類型中省略來構(gòu)造類型。Omit會構(gòu)造一個(gè)除類型K外具有T性質(zhì)的類型
- 語法:Omit<type,string>; 參數(shù):第一個(gè)為繼承的type類型,第二個(gè)為想要的key的字符串,多個(gè)字符串用|分開
- 簡而言之,就是繼承一個(gè)接口,然后過濾掉不想要的接口屬性
31,如何實(shí)現(xiàn)函數(shù)重載
函數(shù)名相同,但參數(shù)類型或返回值不同的函數(shù)就是重載。兩個(gè)函數(shù)必須接收相同數(shù)量的參數(shù)
32,如何讓接口的所有屬性都可選?
使用映射類型
-
語法:{ readonly [p in K] ?: T} //in 表示遍歷,T表示ts中的任意類型
-
常見的類型語法:
1,{ [P in K] : T } // 默認(rèn)不可選 2, { [P in K] ?: T} //全都是可選的 3,{ [P in K ] -?: T} // -號表示移除可選 ,這句的意思是把P都移除可選修飾符 4,{ readonly [P in K] : T} //全是只讀的 5,{ readonly [P in K] ?: T} //添加只讀修飾符 6,{ -readonly [P in K] ?: T} //移除只讀修飾符
-
這題的答案應(yīng)該是用{ [P in K ] ?: T}
33,ts中的模塊指的是什么?
- 指的是相關(guān)變量,函數(shù),類和接口的集合。
- 模塊之間是用import引入,export來導(dǎo)出的。
CSS部分
1,什么叫做偽類,偽元素?都包括什么?
- 偽類(使用單冒號
:
):用來定義元素特殊狀態(tài)的。如鼠標(biāo)懸停,焦點(diǎn)樣式,鏈接樣式。舉例:hover,active,link。 - 偽元素(使用雙冒號
::
):新建的一個(gè)虛擬元素,他不存在于文檔中。判斷是否是偽元素就看他是不是新建的元素
2,回流,重繪
-
回流:元素的大小或者位置發(fā)生了改變,觸發(fā)了 頁面重新布局而導(dǎo)致渲染樹重新計(jì)算布局或者渲染
- 改變窗口大小,
- 改變文字大小,
- 添加/刪除樣式表
- 用戶輸入
- 激活偽類等等
-
重繪:元素樣式的改變(但寬高,大小,位置不變),只改變自身元素,不改變其他元素。包括:
- outline(設(shè)置元素輪廓),visibility(元素是否可見),color(顏色),background-color(背景色)
3,Animation和Transition 的區(qū)別是什么?
都是實(shí)現(xiàn)動畫效果的,區(qū)別是,Animation可以定義動畫關(guān)鍵幀,因此可以實(shí)現(xiàn)更復(fù)雜的動畫效果。
4,媒體查詢的使用方法:
- 語法:
@media 媒體類型 and (媒體特性){樣式規(guī)則}
- 書寫順序:當(dāng)使用
@media screen (min-width:xxxpx)
時(shí),小分辨率要放在大分辨率上面,如先寫768px,再寫992,再寫1440,如果是用max-width時(shí),要先寫大的,再寫小的
5,響應(yīng)式布局有哪些?簡述一下這些響應(yīng)式布局
- 百分比布局:缺點(diǎn)是需要按照設(shè)計(jì)稿,換成成百分比單位
- 媒體查詢布局(@media):缺點(diǎn)是css代碼量會增加很多,常用斷點(diǎn)尺寸:576(small),>=576(sm) ,=>769(md),=>992(lg),=>1200(xl),=>1400(xxl)。實(shí)際開發(fā)中,使用柵格布局+斷點(diǎn)設(shè)定實(shí)現(xiàn)響應(yīng)式
- rem布局:
- rem是相對于html根元素的字體大小的單位
- 通過修改html中根元素字體大小,來控制rem的大小
- flexible.js插件可以實(shí)現(xiàn)。
- vw,vh響應(yīng)式布局
- flex布局(不會脫離文檔流),常用屬性:
- felx-direction(主軸方向):row/row-reverse/column/column-reverse
- flex-wrap(是否換行):nowrap/wrap/wrap-reverse
- flex-flow(direction,wrap的簡寫):第一個(gè)參數(shù)是direction,第二個(gè)是wrap
- justify-content(主軸上對齊方式):flex-start/flex-end/center/space-between/space-around
- align-item(側(cè)軸對齊):flex-start/flex-end/center/baseline(基線對齊)/stretch(拉伸)
- align-content(多軸對齊):flex-start/flex-end/center/space-between/space-around/stretch
- 項(xiàng)目屬性(flex容器的子元素)
- order:子元素排序,數(shù)值越大越靠后
- flex-grow:子元素占領(lǐng)空間百分比,自動增長并填滿空間
- flex-shrink:當(dāng)父元素空間不夠時(shí)進(jìn)行縮小,數(shù)值越大,縮小的越多,0為不收縮
- flex-basis:子元素初始占據(jù)空間大小。
- flex(flex-grow,flex-shrink,flex-basis的簡寫):默認(rèn)值0,1,auto
- align-self(單個(gè)子元素在側(cè)軸上的對齊方式):auto/flex-start/flex-end/cener/baseline/stretch
6,canvas 常用api以及介紹
-
簡介:canvas標(biāo)簽是一個(gè)圖形容器,可以用js腳本來繪制圖形。主要應(yīng)用在動畫,游戲畫面,數(shù)據(jù)可視化,圖片編輯,以及實(shí)時(shí)視頻處理方面。
-
元素屬性
屬性名 含義 值 height canvas元素的高度 number width canvas元素的寬度 number getContext(“2d”) 獲取canvas上下文 2d toDataURL(type, encoderOptions) 返回一個(gè)數(shù)據(jù)URL,該URL包含由類型參數(shù)指定的格式的圖像(默認(rèn)為png) encoderOptions在指定圖片格式為 image/jpeg 或 image/webp的情況下,可以從 0 到 1 的區(qū)間內(nèi)選擇圖片的質(zhì)量 toBlob(callback, type, encoderOptions) 回調(diào)函數(shù),可獲得一個(gè)單獨(dú)的Blob對象參數(shù) 其余兩個(gè)參數(shù)含義同上 -
線條相關(guān)(設(shè)定線條樣式,偏移量,實(shí)線虛線的):
屬性 描述 值 lineWidth 線的寬度 number lineCap 線末端的類型 butt,round,square lineJoin 兩線相交拐點(diǎn)類型 miter,round,bevel miterLimit 斜切面限制比例 10 setLineDash([]) 設(shè)置當(dāng)前的線段樣式 數(shù)組里的值依次對應(yīng)虛線的線段和空白的長度,依次重復(fù) lineDashOffset(offset) 從哪里開始繪制線 -
繪制矩形
屬性 描述 值 clearRect(x,y,width,height) 清除指定區(qū)域矩形 fillRect(x,y,width,height) 填充指定區(qū)域矩形 strokeRect(x, y, width, height) 使用當(dāng)前的繪畫樣式(包括顏色等),描繪一個(gè)矩形 -
路徑
屬性 描述 值 beginPath() 開始一條路徑,或重置當(dāng)前的路徑。 closePath() 使筆點(diǎn)返回到當(dāng)前自路徑的起始點(diǎn) moveTo(x, y) 將一個(gè)新的子路徑的起始點(diǎn)移動到指定坐標(biāo) lineTo(x, y) 鏈接到指定坐標(biāo),可以理解為畫到哪里 arc(x, y, r, startAngle, endAngle, 是否逆時(shí)針) 繪制一段圓弧 arcTo(x1, y1, x2, y2, r) 繪制兩個(gè)點(diǎn)之間半徑為r的圓弧 rect(x, y, width, height) 繪制一個(gè)矩形,可以通過fill或者stroke來填充或描邊 bezierCurveTo() 貝塞爾曲線 -
繪制路徑
屬性 描述 值 fill() 填充路徑 stroke() 描邊路徑 clip() 將當(dāng)前創(chuàng)建的路徑設(shè)置為當(dāng)前剪切路徑的方法 -
填充和描邊
屬性名 作用 默認(rèn)值 fillStyle 設(shè)置或返回用于填充繪畫的顏色、漸變或模式。 strokeStyle 屬性設(shè)置或返回用于筆觸的顏色、漸變或模式。 -
漸變:返回的CanvasGradient對象的addColorStop(offset, color)添加漸變顏色
屬性名 作用 默認(rèn)值 createLinearGradient(x0, y0, x1, y1) 創(chuàng)建一個(gè)沿參數(shù)坐標(biāo)指定的直線的漸變。該方法返回一個(gè)線性 對象 返回值可以作為描邊或者填充的值使用 createRadialGradient(x0, y0, r0, x1, y1, r1) 確定兩個(gè)圓的坐標(biāo),放射性漸變 -
圖案:返回CanvasPattern對象,可以把此模式賦值給當(dāng)前的fillStyle等,在 canvas 上繪制出效果
屬性名 作用 默認(rèn)值 createPattern(image, repetition) 用指定的圖片創(chuàng)建圖案 image可以是圖片,視頻,canvas的Element,或者canvas上下文,ImageData,Blob, ImageBitmap; repetition是重復(fù)方式,跟css里的背景圖片重復(fù)參數(shù)一樣 -
繪制文本
屬性名 作用 默認(rèn)值 fillText(text, x, y,[maxWidth]) 在指定位置填充繪制文本,最大寬度可選 strokeText(text, x, y,[maxWidth]) 在指定位置描邊繪制文本,最大寬度可選 measureText(text) 返回TextMetrics 對象 -
文本樣式
屬性名 作用 默認(rèn)值 font 設(shè)置字體 格式跟css的font一樣 關(guān)于字體的樣式都是在這里一起設(shè)置的 textAlign 文本對齊方式 start, end , left, right, center textBaseline 基線對齊方式 top, hanging, middle, alphabetic (默認(rèn)),ideographic, bottom. direction 文本方向 ltr, rtl, inherit (默認(rèn)) -
陰影
屬性名 作用 默認(rèn)值 shadowColor 陰影顏色 shadowBlur 陰影模糊程度 shadowOffsetX 陰影水平偏移量 shadowOffsetY 陰影垂直方向偏移量 -
變換
屬性名 作用 默認(rèn)值 rotate(deg) 坐標(biāo)系順勢轉(zhuǎn)旋轉(zhuǎn)指定角度 scale(x, y) canvas每個(gè)單位添加縮放變換 translate(x, y) 對當(dāng)前坐標(biāo)系平移 transform() setTransform() resetTransform() -
合成
屬性名 作用 默認(rèn)值 globalAlpha 合成到canvas之前,設(shè)置圖形和圖像的透明度 globalCompositeOperation 設(shè)置如何在已經(jīng)存在的位圖上繪制圖形和圖像 詳細(xì)用法 -
繪制圖像
屬性名 作用 默認(rèn)值 drawImage() 繪制圖像 ctx.drawImage(image, dx, dy); 或者ctx.drawImage(image, dx, dy, dWidth, dHeight); 或者 ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
-
像素控制文章來源:http://www.zghlxwxcb.cn/news/detail-506098.html
屬性名 作用 默認(rèn)值 createImageData(width, height 或者 imagedata) 創(chuàng)建一個(gè)新的、空白的、指定大小的imageData對象 從現(xiàn)有的 ImageData 對象中,復(fù)制一個(gè)和其寬度和高度相同的對象。圖像自身不允許被復(fù)制。 getImageData(sx, sy, sw, sh) 用來描述canvas區(qū)域隱含的像素?cái)?shù)據(jù),這個(gè)區(qū)域通過矩形表示,起始點(diǎn)為(sx, sy)、寬為sw、高為sh putImageData() ctx.putImageData(imagedata, dx, dy);或 ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight); -
canvas狀態(tài)文章來源地址http://www.zghlxwxcb.cn/news/detail-506098.html
屬性名 作用 默認(rèn)值 save() 使用棧保存當(dāng)前的繪畫樣式狀態(tài),你可以使用 restore() 恢復(fù)任何改變 restore() 恢復(fù)到最近的繪制樣式狀態(tài),此狀態(tài)是通過 save() 保存到”狀態(tài)?!爸凶钚碌脑?/td> canvas
到了這里,關(guān)于持續(xù)不斷更新中... 自己整理的一些前端知識點(diǎn)以及前端面試題,包括vue2,vue3,js,ts,css,微信小程序等的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!