vue知識點概括與總結(筆記)

前言

    當前總結是本人在業餘學習與實踐過程後的總結與概括,旨在檢驗本身的積累,也方便忘記時查閱,同時也但願能幫助那些這方面知識匱乏的同行門,總結是基於vue2.x,vue-cli3.x,主要記錄些,vue經常使用的指令、事件,監聽、數據綁定、過濾器、組件、動畫、vuexvue-router等平常工做中時經常使用到的東西,也有些經常使用的插件開發工具的介紹與使用,以及部分性能優化的建議與實踐,若有不對,或不足的地方,也請各位大神,指出來,學習學習。javascript

1.基礎

1. 理解mvvm

  • mvue實例中的data,自定義的數據或後端返回的數組

不是後端mvc裏的model概念不一樣。php

  • vmvue的實例 mv之間的調度者 是mvvm的核心思想
  • vhtml 要渲染的。

2. 經常使用指令

  • v-cloak 解決{{}}插值閃爍問題
  • v-text 會先執行 覆蓋 元素中本來的內容 可是插值表達式只會覆蓋本身的佔位符,默認不會閃爍
  • v-html 渲染 html標籤 覆蓋元素中原有元素內容
  • v-bind: 簡寫爲: 用來綁定數據 能夠寫合法的js表達式
  • v-on: 簡寫爲 @ 用來點擊事件

3.經常使用事件修飾符

  • stop 阻止冒泡 :外層和裏層都有方法 點擊裏層會產生冒泡,也會觸發外層的事件。順序 從裏到外產生事件
  • prevent 阻止瀏覽器默認行爲 :a標籤有瀏覽器默認行爲。
  • capture 捕獲事件 :點擊裏層先觸發外層再觸發裏層 順序從外到裏產生事件
  • self 只觸發本身自己的事件 不會產生冒泡和捕獲事件 相似於阻止冒泡 但只針對本身那一層 最外層仍是會被最裏層冒泡冒到 stop 是阻止全部層次
  • once 事件只執行一次

4.數據的綁定

  • v-bind: 數據的單向綁定
  • v-modle :數據的雙向綁定 這個只能用於表單元素中
tips: 表單元素 radio text address email select checkbox textarea

5.class 綁定

  • 1.數組帶對象
<div :class="[classA,classB,{'classC':flag}]" >

data(){
    return{
        flag:true
    }
}
tips:能夠在類中的數組中寫三元表達式,但推薦使用對象來代替它控制是否渲染
  • 2.單純的對象
<div :class="{classA:falg1,classB:flag2}" />

data(){
    return{
        falg1:true,
        falg2:true
    }
}
  • 3.數組帶三元
<div :class="['ac','bd',falg?'active','']" / >

data(){
    return{
        falg:true,
    }
}
  • 4.對象升級
<div :class="classObj" />

data(){
    return{
      classObj:{classA:falg1,classB:flag2}
    }
}
tips:直接使用一個對象數組來控制樣式
  • 5.使用style 的對象來實現樣式的修改
<div :class="styleObj" />

    data(){
        return{
          styleObj:{color:red}
        }
    }
  • 6.使用style 的數組帶對象來實現樣式的修改
<div :class="[styleObj1,styleObj2]" />
 data(){
    return{
      styleObj1:{color:red},
      styleObj2:{color:red}
    }
}

6.v-for的使用

能夠遍歷: 普通數組,對象數組,對象,還能夠是數字css

<div v-for='(item,key,index) in object' :key='index'>
 {{item}}--{{key}}--{{index}} 
</div>
<div v-for='(count in 10)'> </div>
tips:在遍歷對象的時候有多個 index索引,遍歷數字時是從1開始的。綁定 key時屬性值必須是 number或者 string

7.v-ifv-show

  • v-if 有較高的切換性能 , 適合元素可能永遠不會被用戶看到。
  • v-show 有較高的初始渲染消耗,適合元素頻繁切換。

8 調試插件

  • 在谷歌商店找vue-devtools插件,使用這個插件

並設置插件,容許訪問文件網址。 會在調試中出現vue相關的東西html

  • debugger 直接寫能夠調試

9 過濾器

全局和私有過濾器
<div v-for='(item,key) in object' :key='index'>
 {{item | dateFormat}}
</div>

<div v-for='(count in 10)'> </div>
  • 全局
vue.filter('過濾器名稱',function(){
     
  })
  • 私有(局部)
filters:{
      dateFormat:function(data,param){
          do some
      }
 }

tips前端

  • data 就是 | 第一個參數已經被定死了,永遠是, 管道左邊要被轉換的數據,param 是過濾方法傳進來的其餘參數,過濾器採用就近優先原則,若是私有和全局的名稱同樣就優先採用私有的。
  • padstartpadend es6 的補0 方法
  • 第二個參數是字符串,第三個參數是表達式,若是本身定義參數值是動態的會報錯,還未找到緣由,後期會找時間再看看,目前就是簡單的過濾用過濾器,複雜點用方法,能用計算屬性用計算屬性,有緩存,能提升性能

10 按鍵修飾符

  • 監聽pc鍵盤上的值
<input @keyup.enter='方法名'></input>
tips: enter 能夠換成鍵盤上的任何一個值,只要去找相關的鍵盤碼,就均可以使用,推薦設置個別名,放在沒有按鈕操做的模板。
  • 自定義全局按鍵修飾符

Vue.config.keyCodes.f2=113,就可以使用了vue

tips: f2修飾符是 vue裏沒有定義的本身建立。

11 定義指令

1. 全局

定義的指令都要按規定去建立 在bind
inserted
還有 updated 中去建立java

Vue.directive('focus'{
  //每當指令綁定到元素上的時候,會當即執行bind 函數,只執行一次,
  注意:在元素剛綁定元素的時候,尚未插入到dom中去,這時候,調用focus方法沒有做用,即放在focus 放在bind中是不起做用 的
  bind:function(el,binding){
     el.style.color=binding.value
  },
  
  //表示元素插入到dom中的時候,只執行一次
  inserted:function(){
    el.focus() js行爲放在這裏去建立  
  },
  
  //當組件更新的時候,可能會觸發屢次
  updated:function(){},
 
})

tips:node

  • 參數1指令名稱,在定義的時候,指令名稱前面不須要加v-前綴,可是調用的時候,必須在指令名稱前加v-前綴;參數2:是一個對象,在這個對象身上,有一些指令相關的函數,這些函數能夠在特定的階段,執行

相關的操做。webpack

  • 在每一個函數中,的第一個參數,永遠是el, el是表明被bind綁定的元素,el是個原生的js對象。

第二個參數能夠是用戶傳進來值 bingding.valueios

2. 局部
directives:{
    '指令名':{
     bind:function( el,b){

     }
   }
 }
3. 簡寫
'指令名':function(el,binding){
    
} //注意這個function 等同於 把代碼寫到bind和update中去
tips: 樣式相關的指令放在 bind中, js行爲相關的放在 inserted中比較合適,防止指令不生效。使用場景 寫組件時能夠用這個去改樣式

12 生命週期

  • beforeCreate():這是咱們遇到的第一個生命週期函數,表示實例徹底被建立出來以前,會執行它...
  • created(): 這是遇到的第二個生命週期函數...
  • beforeMount():這是遇到的第3個生命週期函數,表示 模板已經在內存中編輯完成,可是還沒有把模板渲染(掛載)到頁面中。在 beforeMount 執行的時候,頁面中的元素,尚未被真正替換過來,只是以前寫的一些模板字符串。就像{{text}}這樣
  • mounted():這是遇到的第四個生命週期函數,表示內存中的模板,已經真實的掛載到了頁面中,用戶已經能夠看到渲染好的頁面了。只要執行完這個生命週期,就表示整個vue實例已經初始化完畢了,此時,組件已經脫離了建立階段,進入到了運行階段。
  • beforeUpdate():這時候表示,咱們的界面尚未被更新[但數據已經被更新了頁面中顯示的數據,仍是舊的,此時data數據是最新的。頁面還沒有和最新的數據保持同步
  • update() : 這一步執行的是 先根據data中最新的數據,在內存中從新渲染出一份最新的內存dom樹,當最新的內存dom樹被更新後,會把最新的內存DOM樹從新渲染到真實的頁面中去,這時候,就完成了數據data(model層)->view(視圖層)的更新,頁面和data數據已經保持同步了,都是最新的。
  • beforeDestory :當執行 beforeDestory 鉤子函數的時候,Vue實例就已經從運行階段,進入到銷燬階段, 當執行beforeDestroy的時候,實例身上全部的data和全部的methods以及過濾器、指令...都處於可用狀態,此時,尚未真正執行銷燬的過程。
  • destroyed :

當執行這個函數的時候,組件已經被徹底銷燬了,此時,組件中全部的數據,方法,指令,過濾器...都已經不可用了

13 過渡類名實現動畫

1. vue的內置動畫
<style>

 .v-enter,
 .v-leave-to{
     opacity:0;
     transform:translateX(150px) --這東西是位移
 }
 
 .v-enter-active,
 .v-leave-active{
 transition:all 0.4s ease;     
 }
 
 </style>
<transition name='my'>
 <h3 v-if="flag"></h3>
</transition>
<script>
 data(){
  return {
    flag:false
  } 
 }
</script>
2. 使用第三方類實現動畫
<transition enter-active-class="bounceIn"
leave-avtive-class="bounceOut"  duration='200' 

>
 <h3 v-if="flag" class="animated"  ></h3>
</transition>
3. 在屬性中聲明js鉤子 實現半場動畫(只須要進場,不須要離場)
<transition
  <div 
 
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  >
  
  </div>
  </transition>
<transition
  <div 
  v-show="flag"
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  >
  
  </div>
  </transition>
<script>
  methods:{
    beforeEnter(el){
    //動畫入場以前,此時動畫還沒有開始, 能夠在beforeEnter中設置元素開始動畫以前的初始位置    
    
   el.style.transform=
   "translate(0,0)"
    },
    enter(el,done){
     /*這句話,沒有實際的做用,可是,若是不寫,出不來動畫效果,能夠認爲 這個會強制刷新動畫,ofset觸發了重繪重排致使動畫更新了*/
     
     el.offsetWidth
     
     el.style.transform=
     "translate(150px,450px)"
     
     el.style.transition='all 1s ease'
    
     /*這裏的done 表明着 
     afterEnter的引用,
     這個會當即執行afterEnter 不然會有延時 
     */
     done()       
    },
    
    afterEnter(el){
    /*動畫完成以後,會調用afterEnter */
      this.flag=!this.flag
      
    }
  } 
</script>
4. 在實現列表過渡的時候,若是須要過渡的元素,是經過v-for循環渲染出來的,不能使用transition包裹,須要使用transitionGroup
<transition-group appear tag='ul'>
 <li v-for >
 
 <li>

</transition-group>
.v-enter,
 .v-leave-to{
     opacity: 0;
     transform:translateY(80x);
 }
 
 .v-enter-active,
 .v-leave-active {
     transition: all 0.6s ease;
 }
 
 /*離開後下一個東西沒有動畫使用這個可使用動畫實現下一個東西漸漸地飄上來的效果,要和 v-leave-active的absolute 配合 固定寫法*/
 .v-move {
  transition:all 0.6s ease
 }
 
 .v-leave-active{
   /* absolute 有個特色元素默認寬度就是最小值,要在元素上添加width:100%*/
    position:absolute;
 }
<transition mode="out-in">
    <component  :is="comName" >
    </component>
</transition>

tips:

  1. v-enter [這是一個時間點] 是進入以前,元素的起始狀態,此時尚未開始進入
  2. v-leave-to [這是一個時間點]是動畫離開以後,離開的終止狀態,此時,元素動畫已經結束了
  3. v-enter-active[入場動畫的時間段]
  4. v-leave-active[離場動畫的時間段]
  5. animated 是個動畫庫 新版本彷佛不須要加入
  6. 使用:duration=200 來表示動畫的時間 若是隻寫一個表示統一配置了開場和離場時間 用 對象可傳入c入場和離場 duration="{enter:200,leave:400}"
  7. 添加appear屬性,實現頁面剛展現出來,入場時候的效果
  8. 經過爲transition-group 元素,設置tag屬性指定 transition-group 渲染爲指定元素,若是不指定tag屬性,默認,渲染爲span 標籤
  9. mode="out-in" 先過渡再進來,防止有陰影,經過mode`來設置過渡方式。

注意:最外層必定要用transition包裹着,動畫彷佛升級了,能夠在transition標籤中加入name屬性,而且在css樣式中把v,替換爲你的name屬性值。

14 組件

1.使用Vue.extend 來建立全局的Vue組件

var coml=Vue.extend({
 template:'<h3>這是使用Vue.extend 建立的組件</h3>'
})
//第一個參數組件名稱,第二個參數建立出來的組件模板對象
 Vue.component('myComl',coml)
<my-coml><my-coml/>

2.使用 vue.component 來建立組件

Vue.component('mycom2',{
   
template:'<div>
 <h3>
    這是直接使用Vue.component 建立出來的組件
 </h3>
</div>'    
    
})

3.使用 template 來建立組件

<template id='tmp1'>
<div>
 <h1>
 這裏經過template元素,在外部定義的組件結構,這個方式,有代碼的智能提示和高量
 </h1> 
</div>
</template>


 Vue.component('mycom3',{
  template:'#tem1'   
 })

4.私有組件 componment

<template   id='temp2'>
 <h1>這是私有login組件</h1>
</template>

componment:{
 login:
  {
   template:'tmpl2'
  }
}
  • 若是使用了Vue.component 定義了全局組件的時候,組件名稱使用了駝峯命名,在引用的時候大寫的駝峯要改成小寫,同時兩個單詞之間 使用-連接
  • Vue.component第一個參數:組件的名稱,未來在引用組件的時候,就是一個標籤形式來引入的,第二個參數:

Vue.extend 建立的組件,其中 template就是組件未來要展現的內容

  • 注意:不管是哪一種方式建立出來的組件,組件的template 屬性指向的模板內容,必須有且只能有惟一的一個根元素。

15 組件裏的data

  1. 組件能夠有本身的data數據
  2. 組件的data和實例中的data有點不同,實例中的data 能夠爲一個對象,可是組件中的data必須是一個方法。
  3. 組件中的data 除了必須爲一個方法以外,這個方法內部,還必須返回一個對象才行。
  4. 組件中的data數據,使用方式,和實例中的data使用方式徹底同樣!
  5. 組件裏data爲何必須是個方法返回個對象呢? 由於要確保每一個實例裏的數據是惟一的,獨有的。若是data裏的數據是放在實例外部的,會被其餘實例共享。

16 組件切換

  1. 組件裏的切換 能夠用 v-ifv-else 進行切換即標籤頁切換
<a href=""
 @click.prevent="flag=true"
 >
 登陸
 </a>
<a href=""
   @click.prevent="flag=flase"
  >
 註冊
 </a>
<login v-if="flag">
</login>

<register v-else="flag">
</register>

2.vue 提供了 component,來展現對應名稱的組件

//component 是一個佔位符

:is屬性,能夠用來指定要展現的組件的名稱 寫死的時候這個組件名要是個字符串,動態綁定時key普通寫法就好,但value必須是字符串。

<component :is="'componentId'">
</component>

<component :is="oneName">
</component>

data(){
    return{
     oneName:"login",
    }
}

17 父子組件通信

1.父子組件傳值,經過v-bind:(:)來傳值,經過props來接收值

2.父組件用事件綁定機制傳遞方法給子組件—v-on 簡寫 @

//父組件中
  <component-name 
  :children='children'  //傳值
  @handle='show'  //綁定方法
  >
  </component-name>
  
  data(){
    
    return(){
        children:11
    }  
      
  }
  
  methods:{
      
    show(data){
          
      }
  }

3.emit 英文原意: 是觸發,調用,發射的意思。
@handle=show 父組件傳show方法給子組件。
子組件接收父組件的方法,並用$emit把子組件的值傳給父組件

//子組件中
   methods:{
    handle(){
        this.$emit('func',{
            age:1,
            name:'搞事'
        })
      }
  }

4.在父組件中接收子組件全部參數的同時,添加自定義參數

1.子組件傳出單個參數時:

// 子組件
this.$emit('test',this.param)
// 父組件
@test='test($event,userDefined)'

2.子組件傳出多個參數時:

// 子組件
this.$emit('test',this.param1,this.param2, this.param3)
// 父組件 arguments 是以數組的形式傳入
@test='test(arguments,userDefined)'
tips:子組件中的 data數據,並非經過 父組件傳遞過來的,而是子組件自身私有的,好比子組件經過 ajax,請求回來的數據,均可以放到 data身上, data 上的數據都是可讀可寫的;

18 使用 ref 獲取dom元素

<h3  id='myh3' ref='myh3'> </h3>
 methods:{
   getElement(){
     console.log( this.$refs.myh3.innerText)
  } 
 }
//組件也可使用ref,讓父組件調用子組件裏的方法和屬性值
<login ref='mylogin'> </login>

 methods:{
     getElement(){
     //父組件調用子組件裏的屬性值
     console.log(this.$refs.mylogin.msg)
     }    
}

tips:

  1. refs; s表明多個引用,會有多個dom元素。
  2. ref英文是reference,值類型和引用類型。

19 路由

1.這是vue-router提供的元素,專門用來 看成佔位符的,
未來,路由規則,匹配到的組件,就會展現到這個router-view中去,因此:咱們能夠把router-view認爲是一個佔位符

<router-view></router-view>

2.路由切換 模板寫法,默認渲染爲一個a標籤,
使用tagspan能夠用來轉換模板的標籤名

<router-link to="/login" tag='span' >
登陸
</router-link>

3.路由配置

new VueRouter({
//路由匹配規則
routes:[
   {
     path:'/',
     redirect:'/login'
    },
    
    {
     path:'login',
     component:login
    },
    
    {
     path:'/register',
     component:register
    }
]  

//路由高亮的類名
linkActiveClass:'myactive'
})


var vm=new Vue({
 el:'#app',
 data:{},
 methods:{},
 router //將路由規則對象註冊到vm實例上,用來監聽Url地址的變化,而後展現對應的組件。
})

4.路由傳參
1.query

//獲取id
this.$route.query.id

2.在path上設置參數

//參數要一一對應不可缺失,否則可能會
形成路由的不匹配
< router-link
  to="/login/12/ls"
>
{
    path:'/login/:id/:name',component:login   
}

3.params 新的方式可看文檔

5.子路由

<router-link
to="/account/login"
>
</router-link>
routes:[
{
  path:'/account',
  component:account,
  children:{
   {
   path:'login',
   component:login
   }   
  }
}

]

tips:

  • 每一個路由規則,都是一個對象,這個規則對象,身上,有兩個必須的屬性。
  • 屬性1 是path,表示監聽,哪一個路由連接地址;
  • 屬性2是component,表示,若是路由是前面匹配到的path,則展現component屬性對應的那個組件。
  • 子路由不能加/, 加了/ 會以根目錄爲基準匹配,這樣不方便咱們用戶去理解url地址
  • 超連接的to 必定要加上父路由

==注意==:componen屬性值,必須是一個組件的模板對象,不能是組件的引用名稱

20.命名視圖實現經典佈局

根據name 來找組件

<router-view></router-view>
<router-view name="left"></router-view>
<router-view name="main"></router-view>
var header={
    template:'<h1>header</h1>'
}

var leftBox={
    template:'<h1>leftBox</h1>'
}

var mainBox={
    template:'<h1>mainBox</h1>'
}
{
    path:'/',components:{
        'default':header,
        'left':leftBox,
        'main':mainBox
    }
}

21.watch

監聽非dom元素

watch:{
    'obj.a'(newValue,oldValue){  },
     immediate:false  
  }
watch:{
    'obj':{
              handler (newValue, oldValue) {
            }
      },
      deep:true   //深程度監聽 性能消耗大
  }
watch:{ 
    //監聽路由
    '$route.path':{
              handler (newValue, oldValue) {
            }
      },
      //immediate:true表明若是在 wacth 裏聲明瞭以後,就會當即先去執行裏面的handler方法,若是爲 false就跟咱們之前的效果同樣,不會在綁定的時候就執行
      immediate:true   
  }

tips:

  • 用了obj.a 加上handle +immediate:true ,就能夠監聽 對象裏的值,若是是obj 加上 handle+deep true 也是能夠監聽對象的屬性可是性能消耗大 通常是直接對象> > +屬性
  • handle 方法可讓watch初始化就執行,若是不用 handle它就先不執行,待數據改變再執行。
  • 不要在watchcomputer 中去修改參與計算或者監聽的值 而是要生成新的值。

22. computed 計算屬性

computed:{
 'fullname':(){
  return 
 }
}

23. render 函數註冊組件(vm[vue實例]的屬性)

render:function(createElements){
 //createElements是一個方法,調用它,可以把指定的 組件模板 渲染爲html結構
  return createElements(login)
  //注意 這裏 return 的結果,會替換頁面中el 指定的那個容器
 }
tips: rendercomponents區別 render 會把整個 app裏組件所有覆蓋掉一個 app中只能放一個 render組件 components 能夠多個,且不會覆蓋

24. slot 插槽

1.寫插槽

<div v-if="layout === 'block'" class="layout-block" :class="scroll?'layout-scroll':''">
      <slot></slot>  //匿名插槽
    </div>
    

   <!-- 左右塊 -->
    <div v-if="layout === 'both'" class="d-flex jc-between">
      <div class="layout-both" :class="scrollLeft?'layout-scroll':''">
        <slot name="left"></slot> //有名字的插槽
      </div>
      <div class="layout-both" :class="scrollRight?'layout-scroll':''">
        <slot name="right"></slot>
      </div>
    </div>

2.使用插槽

//有名字的插槽 # v-slot的縮寫是#
   <template #left></template>
   <template v-slot="left" > </template>
tips 區別對待v-slot="" 和v-slot:name; =和:的區別 一個是slot的name 一個是父組件獲取子組件的數據,插槽必定要用
template包裹着
<template>
 插槽的內容
</template>

2.雜項

1. nrm

安裝 nrm

  • npm i nrm -g 全局安裝
  • nrm ls 顯示列表
  • nrm use npm 使用npm use 後有不少地址可選擇
tips: nrm只是單純的提供幾個經常使用的下載包 url地址,並可以讓咱們在這幾個地址以前,很方便的進行切換,可是,咱們每次裝包的時候,使用的裝包工具,都是 npm。和
npm i cnpm -g  不同

2. webpack

在網頁中會引用哪些常見的靜態資源

  • js

    • .js .jsx .coffee .ts(TypeScript)
  • css

    • .css .less .sass .scss
  • Image

    • .jpg .png .gif .bmp .svg
  • 字體文件(Fonts)

    • .svg .ttf .eof .woff .woff2
  • 模板文件

    • .ejs .jade .vue

3. 熱部署

webpack-dev-server 實現自動打包功能,瀏覽器不用刷新也能看到文件已經修改,打包的文件並無放在實際的物理磁盤上,而是直接託管到了,電腦的內存中,因此,咱們在項目根目錄中,根本找不到這個打包好的文件,這文件和srcdistnode_modules 平級,有一個看不見的文件

4. 熱更新

hot 網頁不重載 直接更新 加快打包速度 不生成新文件

"scripts":{
   "dev":"webpack-dev-ser  ver --open --prot       3000 --contentBase src --hot "     
 }

配置文件中配置熱更新

devServer:{
     hot:true 就熱更新了
}
tips: webpage當中帶 s都是數組

5.webpack引入vue

webpack 中 使用如下方式導入的Vue
構造函數,功能並不完善,只提供了 runtime-only的方式,並無提供 像網頁中那樣的使用方式;

閹割版
import Vue from 'vue'

齊全版
 1.
 import Vue from '../node_modules/vue/dist/vue.js'
 2.
 module.exports={
  resolve:{
   //設置 Vue被導入的時候的包的路徑
      alias:{
        "vue$":"vue/dist/vue.js"  
      }
  }
 }

tips: 包的查找規則:

  • 找項目根目錄中有沒有node_modules的文件夾
  • node_modules 中 根據包名,找對應的vue文件夾
  • vue文件夾中,找一個叫作package.json 的包配置文件
  • package.json 文件中,查找一個main屬性[main屬性指定了這個包在被加載時候的入口文件]
  • 改了webpake的包就須要從新運行項目

6.在webpack中經過render展現組件

若是想要經過vue,把一個組件放到頁面中去展現,vm 實例中的render函數能夠實現

render:function(createElement){
     return  createElement(login) 
  }
  
  //就一行能夠省略{} 而且沒有花括號默認就有return, 
  簡寫: render: c => c(login)

tips: webpack中 如何使用Vue:

  1. 安裝Vue的包
  2. 因爲在webpack中,推薦使用.vue 這個組件模板文件定義組件,因此須要安裝 能解析這種文件的loader

    1. main.js中,導入vue 模塊
      import Vue from 'vue'
    2. 定義一個.vue 結尾的組件,其中,組件有三部分組成
    3. 使用 import login from './login.vue' 導入這個組件
    4. 建立 vm 的實例 var vm = new Vue ({el:'app',render:c=>c(login)})
    5. 在頁面中建立一個idappdiv元素,做爲咱們vm實例要控制的區域

7. export defaultexport

  • export default 向外暴露的成員,可使用任意的變量來接收
  • 在一個模塊中,export default只容許向外暴露1次
  • 在一個模塊中,能夠同時使用 export defaultexport 向外暴露成員
  • 使用 export 向外暴露的成員,只能使用{}的形式來接收,這種形式,叫作[按需導出]
  • export 能夠向外暴露多個成員,同時,若是某些成員,咱們在import的時候,不須要,則能夠不在 { }中定義
  • 注意使用 export 導出的成員,必須嚴格按照導出時候的名稱,來使用{ } 按需接收
  • 使用 export 導出的成員,若是就想換個名稱來接收,可使用 as 來起別名

    const arr={
         a:'1',
         b:'2'
     }
     export default arr
     
    /* export default {
       這個暴露是錯誤的因此當前註釋 一個js文件中只能暴露一次
        address:'北京'
     }
     */
    
     export title=1 
     import arr, {title as title1 } from  '/xxx.js'

8. router

  • render會把el指定的容器中,全部的內容都清空覆蓋,全部不要把路由的router-viewrouter-link 直接寫到el所控制的元素中
  • 注意 app這個組件,是經過vm 實例的render 函數,渲染出來的,render函數若是要渲染組件,渲染出來的組件,只能放到el: '#app'所指定的元素中;
  • AccountGoodsList 組件,是經過路由匹配監聽到的,因此,這兩個組件,只能展現到屬於路由的

    <router-view></router-view>中去
  • 子路由的應用場景在標籤頁切換

9. scoped原理

樣式的 scoped 是經過 css 的屬性選擇器來實現的 .aa[vsfp]{color:red}

tips:vsfp是哈希值

10. promise

  • 模擬 promise

    getFution(aa,callback){
      callback(aa)   
    }
    
     getFution(aa,funtion(res){
      console.log (aa)
     })
  • 異步操做

    /*
    每當new一個Promise實例的時候,就會當即執行這個異步操做中的代碼。也就是說,new的時候,除了可以獲得一個promise實例以外,還會當即調用 咱們爲 Promise 構造函數傳遞的那個funtion,執行這個function中的異步操做代碼。

*/
var promise=new Promise(function(resolve,reject){

異步操做,ajax函數等,並且能夠自由輸出東西了
 resolve(true) 
 reject(false)

})

getFunction(){

var promise=new  Promise(function(){
 異步操做,ajax函數等,並且能夠自由輸出東西了
 })

}

getFunction().then(
function(data){

console.log(err)

},function(err){

console.log(err)

})

正確使用方式

getFunction(aa)
.then(function(data){

console.log(data)
 return getFunction() --返回後,可使用後續的then

})

.then(function(data){

console.log(data)
   return getFunction()

})
.then(funtion(data){

console.log(data)

})
//捕獲只放在最後面。前面有任何的異常都會終止

.catch(function(data){
   console.log(data)    
}
> tips:在 `then`裏面多寫個返回錯誤的方法是不可取的。

 #### 11. vuex
 
 + `vuex`是爲了保存組件之間共享數據而誕生的,若是組件之間 有要共享的數據,能夠直接掛載到`vuex`中,而沒必要經過父子組件之間傳值了,若是組件的數據不須要共享,此時,這些不須要共享的私有數據,沒有必要放到`vuex`中;

+ `vuex`,存放共享數據,`data` 存放組件私有的數據 `props`存放父組件傳過來的數據

+ 操做`vuex`裏的`state`
- 直接操做`store`裏的屬性值,不推薦這種作法
this.$store.state.屬性值
 ```
    • 推薦只經過mutations 提供的方法,才能操做對應的數據,

      mutations:{
         increment(state,payload){
             state.count++ 
           }
          }
      this.$store.commit('方法名')
    • vuex裏的getters

      若是`store`中`state`上的數據,在對外提供的時候,須要作一層包裝,那麼推薦使用`getters`。
      
      ```
      optCount:state=>state.count
      this.$store.getters.***
      ```
      tips: increment方法裏的 state是屬於 vuex裏的 state; countstate裏的屬性 ; payload外部傳進來的值,用來修改 state裏屬性的值.。最多支持只能傳兩個參數,能夠是數組和對象。

      #### 12. ngrok
      能夠映射本地80端口,把本地的映射爲外網
      npm地址

      //npm下載 --感受下的有點慢 換個路徑下比較好
       npm install ngrok -g 
      //命令
       ngrok http 80
      tips: 須要開啓本地服務器,映射後只是映射www路徑,不是完整的程序路徑須要本身去補充完整

    13.public 目錄下的圖片如何用 require引入

    //第一種 圖片質量小的能夠自動轉換爲base64的
    img: require("@/../public/img/home/user.jpg ")
    
    //第二種 這裏能夠把最前面的 / 看作是public
    /img/abnormal/Trash.png 
    
    即 public/img/abnormal/Trash.png
    tips: @是指src目錄 .. @的上一級目錄,再進入public

    3.性能優化建議

    1.watch若是是obj 加上 handle+deep true 也是能夠監聽對象的屬性可是性能消耗大
    2.computer 裏生成的值 會有緩存 不建議用函數去處理一些值得計算 而是用 computer 來計算值,這樣性能高。
    3.:key ='id'
    id是列表返回的id 若是沒有id 就寫item 通常不建議 寫 index (eslint會有警告錯誤信息) 寫上key 是爲了減小消耗 它會有個緩存。

    4.v-oncev-model 的區別是 只會綁定一次 不會從新更新內容 能夠 減小開銷 應用場景:只讀場景,不進行修改頁面內容的時候

    5.v-forv-if 不適合在同個div連用

    • 可在最外層套用一層template來解決
    <template v-for="(column, index) in btn">
           <el-button size="small"
                           :type='column.type'
                           :plain='column.plain'
                           :class='!isEmpty(column.style)&&[scope.$index + (currentPage - 1) * pageSize==column.style.index?column.style.className:""] '
                           @click="handle(id&&!column.isGetAll?scope.row[id]:scope.row,column.lable,scope.$index + (currentPage - 1) * pageSize)"
                           :key='index'>
                  {{column.lable}}
                </el-button>
              </template>

    6.this.$parent 可修改父組件值,但不建議,只讀就好

    7.gzip 優化

    • vue配置 在前端生成帶有gz的文件
    • 輔助插件:compression-webpack-plugin
    const CompressionWebpackPlugin = require('compression-webpack-plugin')
    const productionGzipExtensions = ['js', 'css']
    const isProduction = process.env.NODE_ENV === 'production'
    
    configureWebpack: config => {
        if (isProduction) {
          config.plugins.push(
            new CompressionWebpackPlugin({
              algorithm: 'gzip',
              test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
              threshold: 10240,
              minRatio: 0.8
            })
          )
        }
      },

    ngnix服務端配置

    //配合前端的gzip
      在站點配置添加以下代碼:
    
        location ~* \.(css|js)$ {
           gzip_static on;
        }
     
        這是 nginx 的靜態 gzip功能,會自動查找對應擴展名的文件,若是存在 gzip 文件,就使用,若是沒有就用原文件
    
       //後端返回gzip
        gzip on;
        gzip_static  on;
        gzip_min_length  1k;
        gzip_buffers     4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 2;
        gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
        gzip_vary on;
        gzip_proxied   expired no-cache no-store private auth;
        gzip_disable   "MSIE [1-6]\.";

    8.cdn加速

    <script src="https://unpkg.com/vue@2.6.10/dist/vue.runtime.min.js"></script>
        <script src="https://unpkg.com/vuex@3.0.1/dist/vuex.min.js"></script>
        <script src="https://unpkg.com/vue-router@3.0.3/dist/vue-router.min.js"></script>
        <script src="https://unpkg.com/axios@0.19.0/dist/axios.min.js"></script>
        <script src="https://unpkg.com/element-ui@2.9.2/lib/index.js"></script>
    //有了config就按如下配置
      configureWebpack: config => {
        //cdn 
        config.externals = {
          vue: 'Vue',
          vuex: 'Vuex',
          'vue-router': 'VueRouter',
          axios: 'axios'
        }
        if (isProduction) {
          config.plugins.push(
            new CompressionWebpackPlugin({
              algorithm: 'gzip',
              test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
              threshold: 10240,
              minRatio: 0.8
            })
          )
        }
      }

    9.網頁中引入的靜態資源多了之後有什麼問題?

    • 網頁加載速度慢, 由於咱們要發起不少的二次請求;
    • 要處理錯綜複雜的依賴關係

      解決方案:
    1. 合併、壓縮、精靈圖、圖片的base64編碼 、cdn
    2. 可使用以前學過的requireJs、也可使用webpage

    10.創建不一樣的環境變量(開發、測試、正式)

    1、創建環境配置文件
    在package.json 同級的目錄下 創建3個文件
    1 .env.development  --開發環境 (本地環境)
    2 .env.production   --正式環境 (正式線服務器--打包)
    3 .env.test         --測試環境 (測試線服務器--打包)
    
    2、在每一個文件中寫入具體的配置內容
    
    /*****.env.development文件的內容*****/
      NODE_ENV = 'development'
      VUE_APP_CURRENT_MODE = 'development'
    
    /*****.env.production文件的內容*****/
      NODE_ENV = 'production'
      VUE_APP_CURRENT_MODE = 'production'
    
    /*****.env.test*****/
      NODE_ENV = 'production' 
      VUE_APP_CURRENT_MODE = 'test'
    
    3、在package.json 中寫入
    
     1.在純粹的vue_cli3.x配置以下
     
     "scripts": {
        "serve": "vue-cli-service serve --mode development",
        "build": "vue-cli-service build --mode production",
        "build:test": "vue-cli-service build --mode test",
      },
      
     2.在uni-app下的vue_cli3.x的配置
     
      "scripts": {
        "serve": "npm run dev:h5 -- development", //修改點
        "build": "npm run build:h5 -- production", //修改點
        "build:test": "npm run build:h5  -- test",  //修改點
        "build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5    vue-cli-service uni-build --mode", //修改點
        "build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
        "build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
        "build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
        "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
        "dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve --mode", //修改點
        "dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
        "dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
        "dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
        "dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
        "info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js"
      },
    tips:以上不一樣環境的切換,修改點主要就是mode -- '環境變量'

    4. 各類插件的介紹和引用

    1.postcss-plugin-px2rem
    配置文件名postcss.config.js vue-cli3.x腳手架自帶的pxrem等單位的配置,創建腳手架的時候選擇分離 否則配置在josn文件中很差配置

    module.exports = {
      plugins: [
        require('autoprefixer')(),
        require('postcss-plugin-px2rem')({
          rootValue: 192, //設計圖的寬度/10
          unitPrecision: 10, //換算的rem保留幾位小數點
          mediaQuery: true,
          minPixelValue: 3
          // exclude:/node_modules|folder_name/i,把第三方的框架排除掉
        })
      ]
    }

    2.babel-plugin-transform-remove-console
    刪除console,在根目錄中新建個.babelrc的文件,在如下文件中配置

    //第一種
    {
      "env": {
        "production": {
          "plugins": [
            ["transform-remove-console", { "exclude": ["error", "warn"] }]
          ]
        }
      }
    }
    
    //第二種
    
    1、創建環境配置文件
    在package.json 同級的目錄下 創建3個文件
    1 .env.development  --開發環境 (本地環境)
    2 .env.production   --正式環境 (正式線服務器--打包)
    3 .env.test         --測試環境 (測試線服務器--打包)
    
    2、在每一個文件中寫入具體的配置內容
    
    /*****.env.development文件的內容*****/
      NODE_ENV = 'development'
      VUE_APP_CURRENT_MODE = 'development'
    
    /*****.env.production文件的內容*****/
      NODE_ENV = 'production'
      VUE_APP_CURRENT_MODE = 'production'
    
    /*****.env.test*****/
      NODE_ENV = 'production' 
      VUE_APP_CURRENT_MODE = 'test'
    
    3、在package.json 中寫入
     
     "scripts": {
        "serve": "vue-cli-service serve --mode development",
        "build": "vue-cli-service build --mode production",
        "build:test": "vue-cli-service build --mode test",
      },
    
    
    4、在babel.config.js 中寫
     let transformRemoveConsolePlugin = [];
     if (process.env.VUE_APP_CURRENT_MODE === "production") {
      transformRemoveConsolePlugin = [
        ["transform-remove-console", { exclude: ["error", "warn"] }]
      ];
    }
    
    module.exports = {
      presets: ["@vue/app"],
      plugins: [...transformRemoveConsolePlugin]
    };

    3.html-webpack-plugin
    當使用 html-webpack-plugin 以後,咱們再也不須要手動處理bundle.js的引用路徑了,由於這個插件,已經幫咱們自動建立了一個合適的script,而且,引用了正確的路徑

    /*導入在內存中生成html頁面的插件,只要是插件,都必定要放到plugins節點中去
    */
    
     const htmlWebpackPlugin=require("html-webpack-plugin")
    
      //建立一個 內存中 生成html 頁面的插件
     new htmlWebpackPlugin({
     template:path.join(__dirname,'./src/index.html')
     filename:'index.html'
     })
    //這個節點,用於配置 全部 第三方模塊 加載器
    module:{
      rules:[
       {test:/\.css$,use:[]}
      ]     
    }

    4.prerender-spa-plugin

    構建階段生成匹配預渲染路徑的 html 文件

    npm install prerender-spa-plugin --save
    vue.config.js 
    
    const PrerenderSPAPlugin = require('prerender-spa-plugin')
    const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
    
    configureWebpack: config => {
        if (isProduction) {
          config.plugins.push(
            new CompressionWebpackPlugin({
              algorithm: 'gzip',
              test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
              threshold: 10240,
              minRatio: 0.8
            })
          ),
            config.plugins.push(
              new PrerenderSPAPlugin({
                staticDir: path.join(__dirname, 'dist'),
                routes: [
                  // '/'
                  '/login'
                  // '/show',
                  // '/websocket',
                  // 'websocket2',
                  // '/websocket3',
                  // '/home',
                  // 'abnormal/AbnormalStatis',
                  // 'abnormal/FocusCrowd',
                  // 'abnormal/FocusDetail',
                  // 'abnormal/ScaleDetail',
                  // 'abnormal/WarnSetup',
                  // 'abnormal/WarnDetail',
                  // 'abnormal/WarnLists',
                  // 'abnormal/PsychMonth',
                  // 'abnormal/PsychTeacher',
                  // 'abnormal/PsychList',
                  // 'laboratory/sports/MoveClock',
                  // 'laboratory/sports/ClockDetail',
                  // 'activity/ActList',
                  // 'activity/ActForm'
                ],
    
                minify: {
                  minifyCSS: true, // css壓縮
                  removeComments: true // 移除註釋
                },
                server: {
                  port: 8080
                },
    
                //忽略打包錯誤
                ignoreJSErrors: true,
                phantomOptions: '--web-security=false',
                maxAttempts: 10,
                renderer: new Renderer({
                  injectProperty: '__PRERENDER_INJECTED',
                  inject: {
                    foo: 'bar'
                  },
                  headless: false,
                  renderAfterTime: 5000,
                  renderAfterDocumentEvent: 'render-event'
                })
              })
            )
        }
      },
    
         main.js
          new Vue({
           mounted() {
            document.dispatchEvent(new Event('render-event')) 
          }
         }).$mount('#app')
    tips: main.js中的 render-event,要和 renderAfterDocumentEvent:'render-event' 一一對應 , publicPath 目前驗證必須是/ 不能自定義文件夾

    未完待續~~~

    相關文章
    相關標籤/搜索