Vue學(xué)習(xí)分享

介紹:Vue起初是一個構(gòu)建數(shù)據(jù)驅(qū)動的web界面的庫诡挂,通過簡單的API提供高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng),但隨著vue生態(tài)圈的發(fā)展临谱,如vue-router璃俗,vue-resource等的推出,vue已經(jīng)算得上是個輕量級的MVVM框架了悉默,官方定義vue是一套用于構(gòu)建用戶界面的漸進(jìn)式框架城豁。相較于Angular和React框架,vue的的學(xué)習(xí)曲線更平穩(wěn)抄课,這點也是我選擇Vue入門的原因唱星。

如何安裝?

  • 直接HTML引入 script
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  • vue cli方式
$ npm install vue

Vue的核心思想

vue.jpg
  • 數(shù)據(jù)驅(qū)動

DOM是數(shù)據(jù)的一種自然映射跟磨,手動操作DOM是一件非常繁索且容易出錯的事情间聊,而使用vue.js后,就省去了手動操作DOM的步驟抵拘,在Vue.js里我們只需要操作數(shù)據(jù)哎榴,vue會通過Directives指令去修改對應(yīng)的DOM,從而實現(xiàn)數(shù)據(jù)驅(qū)動。

  • 組件化

組件化的目的是擴(kuò)展HTML元素叹话,封裝可重用代碼

通過上圖偷遗,我們可以粗略理解為一個簡單的vue應(yīng)用大概先分兩部分:Vue實例、 HTML

第一部分 : vue實例

每個 Vue 應(yīng)用都是通過創(chuàng)建一個新的 Vue 實例開始驼壶,語法如下:

var vm = new Vue({
  // 選項
})

構(gòu)造器的常用參數(shù)屬性包含:el氏豌、datamethods热凹、computed泵喘、watch生命周期鉤子等般妙,具體應(yīng)用如下:

  • el:提供一個在頁面上已存在的 DOM 元素作為 Vue 實例的掛載目標(biāo)纪铺,在vue單文件情況下不需要該屬性
#掛載到id為app的DOM節(jié)點上
el: '#app'
  • data: 用于定義數(shù)據(jù)屬性,當(dāng) Vue 實例被創(chuàng)建時碟渺,它向 Vue 的響應(yīng)式系統(tǒng)加入了 data 對象中所有的屬性鲜锚。當(dāng)這些屬性的值變化時,HTML 視圖將也會產(chǎn)生相應(yīng)的變化苫拍。
# 實例創(chuàng)建之后,可通過 vm.$data 訪問原始數(shù)據(jù)對象骏令。Vue 實例也代理了 data 對象上所有的屬性垄提,因此訪問 vm.a 等價于訪問 vm.$data.a榔袋。
data: {
  newTodoText: '',
  visitCount: 0,
  hideCompletedTodos: false,
  todos: [],
  error: null
}
  • methods:用于定義的函數(shù)铡俐,通過 return 來返回函數(shù)值。
// 在組件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}
  • computed 用于計算屬性审丘,當(dāng)模板中的邏輯復(fù)雜時聪黎,代碼非常難以看懂理解备恤,可考慮把邏輯寫在computed中露泊,我們用 methods 替代 computed惭笑,效果一樣,但 computed 基于它的依賴緩存捺宗,只有相關(guān)依賴發(fā)生改變時才會重新取值蚜厉。而使用 methods 畜眨,在重新渲染的時候康聂,函數(shù)總會重新調(diào)用執(zhí)行恬汁∶ゲ啵可以說 computed 性能會更好甘苍,除非你不希望緩存。
computed: {
    // 計算屬性的 getter
    reversedMessage: function () {
      // `this` 指向 vue 實例
      return this.message.split('').reverse().join('')
    }
  }
  • watch 監(jiān)聽屬性來響應(yīng)數(shù)據(jù)的變化看彼,當(dāng)我們再輸入框輸入數(shù)據(jù)時靖榕,watch 會實時監(jiān)聽數(shù)據(jù)變化并改變自身的值茁计。
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})
  • vue實例還有一系列的生命周期鉤子星压,給了用戶在不同階段添加自己的代碼的機(jī)會娜膘。
    • beforeCreate 在實例初始化之后調(diào)用
    • created 在實例創(chuàng)建完成后被立即調(diào)用
    • beforemount 在掛載開始之前被調(diào)用
    • mounted 實例被掛載后調(diào)用
    • beforeupdate 數(shù)據(jù)更新時調(diào)用
    • updated 由于數(shù)據(jù)更改導(dǎo)致的虛擬 DOM 重新渲染和打補(bǔ)丁竣贪,在這之后會調(diào)用該鉤子
    • beforeDesgroy 實例銷毀之前調(diào)用
    • destroyed 實例銷毀后調(diào)用
new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vue 實例
    console.log('a is: ' + this.a)
  },
  beforeCreate: function () {
    console.log('beforeCreate')
  }
})

備注:

  • 不要在選項屬性或回調(diào)上使用箭頭函數(shù)演怎,比如 created: () => console.log(this.a)爷耀,因為箭頭函數(shù)并沒有 this
  • 當(dāng)這些數(shù)據(jù)改變時畏纲,視圖會進(jìn)行重渲染。但只有當(dāng)實例被創(chuàng)建時就已經(jīng)存在于 data 中的屬性才是響應(yīng)式的艘蹋;
  • Vue實例針對數(shù)據(jù)女阀、DOM浸策、資源庸汗、組合等都有非常多靈活的屬性蚯舱,具體可查看官方API

第二部分 : HTML

vue實例承載了數(shù)據(jù)和邏輯相關(guān)的內(nèi)容枉昏,那么HTML就是處理我們view相關(guān)內(nèi)容了兄裂,Vue.js 使用了基于 HTML 的模板語法晰奖,允許開發(fā)者聲明式地將 DOM 綁定至底層 Vue 實例的數(shù)據(jù)腥泥。

插值表達(dá)式

數(shù)據(jù)綁定最常見的形式就是使用“Mustache”語法 (雙大括號)

# 基本形式 道川,無論何時冒萄,綁定的數(shù)據(jù)對象上 value 屬性發(fā)生了改變尊流,插值處的內(nèi)容都會更新
{{ value }}
# 只需渲染一次數(shù)據(jù)
{{ *value }}
#可放在HTML標(biāo)簽內(nèi)
<li data-id='{{id}}'></li>
# 表達(dá)式
{{ number / 100 }}
{{ true ? 1 : 0 }}
{{ example.split(",") }}

# Q录肌迎献!錯誤示例(語句并非表達(dá)式吁恍,條件控件語句也是不支持的)
{{var logo = 'DDEF'}}
{{if (true) return 'DDEF'}}

# 過濾器:
{{ date | formateDate }}
{{ example | toUpperCase}}
指令

指令 (Directives) 是帶有 v- 前綴的特殊 attribute冀瓦。指令的職責(zé)是當(dāng)表達(dá)式的值改變時翼闽,將其產(chǎn)生的連帶影響感局,響應(yīng)式地作用于 DOM。包含v-text玄叠、v-html读恃、v-show寺惫、v-if西雀、v-else艇肴、v-else-if再悼、v-for冲九、v-on莺奸、v-bind灭贷、v-model氧腰、v-slotv-pre箩帚、v-cloakv-once是嗜,在實際開發(fā)中應(yīng)用非常頻繁鹅搪,下面我們來詳細(xì)聊聊它們的用法遭铺。
v-bind : 動態(tài)地綁定一個或多個特性魂挂,或一個組件 prop 到表達(dá)式坠非。

<!-- 完整語法 -->
<a v-bind:href="url"></a>
<!-- 縮寫 -->
<a :href="url"></a>
<!-- 內(nèi)聯(lián)字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- 可用于綁定元素 attribute炎码,響應(yīng)地更新 HTML 屬性:-->
<div v-bind:id="dynamicId"></div>
<div v-bind:id="'list-' + id"></div>
<a v-bind:href="url">8891汽車</a>

<!-- 也可以用于綁定樣式:-->
<div v-bind:class="{ active: isActive }"></div>
<div v-bind:class="[ activeClass, errorClass ]"></div>
<div v-bind:class="[ errorClass ,isActive ? activeClass : '' ]"></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>

<!--修飾符-->
<svg :view-box.camel="viewBox"></svg>
<!-- 通過 prop 修飾符綁定 DOM 屬性 -->
<div v-bind:text-content.prop="text"></div>
<!--.sync修飾符會擴(kuò)展成一個更新父組件綁定值的 v-on 偵聽器辅肾。-->
<text-document v-bind:title.sync="doc.title"></text-document>

v-show 根據(jù)表達(dá)式之真假值矫钓,切換元素的 display CSS 屬性

<!--根據(jù)表達(dá)式的值來顯示或隱藏HTML元素-->
<!--元素始終被編譯新娜,只是簡單地基于CSS切換概龄,相比v-if有更高的初始渲染消耗-->
<h1 v-show="ok">Hello!</h1>

v-if 條件判斷私杜,根據(jù)表達(dá)式的值在DOM中生成或移除一個元素

<!--v-if  條件語句-->
<p v-if="seen">現(xiàn)在你看到我了</p>
<!--v-else-->
<div v-if="Math.random() > 0.5"> Now you see me </div>
<div v-else> Now you don't </div>
<!--v-else-if-->
<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-if 是惰性的,在條件第一次變?yōu)檎鏁r才開始局部編譯铝耻,否則什么都不做 . 相比v-show有更高的切換消耗 -->

v-for 循環(huán)語句 :

<!--遍歷數(shù)組瓢捉,其中 items 是源數(shù)據(jù)數(shù)組泡态,而 item 則是被迭代的數(shù)組元素的別名-->
<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>
<!-- 可選的第二參數(shù)某弦,索引-->
<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>

<!--遍歷對象-->
<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
<!--可選的第二參數(shù)刀崖,鍵名-->
<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>
<!--可選的第三參數(shù)亮钦,索引-->
<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>
<!--為了給 Vue 一個提示蜂莉,以便它能跟蹤每個節(jié)點的身份映穗,從而重用和重新排序現(xiàn)有元素蚁滋,需為每項提供一個唯一 key 屬性-->
<div v-for="item in items" v-bind:key="item.id">
  {{ item.message }}
</div>
<!--v-for里還可以使用值范圍-->
<div>
  <span v-for="n in 10">{{ n }} </span>
</div>
#VUE實例部分
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ],
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})

備注:當(dāng)數(shù)組出現(xiàn)變動時睦霎,Vue是如何檢測呢副女?Vue 將被偵聽的數(shù)組的變異方法進(jìn)行了封裝碑幅,它們能觸發(fā)實圖更新沟涨。所以建議盡量避免直接設(shè)置數(shù)據(jù)綁定的數(shù)組元素拷窜,因為這些變化不會被vue.js檢測到篮昧,這些被封裝過的方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

相比之下懊昨,也有非變異 (non-mutating method) 方法酵颁,它們不會改變原始數(shù)組躏惋,而總是返回一個新數(shù)組簿姨。

  • filter()
  • concat()
  • slice()

v-on : 用于監(jiān)聽 DOM 事件准潭,并在觸發(fā)時運(yùn)行一些 JavaScript 代碼

<!-- `greet` 是在vue實例中定義的方法名 -->
<div id="example-2">
 <button v-on:click="greet">Greet</button>
</div>

<!--內(nèi)聯(lián)處理器的方法-->
<div id="example-3">
 <button v-on:click="say('hi')">Say hi</button>
 <button v-on:click="say('what')">Say what</button>
</div>


<!--事件修飾符-->
<!-- 阻止單擊事件繼續(xù)傳播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修飾符可以串聯(lián) -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>
<!-- 點擊事件將只會觸發(fā)一次 -->
<a v-on:click.once="doThis"></a>


<!-- 按鍵修飾符 -->
<!-- 按鍵修飾符刑然,只有在 `key` 是 `Enter` 時調(diào)用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<input v-on:keyup.13="submit">

Vue.js 為 v-on 提供了事件修飾符泼掠。之前提過,修飾符是由點開頭的指令后綴來表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive

為了在必要的情況下支持舊瀏覽器叹谁,Vue 提供了絕大多數(shù)常用的按鍵碼的別名:

  • .enter
  • .tab
  • .delete (捕獲“刪除”和“退格”鍵)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

v-model : 用來在 input焰檩、select析苫、textarea衩侥、checkbox茫死、radio 等表單控件元素上創(chuàng)建雙向數(shù)據(jù)綁定履羞,根據(jù)表單上的值爱榔,自動更新綁定的元素的值详幽。

<!--指令用來在 input妒潭、select雳灾、textarea谎亩、checkbox匈庭、radio 等表單控件元素上創(chuàng)建雙向數(shù)據(jù)綁定阱持,根據(jù)表單上的值鸽扁,自動更新綁定的元素的值桶现。-->
<input v-model="message" >
<textarea v-model="message" placeholder="add multiple lines"></textarea>
<!--單復(fù)選框-->
<input type="checkbox" id="checkbox" v-model="checked">
<!--多復(fù)選框 骡和,綁定到數(shù)組 data: {checkedNames: []}-->
<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
</div>
<!--單選框,綁定到 data: {picked: ''}-->
<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
</div>
<!--選擇框东囚,綁定到 data: {selected: ''}-->
<div id="example-5">
  <select v-model="selected">
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
  </select>
</div>
<!--多選選擇框,綁定到數(shù)組 data: {selected: []}-->
<div id="example-6">
  <select v-model="selected" multiple style="width: 50px;">
    <option>A</option>
    <option>B</option>
  </select>
</div>

<!--v-model指令后份帐,可添加多個參數(shù)(number废境、lazy噩凹、trim)-->
<input v-model.number="age" type="number">
<input v-model.lazy="msg" >
<input v-model.trim="msg">

v-slot: 插槽驮宴,主要用于內(nèi)容分發(fā)修己,插槽內(nèi)可以包含任何模板代碼睬愤,包括 HTML尤辱、其它組件等

<navigation-link url="/profile">
  Your Profile
</navigation-link>

<!--然后你在 `<navigation-link>` 的模板中可能會寫為-->
<a v-bind:href="url" class="nav-link">
  <!--當(dāng)組件渲染的時候啥刻,<slot></slot> 將會被替換為“Your Profile”娄涩。-->
  <slot></slot>
</a>

<!--插槽內(nèi)可以包含任何模板代碼蓄拣,包括 HTML球恤、其它組件-->
<navigation-link url="/profile">
  <!-- 添加一個 Font Awesome 圖標(biāo) (模板代碼)-->
  <span class="fa fa-user"></span> 
  <!-- 添加一個圖標(biāo)的組件 -->
  <font-awesome-icon name="user"></font-awesome-icon>
  Your Profile
</navigation-link>

v-text: 用于更新元素的 textContent

<span v-text="msg"></span>
<!--等價 -->
<span>{{msg}}</span>

v-html : 用于更新元素的 innerHTML

<!--更新元素的 innerHTML,在網(wǎng)站上動態(tài)渲染任意 HTML 是非常危險的堪置,容易導(dǎo)致XSS攻擊。只在可信內(nèi)容上使用 `v-html`张惹,永不用在用戶提交的內(nèi)容上舀锨。-->
<div v-html="html"></div>

v-pre: 用于跳過這個元素和它的子元素的編譯過程⊥鸲海可以用來顯示原始 Mustache 標(biāo)簽

<!--跳過這個元素和它的子元素的編譯過程坎匿。可以用來顯示原始 Mustache 標(biāo)簽。-->
<span v-pre>{{ this will not be compiled }}</span>

v-once : 只渲染元素和組件一次告私。

<span v-once>這個將不會改變: {{ msg }}</span>

指令會在寫HTML時大量應(yīng)用到,特別是表單處理等承桥,建議多加練習(xí)驻粟。

組件

組件化的目的是擴(kuò)展HTML元素,封裝可重用代碼快毛;組件其實是可復(fù)用的 Vue 實例

基礎(chǔ)用法 格嗅,組件注冊 - 全局注冊:

// 定義名為 todo-item 的新組件
Vue.component('todo-item', {
  template: '<li>這是組件內(nèi)容</li>',
})

var app = new Vue(...)
<ol>
  <!-- 創(chuàng)建一個 todo-item 組件的實例 -->
  <todo-item></todo-item>
</ol>

組件注冊 - 局部注冊:

var ComponentA = {
  template:'<div>局部注冊組件的內(nèi)容</div>'
}

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
  }
})
#局部注冊的組件在其子組件中不可用。例如唠帝,如果你希望 ComponentA 在 ComponentB 中可用屯掖,則你需要這樣寫:
var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}

在模塊系統(tǒng)中局部注冊

#這樣 ComponentA 和 ComponentC 都可以在 ComponentB 的模板中使用了
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'

export default {
  components: {
    ComponentA,
    ComponentC
  },
  // ...
}
組件-數(shù)據(jù)傳遞:

props:props 可以是數(shù)組或?qū)ο螅糜诮邮諄碜愿附M件的數(shù)據(jù)襟衰。

  • 數(shù)組模式
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
  • 對象模式
//若想每個prop 都指定的值類型贴铜。可以用對象形式列出prop瀑晒,屬性的名稱和值分別是prop 各自的名稱和類型
props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}
  • Prop 驗證 绍坝,我們可為組件的 prop 指定驗證要求,例如你知道的這些類型苔悦。如果有一個需求沒有被滿足轩褐,則 Vue 會在瀏覽器控制臺中警告你。
Vue.component('my-component', {
  props: {
    // 基礎(chǔ)的類型檢查 (`null` 和 `undefined` 會通過任何類型驗證)
    propA: Number,
    // 多個可能的類型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 帶有默認(rèn)值的數(shù)字
    propD: {
      type: Number,
      default: 100
    },
    // 帶有默認(rèn)值的對象
    propE: {
      type: Object,
      // 對象或數(shù)組默認(rèn)值必須從一個工廠函數(shù)獲取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定義驗證函數(shù)
    propF: {
      validator: function (value) {
        // 這個值必須匹配下列字符串中的一個
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

類型檢查 : type 可以是下列原生構(gòu)造函數(shù)中的一個:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

給 prop 傳入數(shù)據(jù) - 示例:

<!--傳入一個靜態(tài)的值-->
<blog-post title="My journey with Vue"></blog-post>
<!--通過 v-bind 動態(tài)賦值-->
<blog-post v-bind:title="post.title"></blog-post>
<!-- 傳入數(shù)字玖详,這是一個 JavaScript 表達(dá)式而不是一個字符串-->
<blog-post v-bind:likes="42"></blog-post>
<!-- 傳入布爾值把介,包含該 prop 沒有值的情況在內(nèi),都意味著 `true`蟋座。-->
<blog-post is-published></blog-post>
<!--即便 `false` 是靜態(tài)的拗踢,我們?nèi)匀恍枰?`v-bind` 來告訴 Vue-->
<blog-post v-bind:is-published="false"></blog-post>
<!-- 用一個變量進(jìn)行動態(tài)賦值。-->
<blog-post v-bind:is-published="post.isPublished"></blog-post>
<!-- 傳入數(shù)組向臀,即便數(shù)組是靜態(tài)的巢墅,我們?nèi)匀恍枰?`v-bind` 來告訴 Vue-->
<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>
<!-- 傳入對象,即便對象是靜態(tài)的券膀,我們?nèi)匀恍枰?`v-bind` 來告訴 Vue -->
<blog-post
  v-bind:author="{
    name: 'Veronica',
    company: 'Veridian Dynamics'
  }"
></blog-post>
<!--傳入對象所有屬性 post: {id: 1,title: 'kevin'}-->
<blog-post v-bind="post"></blog-post>
<!--等價于-->
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

組件中君纫,data必需是函數(shù),因為它是引用類型芹彬,如果繼續(xù)使用對象庵芭,則會在組件復(fù)用時相互影響:

# 一個組件的 data 選項必須是一個函數(shù),因此每個實例可以維護(hù)一份被返回對象的獨立的拷貝
data: function () {
  return {
    count: 0
  }
}
組件通信
  • 父傳子props

所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中雀监,但是反過來則不行双吆。這樣會防止從子組件意外改變父級組件的狀態(tài)眨唬,從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解。

  • 子傳父$emit好乐,可以使用 $emit 觸發(fā)父組件的自定義事件
// 父組件
Vue.component('parent', {
  template:`
    <div>
      <child :message="message" v-on:getChildData="getChildData"></child>
    </div>
  `,
  data() {
    return {
      message: 'hello'
    }
  },
  methods:{
    // 執(zhí)行子組件觸發(fā)的事件
    getChildData(val) {
      console.log(val);
    }
  }
});

// 子組件
Vue.component('child', {
  template:`
    <div>
      <input type="text" v-model="myMessage" @input="passData(myMessage)">
    </div>
  `,
  props:['message'], 
  data() {
    return {
      // 這里是必要的匾竿,因為你不能直接修改 props 的值
      myMessage: this.message
    }
  },
  methods:{
    passData(val) {
      // 數(shù)據(jù)狀態(tài)變化時觸發(fā)父組件中的事件
      this.$emit('getChildData', val);
    }
  }
});
    
var app=new Vue({
  el: '#app',
  template: `
    <div>
      <parent />
    </div>
  `
});

  • 非父子組件 : vuex,這部分暫時還沒深入學(xué)習(xí)蔚万,以后再展開詳解岭妖。

單文件組成

使用 Vue.componen 來定義全局組件,然后用 new Vue({ el: '#container '}) 在每個頁面內(nèi)指定一個容器元素反璃,在復(fù)雜的項目中會以下明顯缺點:

  • 全局定義 (Global definitions) : 強(qiáng)制要求每個 component 中的命名不得重復(fù)
  • 字符串模板 (String templates) : 缺乏語法高亮昵慌,在 HTML 有多行的時候,需要用到丑陋的 \
  • 不支持 CSS (No CSS support) : 當(dāng) HTML 和 JavaScript 組件化時淮蜈,CSS 明顯被遺漏
  • 沒有構(gòu)建步驟 (No build step) : 只能用 HTML 和 ES5 JavaScript斋攀,而不能使用預(yù)處理器,如Babel

針對以上缺點梧田,vue提供了文件擴(kuò)展名為 .vue 的 single-file components(單文件組件) 為以上所有問題提供了解決方法淳蔼,并且可以用 webpack 等構(gòu)建工具,好在vue提供了腳手架工具Vue CLI 官方地址

安裝Vue CLI

npm install -g @vue/cli
# OR
yarn global add @vue/cli
# 檢查其版本是否正確
vue --version

現(xiàn)在就可以通過Vue CLI創(chuàng)建工程裁眯,然后根據(jù)我們的需求配置并生成項目

vue create demo

# vue create 命令有一些可選項鹉梨,具體可查看
vue create --help
# 也能通過 vue ui 命令以圖形化界面創(chuàng)建和管理項目
vue ui

.vue文件結(jié)構(gòu)如下:

<template>...</template>
<script>...</script>
<style>...</style>

現(xiàn)在我們獲得:

  • 完整語法高亮
  • CommonJS 模塊
  • 組件作用域的 CSS

至此,VUE的一些基本用法都已經(jīng)有大概的了解穿稳,后面還有更多知識要學(xué)習(xí)存皂,比如前面工程化vue第三方庫等等逢艘。

vue生態(tài)之vue-router

Vue.js路由艰垂,允許我們通過不同的 URL 訪問不同的內(nèi)容,從而實現(xiàn)多視圖的單頁Web應(yīng)用
CDN方式

https://unpkg.com/vue-router/dist/vue-router.js

NPM方式安裝

cnpm install vue-router

vue-router應(yīng)用示例:<router-link> 是一個組件埋虹,該組件用于設(shè)置一個導(dǎo)航鏈接,切換不同 HTML 內(nèi)容娩怎。
to 屬性為目標(biāo)地址搔课, 即要顯示的內(nèi)容。

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
 
<div id="app">
  <p>
    <!-- <router-link> 默認(rèn)會被渲染成一個 `<a>` 標(biāo)簽 -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的組件將渲染在這里 -->
  <router-view></router-view>
</div>

JS部分

// 0. 如果使用模塊化機(jī)制編程截亦,導(dǎo)入 Vue 和 VueRouter爬泥,要調(diào)用 Vue.use(VueRouter)
 
// 1. 定義(路由)組件。
// 可以從其他文件 import 進(jìn)來
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
 
// 2. 定義路由
// 每個路由應(yīng)該映射一個組件崩瓤。 其中"component" 可以是通過 Vue.extend() 創(chuàng)建的組件構(gòu)造器袍啡,或者,只是一個組件配置對象却桶。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]
 
// 3. 創(chuàng)建 router 實例境输,然后傳 `routes` 配置
const router = new VueRouter({
  routes // (縮寫)相當(dāng)于 routes: routes
})
 
// 4. 創(chuàng)建和掛載根實例蔗牡。記得要通過 router 配置參數(shù)注入路由,從而讓整個應(yīng)用都有路由功能
const app = new Vue({
  router
}).$mount('#app')

<router-link> 相關(guān)屬性

to : 目標(biāo)路由的鏈接嗅剖。 當(dāng)被點擊后辩越,內(nèi)部會立刻把 to 的值傳到 router.push(),所以這個值可以是一個字符串或者是描述目標(biāo)位置的對象信粮。

<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染結(jié)果 -->
<a href="home">Home</a>

<!-- 使用 v-bind 的 JS 表達(dá)式 黔攒; 不寫 v-bind 也可以,就像綁定別的屬性一樣-->
<router-link v-bind:to="'home'">Home</router-link>
<router-link :to="'home'">Home</router-link>
<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

<!-- 帶查詢參數(shù)强缘,下面的結(jié)果為 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

replace :設(shè)置 replace 屬性后督惰,點擊時會調(diào)用 router.replace() 而不是 router.push(),導(dǎo)航后不會留下 history 記錄旅掂。

<router-link :to="{ path: '/abc'}" replace></router-link>

append :設(shè)置 append 屬性后赏胚,則在當(dāng)前 (相對) 路徑前添加基路徑。例如辞友,我們從 /a 導(dǎo)航到一個相對路徑 b栅哀,如果沒有配置 append,則路徑為 /b称龙,如果配了留拾,則為 /a/b

<router-link :to="{ path: 'relative/path'}" append></router-link>

tag : 有時候想要 <router-link> 渲染成某種標(biāo)簽,例如 <li>鲫尊。 于是我們使用 tag prop 類指定何種標(biāo)簽痴柔,同樣它還是會監(jiān)聽點擊,觸發(fā)導(dǎo)航

<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染結(jié)果 -->
<li>foo</li>

active-class :鏈接激活時使用的 CSS 類名疫向】任担可以通過以下代碼來替代。
exact-active-class : 鏈接被精確匹配的時候應(yīng)該激活的 class

<router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
<router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>

event : 聲明可以用來觸發(fā)導(dǎo)航的事件

<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搔驼,一起剝皮案震驚了整個濱河市谈火,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舌涨,老刑警劉巖诫龙,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谆膳,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)尺上,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門总寒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笋粟,“玉大人探入,你說我怎么就攤上這事∽粮颍” “怎么了蜓堕?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵抛虏,是天一觀的道長。 經(jīng)常有香客問我俩滥,道長嘉蕾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任霜旧,我火速辦了婚禮错忱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挂据。我一直安慰自己以清,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布崎逃。 她就那樣靜靜地躺著掷倔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪个绍。 梳的紋絲不亂的頭發(fā)上勒葱,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音巴柿,去河邊找鬼凛虽。 笑死,一個胖子當(dāng)著我的面吹牛广恢,可吹牛的內(nèi)容都是我干的凯旋。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼钉迷,長吁一口氣:“原來是場噩夢啊……” “哼至非!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起糠聪,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤荒椭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后舰蟆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趣惠,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年夭苗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隔缀。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡题造,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出猾瘸,到底是詐尸還是另有隱情界赔,我是刑警寧澤丢习,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站淮悼,受9級特大地震影響咐低,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜袜腥,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一见擦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羹令,春花似錦鲤屡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肪凛,卻和暖如春堰汉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背伟墙。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工翘鸭, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人远荠。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓矮固,卻偏偏與公主長得像,于是被迫代替她去往敵國和親譬淳。 傳聞我的和親對象是個殘疾皇子档址,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容