請永遠牢記vue是單向數據流javascript
自定義組件:css
建立子組件的文件,創建組件的模板,把架子搭起來,也就是在子組件中寫好<template>視圖層,<script>邏輯層<style>css樣式層。而後定義好props裏面的數據,實現子組件須要的邏輯代碼後,也就封裝好了,而後直接調用便可。調用的花import引入,同時在父組件<script>(邏輯層)中的components這個對象中寫入組件名稱,最後掛載到父組件的template中便可。html
組件通訊:前端
①props / $emitvue
父組件經過props的方式向子組件傳遞數據,而經過$emit子組件能夠向父組件通訊。java
②$children / $parentnode
this.$children[0].msg = "hello world" //父組件修改子組件data中的數據
this.$parent.mag //子組件拿到父組件data中的數據
$children的值是數組,$parent的值是個對象複製代碼
注意:$parent,$children它們的目的是做爲訪問數組的應急方法,更推薦用props和events實現父子組件通訊。react
③provide / injectwebpack
這是vue2.2.0新增的api,簡單來講就是父組件中經過provide來提供變量,而後再子組件中經過inject來注入變量。ios
//父組件
export default{
name:"A",
provide:{
for:"demo"
},
components:{
comB
}
}
//子組件
export default{
name:"B",
inject:["for"],
data(){
demo:this.for
}
}複製代碼
④ref / refs
ref:若是在普通的DOM元素上使用,引用指向的就是DOM元素;若是用在子組件上,引用就指向組件實例,可經過實例直接調用組件的方法或訪問數據。
//父組件
<template>
<component-a ref="comA"></component-a>
</template>
<script>
export default{
mounted(){
const comA = this.$refs.comA;
console.log(comA.name)//Vue.js
comA.sayHello() //hello
}
}
</script>複製代碼
//子組件
export default{
data(){
return {
name:"Vue.js"
}
},
methods:{
sayHello(){
console.log("hello")
}
}
}複製代碼
⑤eventBus(Bus總線):
//首先在src中建立一個Bus文件夾 => index.js
import Vue from "vue";
export default new Vue({
})
//子組件1(發送數據的組件)
<button @click="add()">點擊</button>
import Bus from "@/Bus"
add(){
Bus.$emit("add",this.content);
}
//子組件2(接受數據的組件)
<p>{{tit}}</p>
import Bus from "@/Bus";
created(){
Bus.$on("add",(data) => {
this.tit = data;
})
}複製代碼
⑥Vuex;
⑦LocalStorage;
⑧$attrs / $listeners
將數據掛在到子組件的標籤上去後,在子組件中使用this.$attrs直接獲取到全部掛載的數據,返回的是一個對象。
使用nextTick的緣由:Vue是異步修改DOM的,而且不鼓勵開發者直接接觸DOM,可是有時候須要必須對數據更改後的DOM元素作相應的處理,可是獲取到的DOM數據並非更改後的數據,這時候就須要this.$nextTick();
原理:Vue經過異步隊列控制DOM更新和nextTick回調函數前後執行的方式。
使用:
//HTML
<button @click="change()">按鈕</button><h1 ref="gss">{{msg}}</h1>
//JS
export default{
name:"app",
data(){
return {
msg:"123"
}
},
methods:{
change(){
this.msg = "456";
console.log(this.refs["gss"].innerHTML)//123
this.$nextTick(function(){
console.log(this.refs["gss"].innerHTML)//456
})
}
}
}
複製代碼
補充:
patch方法patch(container, vnode)patch(vnode, newVnode)複製代碼
replacechildrencreateElement複製代碼
數據劫持:當咱們訪問或設置對象的屬性的時候,都會觸發相對應的函數,而後在這個函數裏返回或設置屬性的值。咱們能夠在觸發函數的時候動一些手腳作點咱們本身想作的事情,這也就是「劫持」操做。
Vue3.0摒棄了Object.defineProperty,改成基於Proxy的觀察者機制探索。
首先說一下Object.defineProperty的缺點:
而要取代它的Proxy有如下兩個優勢:
補充:
virtual-dom(簡稱vdom)的概念大規模的推廣仍是得益於react的出現,virtual-dom也是react這個框架的很是重要的特性之一。相比於頻繁的手動去操做dom而帶來性能問題,vdom很好的將dom作了一層映射關係,進而將在咱們本須要直接進行dom的一系列操做,映射到了操做vdom,而vdom上定義了關於真實dom進行的建立節點,刪除節點,添加節點等一系列複雜的dom操做,並將這些操做放到vdom中進行,這樣就經過操做vdom來提升直接操做的dom的效率和性能。
在vue的整個應用生命週期當中,每次須要更新視圖的時候便會使用vdom,vdom算法是基於snabbdom算法所作的修改。
實現:
①用js對象構造一個虛擬的dom樹,插入到文檔中;❄ 單頁面路由跳轉的方式:
①hash(哈希默認)模式:使用 URL hash 值來做路由。默認模式。
②history(mode:history)模式: 依賴 HTML5 History API 和服務器配置。查看 HTML5 History 模式。
③abstract模式(嚴格模式):支持全部 JavaScript 運行環境,如 Node.js 服務器端。
根據mode參數來決定採用哪種方式。
vue-router的實現原理(核心):更新視圖但不從新請求頁面。
❄ vue-router登錄權限的判斷
vue-router的登錄權限判斷主要是在全局鉤子函數中進行的,咱們在router.js文件中的定義路由裏,將須要登錄權限的頁面加上meta屬性,值是對象的形式,而後在該對象中自定義一個屬性,屬性值就是一個Boolean值,這時候在main.js文件的全局鉤子函數中進行判斷,若是須要跳轉的頁面的自定義屬性值爲true,那麼將進行判斷其是否登陸,若是沒有登陸,則告訴用戶登陸,若是有登陸,那麼進行頁面跳轉。
routes:[
{
path:"/home",
name:"Home",
components:Home
meta:{requireAuth:true}
}
]複製代碼
router.beforeEach((to,from,next) => {
if(to.meta.requireAuth){//判斷該路由是否須要登陸權限
if(store.state.token){//經過vuex的state獲取當前的token是否存在
next()
}else{
next({
path:"/one",
query:{redirect:to.fullPath}//將跳轉的路由path做爲參數,登錄成功後跳轉到該路由
})
}
}else{
next();
}
})複製代碼
❄ 路由嵌套
routes:[
{
path:"/home",
name:"Home",
components:Home,
children:[
{
path:"child",
name:"Child",
components:"Child"
}
]
}
]複製代碼
定義:Vuex是一個專爲Vue.js應用程序開發的狀態管理模式。它採用集中式儲存管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
使用場景:須要構建一箇中大型單頁應用,您極可能會考慮如何更好的在組件外部管理狀態,Vuex將會成爲天然而然的選擇。
Vuex的運行機制:Vuex提供數據(state)來驅動試圖(vue components),經過dispath派發actions,在其中能夠作一些異步的操做,而後經過commit來提交mutations,最後mutations來更改state。
核心:
①state:定義初始數據。Vuex的映射:
computed:{
...mapState([
"list",
])
}
methods:{
...mapMutations([
"changes",
])
}複製代碼
當一個Vue實例建立時,vue會遍歷data選項的屬性,用 Object.defineProperty 將它們轉爲 getter/setter而且在內部追蹤相關依賴,在屬性被訪問和修改時通知變化。 每一個組件實例都有相應的 watcher 程序實例,它會在組件渲染的過程當中把屬性記錄爲依賴,以後當依賴項的 setter 被調用時,會通知 watcher 從新計算,從而導致它關聯的組件得以更新。
原理:vue異步組件技術:異步加載,vue-router配置路由 , 使用vue的異步組件技術 , 實現按需加載。
component:(resolve) => {
require(["@/components/HelloWorld"],resolve);
}複製代碼
const info = () => import("@/components/info");複製代碼
const info = (resolve) => {
import("@/components/info").then(modul => {
resolve(modul);
})
}複製代碼
const info = r => require.ensure([],() => r(
require("@/components/info")
),"info");複製代碼
Vue.js是一個輕巧、高性能、可組件化的MVVM庫,同時擁有很是容易上手的API;Vue.js是一套構建用戶界面的 漸進式框架。與其餘重量級框架不一樣的是,Vue 採用自底向上增量開發的設計。Vue的核心庫只關注視圖層,而且很是容易學習,很是容易與其它庫或已有項目整合。數據驅動+組件化的前端開發。經過儘量簡單的 API實現響應的數據綁定和組合的視圖組件。核心是一個響應的數據綁定系統。
補充:
當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用「就地複用」策略。若是數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單複用此處每一個元素,而且確保它在特定索引下顯示已被渲染過的每一個元素。key 的做用主要是爲了高效的更新虛擬DOM。
使用Object.assign(),vm.$data能夠獲取當前狀態下的data,vm.$options.data能夠獲取到組件初始化狀態下的data。
Object.assign(this.$data, this.$options.data())複製代碼
route
是「路由信息對象」,包括path
,params
,hash
,query
,fullPath
,matched
,name
等路由信息參數。
router
是「路由實例對象」,包括了路由的跳轉方法(push
、go
),鉤子函數等。
①把不常改變的庫放到index.html中,經過cdn引入
而後找到 build/webpack.base.conf.js 文件,在 module.exports = { } 中添加如下代碼:
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
},複製代碼
②vue路由懶加載
③不生成map文件,找到config/index.js文件,修改成productionSourcceMap:false
④vue組件儘可能不要全局引入
⑤使用更輕量級的工具庫
⑥開啓gzip壓縮:這個優化是兩方面的,前端將文件打包成.gz文件,而後經過nginx的配置,讓瀏覽器直接解析.gz文件。
⑦首頁單獨作服務端渲染:若是首頁真的有瓶頸,能夠考慮用 node 單獨作服務端渲染,而下面的子頁面仍用 spa 單頁的方式交互。這裏不推薦直接用 nuxt.js 服務端渲染方案,由於這樣一來增長了學習成本,二來服務端的維護成本也會上升,有時在本機測試沒問題,在服務端跑就有問題,爲了省心,仍是最大限度的使用靜態頁面較好。
大體有三個點,第一個是關於提出的新API setup()
函數,第二個說了對於Typescript的支持,最後說了關於替換Object.defineProperty
爲 Proxy 的支持。詳細說了下關於Proxy代替帶來的性能上的提高,由於傳統的原型鏈攔截的方法,沒法檢測對象及數組的一些更新操做,但使用Proxy又帶來了瀏覽器兼容問題。
vue-cli是基於 Vue.js 進行快速開發的完整系統,也能夠理解成是不少 npm 包的集合。
vue-cli完成的功能:
若是開發者須要補充或修改默認設置,須要在 package.json 同級下新建一個 vue.config.js 文件
⑴v-bind:給元素綁定屬性
⑵v-on:給元素綁定事件
⑶v-html:給元素綁定數據,且該指令能夠解析html標籤
⑷v-text:給元素綁定數據,不解析標籤
⑸v-model:數據雙向綁定
⑹v-for:遍歷數組
⑺v-if:條件渲染指令,動態在DOM內添加或刪除DOM元素
⑻v-else:條件渲染指令,必須跟v-if成對使用
⑼v-else-if:判斷多層條件,必須跟v-if成對使用
⑽v-cloak:解決插值閃爍問題
⑾v-once:只渲染元素或組件一次
⑿v-pre:跳過這個元素以及子元素的編譯過程,以此來加快整個項目的編譯速度
⒀v-show:條件渲染指令,將不符合條件的數據隱藏(display:none)
v-for比v-if優先,若是每一次都須要遍歷整個數組,將會影響速度,尤爲是當之須要渲染很小一部分的時候。
//響應攔截
axios.interceptors.response.use(function(response){
//對響應數據作點什麼
return response.data
},function(error){
//對錯誤響應作點什麼
return Promise.reject(error)
})複製代碼
//請求攔截
axios.interceptors.request.use(function(config){
//在發送請求以前作些什麼
return config
},function(error){
//對請求錯誤作些什麼
return Promise.reject(error)
})複製代碼
使用babel-polyfill插件