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