Vue 知識總結

前言:

基于vue 2+ 寫一份知識總結匀借,可以說是學習筆記

目錄:

一颜阐、vue實例的基本結構
二、vue事件處理吓肋、綁定屬性
三凳怨、vue指令、自定義指令
四是鬼、vue過濾器
五肤舞、vue數(shù)據(jù)監(jiān)聽
六、vue組件
七屑咳、vue-router
八萨赁、axios

一弊琴、Vue 實例的基本結構

Vue官網API

 <div id="app">
   <p>{{msg}}<p>
 </div>
 Welcome
var vm = new Vue({
  el: '#app', //等價于后面的 .$mount('#app') 用其中之一就可以了
  render: h => h(App), //理解不夠深入兆龙,參考(https://cn.vuejs.org/v2/api/?#render)
  data: { 
    //頁面響應的數(shù)據(jù)都放在這里如上(組件只接受 function 且必須返回一個對象),zhicvm.$data 訪問這里面的data
    msg: 'Welcome',
  },
  props:{
    //props 可以是數(shù)組或對象敲董,接收任何值
  },
  methods:  {
    //頁面或組件定義的方法的集合紫皇,可通過 vm.reset() 直接調用
    reset: function(){
      this.msg = '這是重新設置之后的數(shù)據(jù)'
    }
  },
  computed: {
    //計算屬性(computed)與方法(methods) 類似,如果計算數(shù)據(jù)量比較大腋寨,建議放到這里
    //計算屬性的結果會被緩存聪铺,除非依賴的響應式屬性變化才會重新計算。
    //參考(https://cn.vuejs.org/v2/api/?#computed)
  },
  components:{
    // 局部組件注冊的地方
    'component-a': ComponentA,
    'component-b': ComponentB
  },
  directives: {
    // 局部指令注冊的地方
    focus: {
      // 指令的定義
      inserted: function (el,binding) {
        el.focus(); 
      }
    }
  },
  filters:{
    // 局部過濾器注冊的地方
  },
  //生命周期鉤子
  beforeCreate: function (){}, //在實例初始化之后萄窜,數(shù)據(jù)觀測 (data observer) 和 event/watcher 事件配置之前被調用铃剔。
  created: function (){},//在實例創(chuàng)建完成后被立即調用撒桨。
  beforeMount: function (){},//在掛載開始之前被調用:相關的 render 函數(shù)首次被調用。
  mounted: function (){},//el 被新創(chuàng)建的 vm.$el 替換键兜,并掛載到實例上去之后調用該鉤子凤类。
  beforeUpdate: function (){},//數(shù)據(jù)更新時調用,發(fā)生在虛擬 DOM 打補丁之前普气。
  updated: function (){},//由于數(shù)據(jù)更改導致的虛擬 DOM 重新渲染和打補丁谜疤,在這之后會調用該鉤子。
  beforeDestroy: function (){},//實例銷毀之前調用现诀。在這一步夷磕,實例仍然完全可用。
  destroyed: function (){
    //Vue 實例銷毀后調用仔沿。
    //調用后坐桩,Vue 實例指示的所有東西都會解綁定,所有的事件監(jiān)聽器會被移除封锉,所有的子實例也會被銷毀撕攒。
  },
}).$mount('#app')
二、Vue 事件處理烘浦、綁定屬性

v-on:

1抖坪、綁定事件監(jiān)聽器。用在普通元素上時闷叉,只能監(jiān)聽原生 DOM 事件(如:click擦俐、keyup/down、mouseenter/over/move/down/out 等)握侧。也可以監(jiān)聽自定義事件即 methods 里面的事件蚯瞧。
2、在監(jiān)聽原生 DOM 事件時品擎,方法以事件為唯一的參數(shù)埋合。如果使用內聯(lián)語句,語句可以訪問一個 $event 屬性:v-on:click="handle('ok', $event)"萄传。

修飾符:
.stop - 調用 event.stopPropagation()甚颂。阻止冒泡
.prevent - 調用 event.preventDefault()。阻止默認事件
.capture - 添加事件偵聽器時使用 capture 模式秀菱。
.self - 只當事件是從偵聽器綁定的元素本身觸發(fā)時才觸發(fā)回調振诬。
.{keyCode | keyAlias} - 只當事件是從特定鍵觸發(fā)時才觸發(fā)回調。
.native - 監(jiān)聽組件根元素的原生事件衍菱。
.once - 只觸發(fā)一次回調赶么。
.left - (2.2.0) 只當點擊鼠標左鍵時觸發(fā)。
.right - (2.2.0) 只當點擊鼠標右鍵時觸發(fā)脊串。
.middle - (2.2.0) 只當點擊鼠標中鍵時觸發(fā)辫呻。
.passive - (2.3.0) 以 { passive: true } 模式添加偵聽器
用法:
<!-- 內聯(lián)語句 -->
<button v-on:click="doThat('hello', $event)"></button>

<!-- 縮寫 -->
<button @click="doThis"></button>

<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>

<!-- 對象語法 (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
.
.
.
鍵盤按鈕的別名
.enter
.tab
.delete (捕獲“刪除”和“退格”鍵)
.esc
.space
.up
.down
.left
.right
// 可以通過全局 `config.keyCodes` 對象自定義按鍵修飾符別名
// 使用 方式 `v-on:keyup.f1` 清钥,f1 這個名字你可以任意取,你知道是什么意思就可以了
Vue.config.keyCodes.f1 = 112

v-bind:

動態(tài)地綁定一個或多個特性放闺,或一個組件 prop 到表達式循捺。

<!-- 綁定一個屬性 -->
<img v-bind:src="imageSrc">

<!-- 縮寫 -->
<img :src="imageSrc">

<!-- 內聯(lián)字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- class 綁定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 綁定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 綁定一個有屬性的對象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- prop 綁定⌒廴耍“prop”必須在 my-component 中聲明从橘。-->
<my-component :prop="someThing"></my-component>
.
.
.

三、Vue 指令础钠、自定義指令

Vue指令:

v-text:

<span v-text="msg"></span>
<!-- 和下面的一樣 -->
<span>{{msg}}</span>

v-html:

//輸出真正的 HTML
<div v-html="html"></div>

data{
  html:'<strong>我是真正的html</strong>'
}

v-show:

//根據(jù)表達式之真假值恰力,切換元素的 display CSS 屬性。
<h1 v-show="ok">Hello!</h1>

v-if旗吁、v-if-else踩萎、v-else:

//v-if 是“真正”的條件渲染,如果條件為假很钓,dom不會渲染在頁面當中
//v-show 會一直渲染在dom當中
//當 v-if 與 v-for 一起使用時香府,v-for 具有比 v-if 更高的優(yōu)先級。
<h1 v-if="ok">Yes</h1>

<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>

<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>

v-for:

//基于源數(shù)據(jù)多次渲染元素或模板塊码倦。
<div v-for="item in items">
  {{ item.text }}
</div>

//另外也可以為數(shù)組索引指定別名 (或者用于對象的鍵):val->對象的鍵值  key->對象的鍵  index->對象的下標
<div v-for="(item, index) in items"></div>
<div v-for="(val, key) in object"></div>
<div v-for="(val, key, index) in object"></div>

v-model:作用于<input>企孩、<select>、<textarea>袁稽,
當v-model作用于 多個復選框勿璃、當選擇按鈕選擇框 時推汽,都是把這些標簽的value值賦值給v-model的變量

修飾符:
.lazy - 取代 `input` 監(jiān)聽 `change` 事件
.number- 輸入字符串轉為數(shù)字
.trim- 輸入首尾空格過濾

<input v-model="message" placeholder="edit me">
<textarea v-model="message" placeholder="add multiple lines"></textarea>

// 選擇框
<select v-model="selected">
   <option disabled value="">請選擇</option>
   <option>A</option>
   <option>B</option>
   <option>C</option>
</select>

// 用 v-for 渲染的動態(tài)選項:
<select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
    {{ option.text }}
  </option>
</select>
.
.
.

v-pre:

//跳過這個元素和它的子元素的編譯過程补疑。可以用來顯示原始 Mustache 標簽歹撒。跳過大量沒有指令的節(jié)點會加快編譯莲组。
//Mustache 標簽:{{ }}
<span v-pre>{{ this will not be compiled }}</span>

v-cloak:

//這個指令保持在元素上直到關聯(lián)實例結束編譯
css:
[v-cloak] {
  display: none;
}
html:
<div v-cloak>
  {{ message }}
</div>

v-once:

只渲染元素和組件一次。隨后的重新渲染暖夭,元素/組件及其所有的子節(jié)點將被視為靜態(tài)內容并跳過锹杈。這可以用于優(yōu)化更新性能。

<!-- 單個元素 -->
<span v-once>This will never change: {{msg}}</span>
<!-- 有子元素 -->
<div v-once>
  <h1>comment</h1>
  <p>{{msg}}</p>
</div>
<!-- 組件 -->
<my-component v-once :comment="msg"></my-component>
<!-- `v-for` 指令-->
<ul>
  <li v-for="i in list" v-once>{{i}}</li>
</ul>

Vue自定義指令:

指令的鉤子函數(shù): 一個指令定義對象可以提供如下幾個鉤子函數(shù) (均為可選):

`bind`:只調用一次鳞尔,指令第一次綁定到元素時調用嬉橙。在這里可以進行一次性的初始化設置早直。

`inserted`:被綁定元素插入父節(jié)點時調用 (僅保證父節(jié)點存在寥假,但不一定已被插入文檔中)。

`update`:1霞扬、所在組件的 VNode 更新時調用糕韧,但是可能發(fā)生在其子 VNode 更新之前枫振。
          2、指令的值可能發(fā)生了改變萤彩,也可能沒有粪滤。
          3、你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細的鉤子函數(shù)參數(shù)見下)雀扶。

`componentUpdated`:指令所在組件的 VNode 及其子 VNode 全部更新后調用杖小。

`unbind`:只調用一次,指令與元素解綁時調用愚墓。

鉤子函數(shù)的參數(shù) (即 el予权、binding、vnode 和 oldVnode)浪册。

`el`:指令所綁定的元素扫腺,可以用來直接操作 DOM 。

`binding`:一個對象村象,包含以下屬性:
    `name`:指令名笆环,不包括 `v-` 前綴。
    `value`:指令的綁定值厚者,例如:`v-my-directive="1 + 1"` 中躁劣,綁定值為 `2`。
    `oldValue`:指令綁定的前一個值库菲,僅在 `update` 和 `componentUpdated` 鉤子中可用习绢。無論值是否改變都可用。
    `expression`:字符串形式的指令表達式蝙昙。例如 `v-my-directive="1 + 1"` 中闪萄,表達式為 `"1 + 1"`。
    `arg`:傳給指令的參數(shù)奇颠,可選败去。例如 `v-my-directive:foo` 中,參數(shù)為 `"foo"`烈拒。
    `modifiers`:一個包含修飾符的對象圆裕。例如:`v-my-directive.foo.bar` 中,修飾符對象為 `{ foo: true, bar: true }`荆几。

`vnode`:Vue 編譯生成的虛擬節(jié)點吓妆。移步(https://cn.vuejs.org/v2/api/#VNode%E6%8E%A5%E5%8F%A3) 來了解更多詳情。

`oldVnode`:上一個虛擬節(jié)點吨铸,僅在 `update` 和 `componentUpdated` 鉤子中可用行拢。
// 注冊一個全局自定義指令 `v-focus`
// 在這里需要注意一下,給一個全局指令命名的時候不要加 `v-` 前綴诞吱,用在dom的時候再加上
Vue.directive('focus', {
  // 當被綁定的元素插入到 DOM 中時……
  inserted: function (el,binding) {
    // 聚焦元素
    el.focus();
    console.log(binding.value) //=>666
  }
})

//如果想注冊局部指令舟奠,組件中也接受一個 directives 的選項:
directives: {
  focus: {
    // 指令的定義
    inserted: function (el,binding) {
      el.focus(); 
      console.log(binding.value) //=>666
    }
  }
}

//然后你可以在模板中任何元素上使用新的 v-focus 屬性竭缝,如下:
<input v-focus="6666">  // 6666 可用data 里面的變量替換,建議傳簡單數(shù)據(jù)類型

一個正常的業(yè)務不可能只有一個指令沼瘫,如果把所有的指令都注冊在main.js里面會不好管理抬纸,所以最好放在一個統(tǒng)一文件 directives.js
這里就產生了兩個問題:
1、怎么把directives.js 這個文件引用到main.js
2耿戚、Vue.directives() 支不支持鏈式調用(因為老版本angular 支持湿故,所以做一個假想)

// 第二個問題很好解決,經過測試膜蛔,Vue.directives() 不支持鏈式調用 `Vue.directives().directives()`

// 第一個問題:經過查閱相關資料之后可以以插件的形式引入
// 這種方式引入暫時還沒有發(fā)現(xiàn)有其他的問題

// main.js
import directives from './directives.js'
Vue.use(directives);

// directives.js
export default{
  // install 方法會默認在main.js里面調用
  install(Vue){
    Vue.directive('focus',{
      inserted(el,binding){
        el.focus();
      }
    });
    Vue.directive('data',{
      inserted(el){
        console.log(el)
      }
    });
    //有多個就繼續(xù)往這里添加就好了
  }
}

四晓锻、Vue 過濾器

Vue 過濾器的用法

過濾器可以用在兩個地方:雙花括號插值和 v-bind 表達式 (后者從 2.1.0+ 開始支持)。
與指令的用法類似飞几,但過濾器一定要有返回值砚哆,也不支持鏈式調用

這里需要注意的地方是,vue 2.0 之后移除了自帶的過濾器

// 在雙花括號中
{{ message | capitalize }}

// 在 `v-bind` 中
<div v-bind:id="rawId | formatId"></div>

// 局部注冊過濾器
filters: {
  // 首字母大寫
  capitalize: function (value) {
    // value 就是 ‘|’ 符號前面的值
    if (!value) return '';
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

// 注冊全局過濾器
Vue.filter('capitalize', function (value) {
  if (!value) return '';
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})
// 過濾器傳值
{{ number | dual(2) }}

Vue.filter('dual', function (value,type) {
  // 回調函數(shù)里面默認有 value ,在頁面上傳過來的值會依次添加在后面
  console.log(type)  // => 2
  if (!value) return '';
  if (typeof value !== "number") return alert(value + ' 不是數(shù)字');
  if( parseInt(type) === 2 ){
    return value = value > 10 ? value : '0' + value
  }
  return value
})
// 過濾器的插件用法屑墨,與 directives.js 一致
// main.js
import directives from './filters.js'
Vue.use(filters);

// filters.js
export default {
  install(Vue){
    Vue.filter('dual', function (value,type) {
      if (!value) return '';
      if (typeof value !== "number") return alert(value + ' 不是數(shù)字');
      if( parseInt(type) === 2 ){
        return value = value > 10 ? value : '0' + value
      }
      return value
    })
  }
}

五躁锁、Vue 數(shù)據(jù)監(jiān)聽

Vue 數(shù)據(jù)監(jiān)聽 watch

// watch 基本用法與注意事項
data: {
  a: 1,
  e: {
    f: {
      g: 5
    }
  },
  items: [
    { message: 'Foo' },
    { message: 'Bar' }
  ],
}
mounted: function(){
  this.a = 2;
  this.e.f.g = 10;
  this.$set(this.items, 0, { message: 'AAA' });  // $set 賦值
  this.items[0] = { message: 'AAA' };  // 直接賦值
},
watch: {
  // 最簡單最直接的監(jiān)聽方式卵史,能監(jiān)聽簡單的數(shù)據(jù)變化战转,這種方法默認就是執(zhí)行 handler: function(){}
  // 注意:這種方式監(jiān)聽不到對象的變化
  a: function(val, oldVal){
    console.log(val);  // => 變化之后的數(shù)據(jù)
    console.log(oldVal); // => 變化之前的數(shù)據(jù)
  },
  // 深度監(jiān)聽,這里要注意一下以躯,這樣的方式打印出來兩個值都是變化之后的值
  // deep 的值默認為false槐秧,如果不寫或者deep: false 都不能監(jiān)聽到對象值的變化
  e: {
    handler: function (val, oldVal) {
      console.log(val);  // => 變化之后的數(shù)據(jù)
      console.log(oldVal);  // => 變化之后的數(shù)據(jù)
    },
    deep: true, 
  },
  // 如果要精準監(jiān)聽的對象值的變化,可以用這種方法
  'e.f.g': function (val, oldVal) {
    console.log(val);  // => 變化之后的數(shù)據(jù)
    console.log(oldVal);  // => 變化之前的數(shù)據(jù)
  },
  // 監(jiān)聽數(shù)組
  // 由于 JavaScript 的限制忧设,Vue 不能檢測 this.items[0] = { message: 'AAA' }; 這種方式賦值的變化
  // 所以你要用 $set刁标、或者數(shù)組變異的方法賦值
  items: function(val, oldVal){
    console.log(val);  // => 變化之后的數(shù)據(jù)
    console.log(oldVal);  // => 變化之后的數(shù)據(jù)
  },
}

Vue 數(shù)組更新檢測

官網的介紹:由于 JavaScript 的限制,Vue 不能檢測以下變動的數(shù)組
換句話來說:這樣賦值不觸發(fā)視圖更新

  • 1址晕、當你利用索引直接設置一個項時膀懈,例如:
this.items[indexOfItem] = newValue  // indexOfItem 是指數(shù)組的index 下標
  • 2、當你修改數(shù)組的長度時谨垃,例如:
this.items.length = newLength

要解決上面問題启搂,你可以用以下方式解決:

1、Vue.set( target, key, value) 刘陶,set方法有下面3個參數(shù)
  • {Object | Array} target -- 給誰設置值(對象胳赌,數(shù)組)都可以
  • {string | number} key -- 給對象設值,key 就是對象的key匙隔,給數(shù)組設值疑苫,key 就是數(shù)組的下標 index
  • {any} value -- 添加任何值都可以
2、數(shù)組變異的方式

push():將一個或多個元素添加到數(shù)組的末尾,并返回新數(shù)組的長度缀匕。
pop():從數(shù)組中刪除最后一個元素纳决,并返回該元素的值碰逸。此方法更改數(shù)組的長度乡小。
shift():從數(shù)組中刪除第一個元素,并返回該元素的值饵史。
unshift():將一個或多個元素添加到數(shù)組的開頭满钟,并返回新數(shù)組的長度。
splice():通過刪除現(xiàn)有元素和/或添加新元素來更改一個數(shù)組的內容胳喷。
sort():用就地( in-place )的算法對數(shù)組的元素進行排序湃番,并返回數(shù)組。 sort 排序不一定是穩(wěn)定的吭露。默認排序順序是根據(jù)字符串Unicode碼點吠撮。
reverse():將數(shù)組中元素的位置顛倒。

六讲竿、Vue 組件

Vue 組件基礎

組件是可復用的 Vue 實例泥兰,所以它們與 new Vue 接收相同的選項,例如 data题禀、computed鞋诗、watch、methods 以及生命周期鉤子等迈嘹。
注意:組件沒有 el 這樣根實例特有的選項削彬;而根實例沒有 props 這個子組件特有的屬性

  • Vue.component( 組件名 ,{ 選項 }) 全局注冊
// 全局注冊組件的時候必須寫在Vue實例創(chuàng)建之前
// 下面這幾種方式是等價的
import Vue from 'vue'
var MyComponent = Vue.extend({
  template:"<h1>我是全局組件</h1>"
});
Vue.component("my-component",MyComponent);

// 注冊組件,傳入一個擴展過的構造器
Vue.component('my-component', Vue.extend({ /* ... */ }))

// 注冊組件秀仲,傳入一個選項對象 (自動調用 Vue.extend)
Vue.component('my-component', { /* ... */ })
  • 通常情況下一個組件肯定是由很多html標簽組成的融痛,如果全部寫在template 里會非常難看且沒有語法高亮提示,有沒有其他解決辦法神僵?還真有
// 一個定義模板的方式是在一個 <script> 元素中酌心,并為其帶上 text/x-template 的類型,然后通過一個 id 將模板引用過去挑豌。
<script type="text/x-template" id="hello-world-template">
  <p>Hello hello hello</p>
</script>

// 另一個定義模板的方式是在一個 <template> 元素中安券,通過一個 id 將模板引用過去;在單文件組件 .vue 當中氓英,id可以省略侯勉;
<template id="hello-world-template">
  <p>Hello hello hello</p>
</template>

Vue.component("my-component",{
    template:"#hello-world-template"
});
  • 引入外部單文件組件注冊成全局組件
// .vue 
// 在單文件組件中 template 標簽下只能有一個根元素
// 如果硬要有多個根元素,你只能在多個根元素中添加 v-if铝阐、v-else-if址貌、v-else 來判斷什么時候用哪個根元素
<template>
  <div class="home">
    <p>{{getting}}</p>
  </div>
  <!-- <p>這樣是不行的</p> -->
</template>
<script>
  export default {
    name: "home",  // 便于在vue-devtools 調試中提供更加友好的警告信息
    data: function () {
      return {
        getting: 'welcome'
      }
    }
  }
</script>
<style scoped>
// 局部css樣式
</style>
// main.js
import home from './components/home/home'
Vue.component('home',home);
  • 局部注冊組件
// 每個vue 實例都會有一個 components 的選項,而組件是可復用的 Vue 實例,所以每個組件都有components 選項
// 引入外部文件注冊成局部組件
import home from './components/home/home'
new Vue({
  el:"#app",
  components: {
    home, // 等價于home: home练对,ES6對象中屬性的簡潔表示遍蟋,ES6(http://es6.ruanyifeng.com/#docs/object)
  }
});
// 直接在components 選項中寫,(不推薦這種用法)
new Vue({
  el:"#app",
  components: {
    loading: {
      data: function () {
        return {
          getting: 'welcome'
        }
      },
      components:{
       // 這里還可以嵌套局部組件... 
      }
    }
  }
});
  • 組件間的傳值

通過 Prop 向子組件傳遞數(shù)據(jù)

// HTML 中的特性名是大小寫不敏感的,所以瀏覽器會把所有大寫字符解釋為小寫字符螺男。
// 這意味著當你使用 DOM 中的模板時棒厘,駝峰命名法的 prop 名需要使用其等價的 短橫線分隔命名命名。
// 如果使用字符串模板下隧,那么這個限制就不存在了奢人。
Vue.component('my-component', {
  props: ['myTitle'],
  template: '<h3>{{ myTitle}}</h3>'
})

// HTML
<my-component my-title='hello world'></my-component>
// 上述例子只是一個靜態(tài)數(shù)據(jù)傳輸,如果你要動態(tài)傳輸數(shù)據(jù)淆院,可以用 v-bind 綁定一個屬性
// 也可以用v-bind 的縮寫形式
<my-component v-bind:my-title='hello world'></my-component> 
// 任何類型的值都可以傳遞給 prop何乎,prop 允許很多個
// 如果你想要將一個對象的所有屬性都作為 prop 傳入,你可以使用不帶參數(shù)的 v-bind土辩,如:
obj: {
  id: 1,
  title: 'Hello World'
}
<my-component v-bind='obj'></my-component>
// 等價于:
<my-component 
  v-bind:id='obj.id'
  v-bind:title='obj.title'
></my-component>

Prop 還提供驗證的方式指定傳什么值

Vue.component('my-component', {
  props: {
    // 基礎的類型檢查 (`null` 匹配任何類型)
    propA: Number,
    // 多個可能的類型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 帶有默認值的數(shù)字
    propD: {
      type: Number,
      default: 100
    },
    // 帶有默認值的對象
    propE: {
      type: Object,
      // 對象或數(shù)組且一定會從一個工廠函數(shù)返回默認值
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定義驗證函數(shù)
    propF: {
      validator: function (value) {
        // 這個值必須匹配下列字符串中的一個
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

既然 prop 的單向的支救,那如果子組件向父組件傳值怎么辦?

// 子組件,子組件可以通過$emit() 廣播一個事件給父組件
// 命名的這個事件名沒有限制搂妻,子組件與父組件的名字保持一致就可以了
<button v-on:click="$emit('broadcast')">向父組件廣播這個事件</button>

// $emit() 這個方法也可以寫在 子組件的 methods 里面
<button v-on:click="broadcast">向父組件廣播這個事件</button>
methods: {
  broadcast(){
    this.$emit('broadcast')
    // 如果要傳值,就使用$emit(事件名, 值) 的第二個參數(shù)
    this.$emit('broadcast', value)
  }
} 
// 在父組件中辕棚,父組件可以用 v-on 監(jiān)聽子組件觸發(fā)的 `broadcast` 事件欲主,類似監(jiān)聽Dom 事件一樣的用法
<my-component v-on:broadcast='catchYou'></my-component>
methods: {
  catchYou(val){
    // 子組件傳過來的值就會作為第一個參數(shù)傳入這個方法 
    console.log(val)
  }
} 
// 在組件的表達式里面,你可以通過$event 訪問到子組件傳遞過來的值
<my-component v-on:broadcast='$event'></my-component>

七扁瓢、vue-router

  • 貼一段 app 構建的案例琼娘。官網API 點這里
<!-- 這里我讓 app.vue作為最大的渲染層鞠值,渲染tabs -->
<!-- 這里我模擬的是一個商場app,下面幾個tab嘱丢;點擊`tab`直接渲染在`tabs`的<router-view></router-view>上 -->
<!-- tabs 之外的頁面直接渲染在app.vue 的<router-view></router-view>上 -->
<!--  app.vue -->
<div id="app">
  <router-view></router-view>
</div>

<!-- tabs.vue -->
<div class="tabs">
  <router-view></router-view>
  <nav class="nav">
    <router-link class="nav-link" to="home">
      <i></i>
      <p>首頁</p>
    </router-link>
  <nav>
</div>
// 以下一些配置是簡單要用到的挽铁,高級的用法請看官網
// router.js
import tabs from './components/tabs/tabs'
import home from './components/home/home'
const router =  new VueRouter({
  mode: 'history',  // 可選值: "hash" 伟桅、 "history" 、 "abstract" 
  linkActiveClass: 'active',  // 默認值: "router-link-active" 全局配置 <router-link> 的默認『激活 class 類名』
  routes: [
    {
      path: "/tabs",    // 指向的路徑
      name: "tabs",   // 命名路由叽掘,可以通過這個名稱跳轉到這個組件
      component: tabs, // 指向路徑加載的組件
      children: [  // 嵌套路由也有跟父級一樣的選項
        {
          path:"home",
          name: "home",
          component: home, 
        }
      ]
    },
    {
      path: '/',
      redirect: '/tabs/home'   // 重定向楣铁,即無目標地址的時候轉到這個路徑
    }
  ]
});
export default router;
// main.js
import router from './router.js'
new Vue({
  router,
  render: h => h(App)
}).$mount('#app');
<!-- 字符串模式,可以說是靜態(tài)模式更扁,不用v-bind -->
<router-link to="home">Home</router-link>

<!-- 下面幾種是動態(tài)模式 -->
<!-- 使用 v-bind 的 JS 表達式 -->
<router-link v-bind:to="'home'">Home</router-link>

<!-- 不寫 v-bind 也可以盖腕,就像綁定別的屬性一樣 -->
<router-link :to="'home'">Home</router-link>

<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 跳轉到命名的路由 -->
<!-- 這里有需要注意的地方是赫冬,如果路由有傳值,那這里的params 就不能省略-->
<router-link :to="{ name: 'user' , params: { userId }}">User</router-link>
  • router 傳值的幾種方式
    注意:如果提供了 path溃列,params 會被忽略劲厌,取而代之的是提供路由的 name 或手寫完整的帶有參數(shù)的 path,同樣的規(guī)則也適用于 router-link 組件的 to 屬性
  • 另外的傳參方式听隐,有興趣可以了解一下 props
// 在函數(shù)里面
this.$router.push({ name: 'user', params: { userId }})
this.$router.push({ path: `/user/${userId}` })  // `${ }` 是ES6 的模板字符串概念补鼻,標識符是 ` `
// 這里的 params 不生效
this.$router.push({ path: '/user', params: { userId }})
// router-link 傳值
<router-link :to="{ name: 'user',params: { userId } }">User</router-link>
<router-link :to="{ path: `/user/${userId}` }">User</router-link>
// 這里的 params 不生效
<router-link :to="{ path: '/user', params: { userId }}">User</router-link>
  • 目標組件取值
    這里要很小心,是 this.$route遵绰,不是 this.$router辽幌,沒有 r 的
// 使用這種方式獲取路由傳過來的值
this.$route.params.userId
  • 路由的命名視圖增淹,這里貼的是官網的例子椿访,官網API 點這里
<!-- html -->
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
// js
const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: { // 這里的 `components` 要跟上面的 `component` 區(qū)分一下,有多個視圖渲染的時候有 `s`虑润,別漏了
        default: Foo,  // 這是默認指定的 Foo 這個組件成玫,也就是在沒有命名的<router-view>上渲染
        a: Bar,  // 這里一一對應有 name 屬性的<router-view>就可以了
        b: Baz
      }
    }
  ]
})
  • 幾種導航的方法,官網 點這里
    下面幾種方法跟 window.history 的幾種方法很像拳喻,其實就是仿照 window.history
// 往路由歷史新增一條記錄哭当,相關參數(shù)參考官網
this.$router.push(location, onComplete?, onAbort?)

// 替換掉當前的記錄
this.$router.replace(location, onComplete?, onAbort?)

// 在瀏覽器記錄中前進一步,等同于 this.$router.forward()
this.$router.go(1)
this.$router.forward()

// 后退一步記錄冗澈,等同于 this.$router.back()
this.$router.go(-1)
this.$router.back()

// 前進 3 步記錄
this.$router.go(3)

// 如果 history 記錄不夠用钦勘,那就默默地失敗唄
this.$router.go(-100)
this.$router.go(100)
  • 路由跳轉的時候支持過度動效,感興趣可以去玩一下亚亲,官網 點這里 (還有其他更加高級的用法要靠自己去查閱了)

八彻采、axios

axios 英文文檔
axios 中文文檔 — 對英文文檔的翻譯
axios 是基于 ES6 的 Promise 寫的,具體可以看 Promise 相關說明

// npm 安裝
npm i axiso  // 等價于 npm install axios 捌归,i 是 install 的簡寫 

axios 的一些簡單用法

// GET 請求
// 為給定 ID 的 user 創(chuàng)建請求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// 上面的請求可以這樣做
axios.get('/user', {
  params: {
    ID: 12345
  }
})
.then(function (response) {
  console.log(response);
})
.catch(function (error) {
  console.log(error);
});
// POST 請求
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
//  執(zhí)行多個并發(fā)請求
function getUserAccount() {
  return axios.get('/user/12345');
}
function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}
// 這兩個方法返回的都是 Promise 對象肛响,這兩個請求方法都成功返回的時候,下面方法才返回成功惜索。
// 這兩個方法中有一個返回不成功就算返回失敗 
axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 兩個請求現(xiàn)在都執(zhí)行完成
  }));

通過向 axios 傳遞相關配置來創(chuàng)建請求

  • axios(config)
// 發(fā)送 POST 請求
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

  • axios(url[, config])
// 發(fā)送 GET 請求(默認的方法)
axios('/user/12345');

為方便特笋,axios 還為支持的請求方法提供了別名,如:
注意:在使用別名方法時巾兆, url猎物、methoddata 這些屬性都不必在配置中指定角塑。

  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])

處理并發(fā)請求的助手函數(shù)

  • axios.all(iterable)
  • axios.spread(callback)

還有其他高級用法蔫磨,具體請查閱官網 axios 英文文檔

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吉拳,隨后出現(xiàn)的幾起案子质帅,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件煤惩,死亡現(xiàn)場離奇詭異嫉嘀,居然都是意外死亡,警方通過查閱死者的電腦和手機魄揉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門剪侮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洛退,你說我怎么就攤上這事瓣俯。” “怎么了兵怯?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵彩匕,是天一觀的道長。 經常有香客問我媒区,道長驼仪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任袜漩,我火速辦了婚禮绪爸,結果婚禮上,老公的妹妹穿的比我還像新娘宙攻。我一直安慰自己奠货,他們只是感情好,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布座掘。 她就那樣靜靜地躺著递惋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雹顺。 梳的紋絲不亂的頭發(fā)上丹墨,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機與錄音嬉愧,去河邊找鬼贩挣。 笑死,一個胖子當著我的面吹牛没酣,可吹牛的內容都是我干的王财。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼裕便,長吁一口氣:“原來是場噩夢啊……” “哼绒净!你這毒婦竟也來了?” 一聲冷哼從身側響起偿衰,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤挂疆,失蹤者是張志新(化名)和其女友劉穎改览,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缤言,經...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡宝当,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了胆萧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庆揩。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖跌穗,靈堂內的尸體忽然破棺而出订晌,到底是詐尸還是另有隱情,我是刑警寧澤蚌吸,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布锈拨,位于F島的核電站,受9級特大地震影響套利,放射性物質發(fā)生泄漏推励。R本人自食惡果不足惜鹤耍,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一肉迫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧稿黄,春花似錦喊衫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至陵珍,卻和暖如春寝杖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背互纯。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工瑟幕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人留潦。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓只盹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親兔院。 傳聞我的和親對象是個殘疾皇子殖卑,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內容

  • 響應式布局的理解 響應式開發(fā)目的是一套代碼可以在多種終端運行,適應不同屏幕的大小,其原理是運用媒體查詢,在不同屏幕...
    懶貓_6500閱讀 790評論 0 0
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內容,還有我對于 Vue 1.0 印象不深的內容坊萝。關于...
    云之外閱讀 5,052評論 0 29
  • vue-cli搭建項目 確保安裝了node與npm 再目標文件夾下打開終端 執(zhí)行cnpm i vue-cli -g...
    Akiko_秋子閱讀 3,243評論 1 22
  • 比較喜歡走路孵稽,一個人走在路上许起,可以什么都不想,可以什么都想菩鲜,讓思緒隨著腳下的塵土飛揚…… 兩個人散散步街氢、聊聊天,看...
    每日正能量閱讀 181評論 0 0
  • 掌柜前言: 你好睦袖,感謝你選擇購買小米平板2珊肃。小米的產品是一如既往的性價比與實用。而了解與學習使用以下的方法能讓你更...
    賣點兒什么閱讀 1,630評論 0 0