1. 程式人生 > 實用技巧 >Vue知識點總結

Vue知識點總結

一、指令

1.入門

<body>
    <div id="app">
       <div>{{msg}}</div>      1.標籤用於填充資料   插值表示式
    </div>
    <script type="text/javascript" src="js/vue.js"></script>  2.引入vue.js庫檔案
    <script>
        var vm = new Vue({  3.使用vue的語法
            el: '#app',  
            data {       
                msg: 'Hello Vue'   4.把vue提供的資料填充到標籤中
            }
        })
    </script>
</body>

2. v-cloak 防止頁面載入時出現閃爍問題

原理:先通過樣式隱藏內容,在記憶體中進行值得替換,替換好之後顯示最終結果

<style>
    [v-cloak] {  
        display: none; 
    }
</style>
<body>
    <div id="app">
       <div v-cloak>{{msg}}</div>     
    </div>
    <script type="text/javascript" src="js/vue.js"></script>  
    <script>
        var vm = new Vue({ 
            el: '#app',  
            data {      
                msg: 'Hello Vue'
            }
        })
    </script>
</body>

3. v-text 將資料填充到標籤中

作用於插值表示式,沒有閃爍問題。
注意:此處為單向繫結,資料物件上的值改變,插值會發生變化。插值變化,不影響資料物件的值

<body>
    <div id="app">
       <div v-text="msg"></div>       
    </div>
    <script type="text/javascript" src="js/vue.js"></script>  
    <script>
        var vm = new Vue({ 
            el: '#app',  
            data {      
                msg: 'Hello Vue'
            }
        })
    </script>
</body>

4.v-html 可以將HTML片段填充到標籤中,會將其當html標籤解析後輸出

5.v-pre 跳過編譯,直接顯示

6.v-once 執行一次性的插值,當資料改變時,插值處內容不會繼續更新

應用場景: 顯示後的資訊後續不用再修改,用v-once

7.v-model 雙向資料繫結

當資料發生變化的時候,檢視會發生變化。
當檢視發生變化的時候,資料也會跟著同步變化
限制在<input><select><textarea> components中使用

v-model原理(v-bind繫結資料,v-on處理資料)

<div id="app">
    <input v-bind:value="msg" v-on:input="handle">
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            msg: "hello"
        },
        methods: {
            handle: function(event){
                this.msg = event.target.value;
            }
        }
    })
</script>

8.v-on用來繫結事件的

  1. 無參
    v-on:click 縮寫 @click
<div id="app">
    <div>{{num}}</div>
    <div>
        <button v-on:click="num++">點選</button>   
        <button @click="num++">點選1</button> 
        <button @click="handle">點選2</button> 
        <button @click="handle()">點選3</button> 
    </div>
</div>
<script type="text/javascript">
    var vm = new Vue({
        el: "#app"
        data: {
            num: 0
        },
        methods: {
            handle: function(){
                console.log(this === vm) 
                this.num++;
            }
        }
    })
</script>
  1. v-on事件函式傳入引數
<div>
    <div>{{num}}</div>
    
    <button v-on:click="handle">點選</button>
    
    <button v-on:click="handle1(12, $event)">點選1</button>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            num: 0
        },
        methods: {
            handle: function(event){
                console.log(event.target.innerHTML)
            },
            handle1: function(p, event){
                console.log(p)
                console.log(event.target.innerHTML)
                this.num++
            }
        }
    })
</script>
  1. 事件修飾符
<a v-on:click.stop="doThis"></a>  
<a v-on:click.submit.prevent="onSubmit></a>  <!--阻止預設"event.preventDefault()-->
v-on:click.stop.prevent  
v-on:click.prevent.self  
v-on:click.self.prevent  
  1. 按鍵修飾符
<input v-on:keyup.13="submit">  
<input v-on:keyup.enter="submit">
<input v-on:keyup.enter.space="alerMe">  

常見按鍵修飾符

.enter  .tab   .delete  .esc  .space  .up  .down  .left  .right

自定義按鍵修飾符(通過config.keyCodes自定義按鍵修飾符別名)

<div id="app">
    <input v-on:keydown.f5 = "prompt()">
</div>
<script>
    Vue.config.keyCodes.f5 = 116;
    var vm = new Vue({
        el: "#app",
        methods: {
            prompt: function(){
                alter("我是f5");
            }
        }
    })
</script>

9.v-bind屬性繫結

v-bind:href 縮寫為href(對應js的getAttribute / setAttribute)

  1. 繫結物件
    可以給v-bind:class一個物件,以動態地切換class。
    注:v-bind:class 指令可以與普通class特性共存
<ul v-bind:class="{textColor: isColor, textSize: isSize}">
    <li>學習</li>
    <li>Js</li>
</ul>
<div v-bind:style="{color: activeColor, fontSize: activeSize}">物件語法</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            isColor: true,
            isSize: true,
            active: "red",
            active: "25px"
        }
    })
</script>
  1. 繫結陣列
<ul :class="[classA, classB]">
    <li>學習</li>
</ul>
<div :style="[styleObj1, styleObj2]"></div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            classA: 'textColor',
            classB: 'textSize'
        },
        styleObj1: {
             color: 'red'
       },
       styleObj2: {
            fontSize: '30px'
       }
    })
</script>

10.v-if

11.v-show

12.v-for 可迴圈物件/陣列/普通元素

二、Vue常用特性

1.表單基本操作

獲取單選框裡面的值,v-model
獲取複選框裡面的值,v-model
獲取下拉框和文字框中的值,v-model

2.表單修飾符

.number
.trim
.lazy 

3.自定義指令

1.Vue.directive註冊全域性指令

<input type="text" v-focus> 
<input type="text" v-color="msg">
<script>
    Vue.directive('focus',{   
        inserted: function(el){
            el.focus()
        }
    })
    Vue.directive('color', {
        bind: function(el, binding){
            el.style.backgroundColor = binding.value.color;
        }
    })
    var vm = new Vue({
        el: '#app',
        data: {
            msg: {
                color: 'blue'
            }
        }
    })
</script>
  1. 在directives中註冊區域性指令
<input type="text" v-focus> 
<input type="text" v-color="msg">
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            msg: {
                color: 'blue'
            }
        }
        directives: {
            color: {
                inserted:function(el){
                    el.focus()
                } 
            },
            focus: {
                bind:function(el, binding){
                    el.style.backgroundColor = binding.value.color;
                }
            }
        }    
    })

4.計算屬性computed(他們的響應式依賴快取)

適合對多個變數或物件進行處理後返回一個結果值。
在多個變數中的某一個值發生了變化,監控的這個值也會發生變化

<div>
    <div>{{reverseString}}</div>
</div>
<script>
    var vm = new Vue({
        el: 'app',
        data: {
            num: 100
        },
        computed: {
            reverseString: function(){
                console.log('computed')
                var total = 0;
                for(var i=0 ; i <= this.num; i++){
                    total += i;
                }
                return total;  
            }
        }
    })
</script>

5.偵聽器watch (watch中的屬性一定是data中已經存在的資料)

當需要監聽一個物件的改變時,普通的wacth方法無法監聽到物件內部屬性的改變。
只要data中的資料才能夠監聽到變化,此時需要deep屬性對物件進行深度監聽

 <div id="app">
        <div>
            <span>名:</span>
            <span>
        <input type="text" v-model='firstName'>
      </span>
        </div>
        <div>
            <span>姓:</span>
            <span>
        <input type="text" v-model='lastName'>
      </span>
        </div>
        <div>{{fullName}}</div>
    </div>
  <script type="text/javascript">
        var vm = new Vue({
            el: '#app',
            data: {
                firstName: 'Jim',
                lastName: 'Green',
            },
            watch: {
                firstName: function(val) {
                    this.fullName = val + ' ' + this.lastName;
                },
                lastName: function(val) {
                    this.fullName = this.firstName + ' ' + val;
                }
            }
        });
    </script>

6.過濾器

應用:雙花括號插值 和 v-bind表示式
支援級聯操作

<div id="app">
    <div>{{msg | upper | lower}}</div>
    <div :abc='msg | upper'>測試資料</div>
    <div> {{ message | filterA('arg1', 'arg2') }}</div>  
  </div>
<script type="text/javascript">
   Vue.filter('lower', function(val) {  
      return val.charAt(0).toLowerCase() + val.slice(1);
    });
    Vue.filter('filterA',function(n,a,b){   
            if(n<10){
                return n+a;
            }else{
                return n+b;
            }
        });
    var vm = new Vue({
      el: '#app',
      data: {
        msg: ''
      },
      filters: { 
        upper: function(val) {
          return val.charAt(0).toUpperCase() + val.slice(1);
        }
      }
    });
  </script>

7.生命週期鉤子

常用的鉤子函式

鉤子函式 說明
beforeCreate 在例項初始化之後,資料觀測和事件配置之前被呼叫 此時data 和 methods 以及頁面的DOM結構都沒有初始化 什麼都做不了
created 在例項建立完成後被立即呼叫此時data 和 methods已經可以使用 但是頁面還沒有渲染出來
beforeMount 在掛載開始之前被呼叫 此時頁面上還看不到真實資料 只是一個模板頁面而已
mounted el被新建立的vm.$el替換,並掛載到例項上去之後呼叫該鉤子。 資料已經真實渲染到頁面上 在這個鉤子函式裡面我們可以使用一些第三方的外掛
beforeUpdate 資料更新時呼叫,發生在虛擬DOM打補丁之前。 頁面上資料還是舊的
updated 由於資料更改導致的虛擬DOM重新渲染和打補丁,在這之後會呼叫該鉤子。 頁面上資料已經替換成最新的
beforeDestroy 例項銷燬之前呼叫
destroyed 例項銷燬後呼叫

9.動態陣列響應式資料

Vue.set(a, b, c)  //讓觸發檢視重新更新一遍,資料動態展示
a  要更改的資料
b  資料的第幾項
c  更改後的資料

三、Vue元件 component

1.全域性註冊

Vue.component('元件名稱', {})

<div id="example">
    <my-component></my-component>
</div>
<script>
    Vue.component('my-component', {
        template: '<div>A custom </div>'
    })
    new Vue({
        el: '#example'
    })
</script>

元件注意事項

元件引數的data值必須是函式同時這個函式要求返回一個物件
元件模板必須是單個根元素
元件模板的內容可以是模板字串

<div>
    <button-counter></button-counter>
</div>
<script>
    Vue.component('button-counter', {
        data: function(){
            return {
                count: 0
            }
        },
        template: `
            <button @click="handle">點選{{count}}次數</button>
            <div>測試</div>
        `,
        methods: {
            handle: function(){
                this.count += 2
            }
        }
    })
</script>

2.區域性註冊

 <div id="app">
      <my-component></my-component>
  </div>
<script>
    var Child = {  // 定義元件的模板
      template: '<div>A custom component!</div>'
    }
    new Vue({
      components: {
        'my-component': Child
      }
    })
 </script>

3.Vue元件之間傳值--父元件向子元件傳值

父元件傳送的形式:是以形式繫結值到子元件身上 子元件接收的方式:用props接收

<div id="app">
    <div>{{pmsg}}</div>
     
     
    <menu-item title='來自父元件的值'></menu-item>
    
    <menu-item :title='ptitle' content='hello'></menu-item>
  </div>

  <script type="text/javascript">
    Vue.component('menu-item', {
      
      props: ['title', 'content'],
      data: function() {
        return {
          msg: '子元件本身的資料'
        }
      },
      template: '<div>{{msg + "----" + title + "-----" + content}}</div>'
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父元件中內容',
        ptitle: '動態繫結屬性'
      }
    });
  </script>

4.Vue元件之間傳值--子元件向父元件傳值

子元件:用

emit()第一個引數為自定義的事件名稱,第二個引數為需要傳遞的資料
父元件:用v-on監聽子元件的事件

<div id="app">
    <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
        
    <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    
    Vue.component('menu-item', {
      props: ['parr'],
      template: `
        <div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>
            ##  1、子元件用$emit()觸發事件
            ## 第一個引數為 自定義的事件名稱   第二個引數為需要傳遞的資料  
          <button @click='$emit("enlarge-text", 5)'>擴大父元件中字型大小</button>
          <button @click='$emit("enlarge-text", 10)'>擴大父元件中字型大小</button>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父元件中內容',
        parr: ['apple','orange','banana'],
        fontSize: 10
      },
      methods: {
        handle: function(val){
          
          this.fontSize += val;
        }
      }
    });
  </script>

5.Vue元件之間傳值--兄弟元件之間傳值

事件中心傳遞資料 提供事件中心 var hub = new Vue()   
傳遞資料,通過一個事件觸發hub.$emit(方法名,傳遞的資料)  
接收資料,通過mounted() {}鉤子中,觸發hub.$on()方法名  
銷燬事件,通過hub.$off()方法名銷燬之後無法進行傳遞資料 
 <div id="app">
    <div>父元件</div>
    <div>
      <button @click='handle'>銷燬事件</button>
    </div>
    <test-tom></test-tom>
    <test-jerry></test-jerry>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    
    
    var hub = new Vue();

    Vue.component('test-tom', {
      data: function(){
        return {
          num: 0
        }
      },
      template: `
        <div>
          <div>TOM:{{num}}</div>
          <div>
            <button @click='handle'>點選</button>
          </div>
        </div>
      `,
      methods: {
        handle: function(){
          
          hub.$emit('jerry-event', 2);
        }
      },
      mounted: function() {
       
        hub.$on('tom-event', (val) => {
          this.num += val;
        });
      }
    });
    Vue.component('test-jerry', {
      data: function(){
        return {
          num: 0
        }
      },
      template: `
        <div>
          <div>JERRY:{{num}}</div>
          <div>
            <button @click='handle'>點選</button>
          </div>
        </div>
      `,
      methods: {
        handle: function(){
          
          hub.$emit('tom-event', 1);
        }
      },
      mounted: function() {
        
        hub.$on('jerry-event', (val) => {
          this.num += val;
        });
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {
        
      },
      methods: {
        handle: function(){
          
          hub.$off('tom-event');
          hub.$off('jerry-event');
        }
      }
    });
  </script>

6.元件插槽

匿名插槽

<div id="app">
      
    <alert-box>有bug發生</alert-box>
    <alert-box>有一個警告</alert-box>
    <alert-box></alert-box>
  </div>

  <script type="text/javascript">
    /*
      元件插槽:父元件向子元件傳遞內容
    */
    Vue.component('alert-box', {
      template: `
        <div>
          <strong>ERROR:</strong>
        # 當元件渲染的時候,這個 <slot> 元素將會被替換為“元件標籤中巢狀的內容”。
        # 插槽內可以包含任何模板程式碼,包括 HTML
          <slot>預設內容</slot>
        </div>
      `
    });
  </script>
</body>
</html>

具名插槽

使用 中的 "name" 屬性繫結元素

<div id="app">
    <base-layout>
        
      <p slot='header'>標題資訊</p>
      <p>主要內容1</p>
      <p>主要內容2</p>
      <p slot='footer'>底部資訊資訊</p>
    </base-layout>

    <base-layout>
        
      <template slot='header'>
        <p>標題資訊1</p>
        <p>標題資訊2</p>
      </template>
      <p>主要內容1</p>
      <p>主要內容2</p>
      <template slot='footer'>
        <p>底部資訊資訊1</p>
        <p>底部資訊資訊2</p>
      </template>
    </base-layout>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      具名插槽
    */
    Vue.component('base-layout', {
      template: `
        <div>
          <header>
            ### 1、 使用 <slot> 中的 "name" 屬性繫結元素 指定當前插槽的名字
            <slot name='header'></slot>
          </header>
          <main>
            <slot></slot>
          </main>
          <footer>
            ##  注意點: 
            ##  具名插槽的渲染順序,完全取決於模板,而不是取決於父元件中元素的順序
            <slot name='footer'></slot>
          </footer>
        </div>
      `
    });
  </script>
</body>
</html>

作用域插槽

  • 父元件對子元件加工處理
  • 既可以複用子元件的slot,又可以使slot內容不一致
 <div id="app">
    <fruit-list :list='list'>
      <template slot-scope='slotProps'>
        <strong v-if='slotProps.info.id==3' class="current">
            {{slotProps.info.name}}              
         </strong>
        <span v-else>{{slotProps.info.name}}</span>
      </template>
    </fruit-list>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    Vue.component('fruit-list', {
      props: ['list'],
      template: `
        <div>
          <li :key='item.id' v-for='item in list'>
    ##  1、 在子元件模板中,<slot>元素上有一個類似props傳遞資料給元件的寫法msg="xxx",
    ##   插槽可以提供一個預設內容,如果如果父元件沒有為這個插槽提供了內容,會顯示預設的內容。
    ##   如果父元件為這個插槽提供了內容,則預設的內容會被替換掉
            <slot :info='item'>{{item.name}}</slot>
          </li>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        list: [{
          id: 1,
          name: 'apple'
        },{
          id: 2,
          name: 'orange'
        },{
          id: 3,
          name: 'banana'
        }]
      }
    });
  </script>
</body>
</html>

四、介面呼叫方式

  • 原生ajax
  • 基於jQuery的ajax
  • fetch
  • axios

1.非同步

  • JS中常見的非同步呼叫
    • 定時任何
    • ajax
    • 事件函式

2. promise

promise

var p = new Promise(function(resolve, reject){ 
      setTimeout(function(){
        var flag = false;
        if(flag) {   
          resolve('hello');
        }else{       
          reject('出錯了');
        }
      }, 100);
    });
    p.then(function(data){
      console.log(data)
    },function(info){
      console.log(info)
    });

promise傳送Ajax

 function queryData(url) {
      var p = new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
          if(xhr.readyState != 4) return;
          if(xhr.readyState == 4 && xhr.status == 200) {  
            resolve(xhr.responseText);
          }else{  
            reject('伺服器錯誤');
          }
        };
        xhr.open('get', url);
        xhr.send(null);
      });
      return p;
    }
    
    queryData('http://localhost:3000/data')
      .then(function(data){
        console.log(data)
        return queryData('http://localhost:3000/data1');
      })
      .then(function(data){
        console.log(data);
        return queryData('http://localhost:3000/data2');
      })
      .then(function(data){
        console.log(data)
      });

promise常用API

    function foo() {
      return new Promise(function(resolve, reject){
        setTimeout(function(){
          
          reject('error');
        }, 100);
      })
    }
    foo()                          等效   foo()
      .then(function(data){                 .then(function(data){
        console.log(data)                       console.log(data)
      },function(data){                     }).catch(function(data){
        console.log(data)                       console.log(data)
      })                                    })
      .finally(function(){                  .finally(function(){
        console.log('finished')                 console.log('finished')
      });                                    });
    function queryData(url) {
      return new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
          if(xhr.readyState != 4) return;
          if(xhr.readyState == 4 && xhr.status == 200) { 
            resolve(xhr.responseText);
          }else{ 
            reject('伺服器錯誤');
          }
        };
        xhr.open('get', url);
        xhr.send(null);
      });
    }

    var p1 = queryData('http://localhost:3000/a1');
    var p2 = queryData('http://localhost:3000/a2');
    var p3 = queryData('http://localhost:3000/a3');
    
    
    
    Promise.race([p1,p2,p3]).then(function(result){
      console.log(result)
    })

3.Fetch

    fetch('http://localhost:3000/fdata').then(function(data){
      // text()方法屬於fetchAPI的一部分,它返回一個Promise例項物件,用於獲取後臺返回的資料
      return data.text();
    }).then(function(data){
      console.log(data);
    })

4. Fetch API 呼叫介面傳遞引數

GET引數傳遞-傳統URL

    fetch('http://localhost:3000/books?id=123', {
      method: 'get'
    })
      .then(function(data){
        return data.text();
      }).then(function(data){
        console.log(data)
      });

GET引數傳遞-restful形式的URL

   fetch('http://localhost:3000/books/456', {
      method: 'get'
    })
      .then(function(data){
        return data.text();
      }).then(function(data){
        console.log(data)
      });

DELETE請求方式引數傳遞

    fetch('http://localhost:3000/books/789', {
      method: 'delete'
    })
      .then(function(data){
        return data.text();
      }).then(function(data){
        console.log(data)
      });

POST請求傳參

    fetch('http://localhost:3000/books', {
      method: 'post',
      body: 'uname=lisi&pwd=123',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    })
      .then(function(data){
        return data.text();
      }).then(function(data){
        console.log(data)
      });
    fetch('http://localhost:3000/books', {
      method: 'post',
      body: JSON.stringify({
        uname: '張三',
        pwd: '456'
      }),
      headers: {
        'Content-Type': 'application/json'
      }
    })
      .then(function(data){
        return data.text();
      }).then(function(data){
        console.log(data)
      });

PUT請求傳參

    fetch('http://localhost:3000/books/123', {
      method: 'put',
      body: JSON.stringify({
        uname: '張三',
        pwd: '789'
      }),
      headers: {
        'Content-Type': 'application/json'
      }
    })
      .then(function(data){
        return data.text();
      }).then(function(data){
        console.log(data)
      });

5.Fetch響應結果的資料格式

    fetch('http://localhost:3000/json').then(function(data){
      // return data.json();
      return data.text();
    }).then(function(data){
      // console.log(data.uname)
      // console.log(typeof data)
      var obj = JSON.parse(data);
      console.log(obj.uname,obj.age,obj.gender)
    })

6.axios基本用法 (axios是個庫)

    axios.get('http://localhost:3000/adata').then(function(ret){
      // 注意data屬性是固定的用法,用於獲取後臺的實際資料
      // console.log(ret.data)
      console.log(ret)
    })

7.axios請求引數傳遞

axios get請求傳參

    axios.get('http://localhost:3000/axios?id=123').then(function(ret){
    
      console.log(ret.data)
    })
    
    axios.get('http://localhost:3000/axios/123').then(function(ret){
      console.log(ret.data)
    })
    
    axios.get('http://localhost:3000/axios', {
      params: {
        id: 789
      }
    }).then(function(ret){
      console.log(ret.data)
    })

axios delete 請求傳參

    axios.delete('http://localhost:3000/axios', {
      params: {
        id: 111
      }
    }).then(function(ret){
      console.log(ret.data)
    })

axios post請求傳參

    axios.post('http://localhost:3000/axios', {  
      uname: 'lisi',
      pwd: 123
    }).then(function(ret){
      console.log(ret.data)
    })
    
    var params = new URLSearchParams();  
    params.append('uname', 'zhangsan');
    params.append('pwd', '111');
    axios.post('http://localhost:3000/axios', params).then(function(ret){
      console.log(ret.data)
    })

axios put 請求傳參

    axios.put('http://localhost:3000/axios/123', {
      uname: 'lisi',
      pwd: 123
    }).then(function(ret){
      console.log(ret.data)
    })

8.axios響應結果

    axios.get('http://localhost:3000/axios-json').then(function(ret){
      console.log(ret.data.uname)
    })

9.axios全域性配置

    // 配置請求的基準URL地址
    axios.defaults.baseURL = 'http://localhost:3000/';
    // 配置請求頭資訊
    axios.defaults.headers['mytoken'] = 'hello';
    axios.get('axios-json').then(function(ret){
      console.log(ret.data.uname)
    })

10.axios攔截器

請求攔截器

    axios.interceptors.request.use(function(config) {
      console.log(config.url)
      config.headers.mytoken = 'nihao';
      return config;
    }, function(err){
      console.log(err)
    })

響應攔截器

    axios.interceptors.response.use(function(res) {
      // console.log(res)
      var data = res.data;
      return data;
    }, function(err){
      console.log(err)
    })

11.async 函式基本用法

async/await 處理非同步操作:
async函式返回一個Promise例項物件
await後面可以直接跟一個 Promise例項物件

axios 與 async

    axios.defaults.baseURL = 'http:localhost:3000';
    axios.get('adata').then(function(ret){
      console.log(ret.data)
    })
    
    axios.defaults.baseURL = 'http:localhost:3000';
    async function queryData() {
      var ret = await axios.get('adata');
      // console.log(ret.data)
      return ret.data;
    }

async 與 promise

    async function queryData() {
      var ret = await new Promise(function(resolve, reject){
        setTimeout(function(){
          resolve('nihao')
        },1000);
      })
      // console.log(ret.data)
      return ret;
    }
    queryData().then(function(data){
      console.log(data)
    })

12.async/await處理多個非同步任務

    axios.defaults.baseURL = 'http://localhost:3000';

    async function queryData() {
      var info = await axios.get('async1');
      var ret = await axios.get('async2?info=' + info.data);
      return ret.data;
    }

    queryData().then(function(data){
      console.log(data)
    })

五、路由 Vue-Router

1、路由:本質一種對應關係

路由分為前端路由和後端路由
1).後端路由是由伺服器端進行實現,並完成資源的分發
2).前端路由是依靠hash值(錨鏈接)的變化進行實現

2、前端路由

前端路由是基於hash值的變化進行實現的(比如點選頁面中的選單或者按鈕改變URL的hash值,根據hash值的變化來控制組件的切換)
核心實現依靠一個事件,即監聽hash值變化的事件

window.onhashchange = function(){
    //location.hash可以獲取到最新的hash值
    location.hash
}

3.Vue Router

Vue Router的特性:

支援H5歷史模式或者hash模式
支援巢狀路由
支援路由引數
支援程式設計式路由
支援命名路由
支援路由導航守衛
支援路由過渡動畫特效
支援路由懶載入
支援路由滾動行為

4、Vue-Router使用

  • A.匯入js檔案
<script src="lib/vue_2.5.22.js"></script>
<script src="lib/vue-router_3.0.2.js"></script>
  • B.新增路由連結:是路由中提供的標籤,預設會被渲染為a標籤,to屬性預設被渲染為href屬性, to屬性的值會被渲染為#開頭的hash地址
<router-link to="/user">User</router-link>
<router-link to="/login">Login</router-link>
  • C.新增路由填充位(路由佔位符)
<router-view></router-view>
  • D.定義路由元件
var User = { template:"<div>This is User</div>" }
var Login = { template:"<div>This is Login</div>" }
  • E.配置路由規則並建立路由例項
var myRouter = new VueRouter({
    //routes是路由規則陣列
    routes:[
        //每一個路由規則都是一個物件,物件中至少包含path和component兩個屬性
        //path表示  路由匹配的hash地址,component表示路由規則對應要展示的元件物件
        {path:"/user",component:User},
        {path:"/login",component:Login}
    ]
})
  • F.將路由掛載到Vue例項中
new Vue({
    el:"#app",
    //通過router屬性掛載路由物件
    router:myRouter
})

5.路由重定向

var myRouter = new VueRouter({
    //routes是路由規則陣列
    routes: [
        //path設定為/表示頁面最初始的地址,redirect表示要被重定向的新地址,設定為一個路由即可
        { path:"/",redirect:"/user"},
        { path: "/user", component: User },
        { path: "/login", component: Login }
    ]
})

6、巢狀路由,動態路由的實現方式

巢狀路由的概念

  <body>
    <div id="app">
      <router-link to="/user">User</router-link>
      <router-link to="/register">Register</router-link>
      <router-view></router-view>  
    </div>
    <script>
      const User = {
        template: '<h1>User 元件</h1>'
      }
      const Register = {
        template: `<div>
          <h1>Register 元件</h1>
          <hr/>

          
          <router-link to="/register/tab1">tab1</router-link>
          <router-link to="/register/tab2">tab2</router-link>

          
          <router-view />
        <div>`
      }

      const Tab1 = {
        template: '<h3>tab1 子元件</h3>'
      }

      const Tab2 = {
        template: '<h3>tab2 子元件</h3>'
      }
      const router = new VueRouter({  // 建立路由例項物件
        routes: [ // 所有的路由規則
          { path: '/', redirect: '/user'},
          { path: '/user', component: User },
          { path: '/register', component: Register, children: [ // children 陣列表示子路由規則
            { path: '/register/tab1', component: Tab1 },
            { path: '/register/tab2', component: Tab2 }
          ] }
        ]
      })
      const vm = new Vue({  // 建立 vm 例項物件
        el: '#app',  // 指定控制的區域
        data: {},
        // 掛載路由例項物件
        // router: router
        router
      })
    </script>
  </body>
</html>

動態路由匹配1使用$route.params.id來獲取路徑傳參的資料

var User = { template:"<div>使用者:{{$route.params.id}}</div>"}
var myRouter = new VueRouter({
    //routes是路由規則陣列
    routes: [
        //通過/:引數名  的形式傳遞引數 
        { path: "/user/:id", component: User },
    ]
})

動態路由匹配2通過props來接收引數

var User = { 
    props:["id"],
    template:"<div>使用者:{{id}}</div>"
    }

var myRouter = new VueRouter({
    //routes是路由規則陣列
    routes: [
        //通過/:引數名  的形式傳遞引數 
        //如果props設定為true,route.params將會被設定為元件屬性
        { path: "/user/:id", component: User,props:true },
    ]
})

動態路由匹配3將props設定為物件,那麼就直接將物件的資料傳遞給 元件進行使用

var User = { 
    props:["username","pwd"],
    template:"<div>使用者:{{username}}---{{pwd}}</div>"
    }

var myRouter = new VueRouter({
    //routes是路由規則陣列
    routes: [
        //通過/:引數名  的形式傳遞引數 
        //如果props設定為物件,則傳遞的是物件中的資料給元件
        { path: "/user/:id", component: User,props:{username:"jack",pwd:123} },
    ]
})

動態路由匹配4.如果想要獲取傳遞的引數值還想要獲取傳遞的物件資料,那麼props應該設定為 函式形式。

var User = { 
    props:["username","pwd","id"],
    template:"<div>使用者:{{id}} -> {{username}}---{{pwd}}</div>"
    }

var myRouter = new VueRouter({
    //routes是路由規則陣列
    routes: [
        //通過/:引數名  的形式傳遞引數 
        //如果props設定為函式,則通過函式的第一個引數獲取路由物件
        //並可以通過路由物件的params屬性獲取傳遞的引數
        //
        { path: "/user/:id", component: User,props:(route)=>{
            return {username:"jack",pwd:123,id:route.params.id}
            } 
        },
    ]
})

7.命名路由以及程式設計式導航

命名路由:給路由取別名

var myRouter = new VueRouter({
    //routes是路由規則陣列
    routes: [
        //通過name屬性為路由新增一個別名
        { path: "/user/:id", component: User, name:"user"},
    ]
})
//添加了別名之後,可以使用別名進行跳轉
<router-link to="/user">User</router-link>
<router-link :to="{ name:'user' , params: {id:123} }">User</router-link>
//還可以程式設計式導航
myRouter.push( { name:'user' , params: {id:123} } )

程式設計式導航:通過點選連結的方式實現的導航 程式設計式導航:呼叫js的api方法實現導航

this.$router.push("hash地址");
this.$router.push("/login");
this.$router.push({ name:'user' , params: {id:123} });
this.$router.push({ path:"/login" });
this.$router.push({ path:"/login",query:{username:"jack"} });

this.$router.go( n );//n為數字,參考history.go
this.$router.go( -1 );