我從未見過如此簡(jiǎn)潔易懂的Vue教程

我從未見過如此簡(jiǎn)潔易懂的Vue教程

這是一篇長(zhǎng)文,按照我自己的邏輯重新整理一下,包含所有Vue的基礎(chǔ)知識(shí)點(diǎn)。

但是我更建議你先簡(jiǎn)略的閱讀官方的文檔,因?yàn)楸疚木哂幸欢ǖ拈喿x門檻,同時(shí)我也竭盡所能把這門檻降到最低,同樣你也可以把本文作為快速回憶教程。

發(fā)揮100%的專注力,調(diào)動(dòng)體內(nèi)所有的熱情,你將做到很多令人驚嘆的事情

什么是MVVM ?

對(duì)比以前的mvc或者mvp,就是把C或者p替換成vm

vm就是上圖,請(qǐng)仔細(xì)看一些細(xì)節(jié),vm監(jiān)聽DOM,當(dāng)數(shù)據(jù)改變的時(shí)候,vm會(huì)去自動(dòng)更新視圖。

面向未來的組件系統(tǒng)

實(shí)現(xiàn)了一些未來的w3c規(guī)范(暫不贅述)

  • Web 組件規(guī)范
  • Slot API

根 vue 實(shí)例

let viewModel = new Vue({
    // 包含數(shù)據(jù)、模板、掛載元素、方法、生命周期鉤子等選項(xiàng)
})

Hello Wrold 例子

<!-- 這是我們的 View -->
<div id="app">
  Hello {{ name }}!
</div>
// 這是我們的 Model
var model = {
  name: 'Vue.js'
}

// 創(chuàng)建一個(gè) Vue 實(shí)例或 "viewModel"
// 它連接 View 與 Model
var viewModel = new Vue({
  el: '#app',
  data: model
})

組件 Component 構(gòu)造器

vue.extend()返回的只是一個(gè)構(gòu)造器,我們需要通過vue.extend()的返回值和new關(guān)鍵字創(chuàng)建實(shí)例。

當(dāng)我們注冊(cè)為組件的時(shí)候,內(nèi)部就已經(jīng)幫我們創(chuàng)建好了實(shí)例。

Tip: 如果在實(shí)例創(chuàng)建之后添加新的屬性到實(shí)例上,它不會(huì)觸發(fā)視圖更新。

<div id="app">
  <v-footer></v-footer> <!-- 加一個(gè)v前綴,跟原生的footer標(biāo)簽區(qū)別開來 -->
</div>
let Footer = vue.extend({
    template: '<div>我是頁腳組件</div>'
})

// 注冊(cè)為全局組件
Vue.component('v-footer', MyComponent)

// 創(chuàng)建根實(shí)例
new Vue({
  el: '#app'
})

生命周期


上圖的就是ViewModel的生命周期,仔細(xì)的看其實(shí)并不難。目前先了解一下。

在傳統(tǒng)軟件工程中,特別是QT類桌面端軟件,都有軟件的生命周期,還有比如Android的生命周期,React的生命周期。

目前的前端趨勢(shì)正在向此方面靠近。

流程大致像這樣

created()->beforeCompile()->compiled()->ready()

->attached()->detached()->beforeDestroy()->destroyed()   

更詳細(xì)的介紹,請(qǐng)點(diǎn)這里查看API文檔

綁定

簡(jiǎn)單的理解就是模板字符串功能,放心的在任何你想用的地方去用,假如錯(cuò)了vue會(huì)給你提示。

定界符都是可以修改的

// 模板定界符
Vue.config.delimiters = ['{{', '}}']

// html模板定界符
Vue.config.unsafeDelimiters = ["{{{", "}}}"]

數(shù)據(jù)的綁定

<span>消息: {{ msg }}</span>  <!-- 同步更新js里面的數(shù)據(jù) -->

<span>他將永不會(huì)改變: {{* msg }}</span>  <!-- 第一次插入之后就不更新了 -->

<div>{{{ raw_html }}}</div> <!-- 插入原生的 html -->

<div id="item-{{ id }}"></div> <!-- 放在id中 -->


表達(dá)的綁定

不可使用,var/let關(guān)鍵字聲明變量,也不能使用if/for流程控制。

{{ number + 1 }}   // 做簡(jiǎn)單的運(yùn)算

{{ ok ? 'YES' : 'NO' }}   // 三元表達(dá)式

{{ message.split('').reverse().join('') }}   // 調(diào)用該對(duì)象上的方法 

過濾器

對(duì)數(shù)據(jù)進(jìn)行相應(yīng)的處理,message第一個(gè)參數(shù)filter要執(zhí)行的函數(shù)

{{ message | filter }}

{{ message | filterA | filterB }} // filterB(filterA(message))

{{ message | filterA 'arg1' arg2 }} 

// arg2是一個(gè)表達(dá)式(假設(shè)是1+2) filterA(message,arg1,3)

指令

當(dāng)其表達(dá)式的值改變時(shí)把某些特殊的行為應(yīng)用到 DOM 上。

<p v-if="ok">Hello!</p> <!-- 根據(jù)if里面的值,確定是否編譯 -->

<a v-bind:href="url"></a>  
<!-- 等于href="{{url}}" 這里 href 是參數(shù),將元素的 href 屬性傳進(jìn)去。
     告訴vue元素的 href 特性跟表達(dá)式 url 的值綁定 -->


<a v-on:click="doSomething"> 
<!-- v-on表示監(jiān)聽,傳入了click參數(shù),表示當(dāng)click事件發(fā)生的時(shí)候,執(zhí)行doSomething函數(shù) -->


<a v-bind:href.literal="/a/b/c"></a>
<!-- .literal 修飾符告訴指令將它的值解析為一個(gè)字面字符串而不是一個(gè)表達(dá)式 -->

v-bind 縮寫

<!-- 完整語法 -->
<a v-bind:href="url"></a>

<!-- 縮寫 -->
<a :href="url"></a>
<!-- 完整語法 -->
<a v-on:click="doSomething"></a>

<!-- 縮寫 -->
<a @click="doSomething"></a>

計(jì)算屬性

<div id="example">
  a={{ a }}, b={{ b }}
</div>
var vm = new Vue({
  el: '#example',
  data: {
    a: 1
  },
  computed: {
    // 一個(gè)計(jì)算屬性的 getter
    b: function () {
      // `this` 指向 vm 實(shí)例
      return this.a + 1
    }
  }
})

給計(jì)算屬性設(shè)置setter

computed: {
    fullname: {
        get: function() {
            return this.firstName + ' ' + this.lastName
        },
        set: function() {
            let names = newValue.split(' ')
            this.firstName = names[0]
            this.lastName = names[names.length - 1]
        }
    }
}

$watch

通常更優(yōu)的做法是使用computed計(jì)算屬性

<div id="app">{{ fullname }}</div>
let vm = new Vue({
    data: {
        firstName: 'C',
        lastName: 'O',
        fullName: 'CO'
    }
})

vm.$watch('firstname', funciton(val){
    this.fullname = val + ' ' + this.lastName   
})

vm.$watch('lastname', funciton(val){
    this.fullname = this.firstName + ' ' + val  
})


// 等價(jià)于

let vm = new Vue({
    data: {
        firstName: 'Foo',
        lastName: 'Bar'
    },
    computed: {
        fullName: function(){
            return this.firstName + ' ' + this.lastName
        }
    }
})


Class 與 Style 綁定

vue特意增強(qiáng)了他們,支持對(duì)象和數(shù)組綁定

Class 對(duì)象綁定

<div class="static" :class="{ 'class-a': isA , 'class-b': isB}"></div>

data: {
    isA: true,
    isB: false
}

<div class="static" :class="classObjcet"></div>

data: {
    classObject: {
        'class-a': true
        'class-b': false
    }
}


//渲染之后

<div class="static class-a"></div>

Class 數(shù)組語法

<div :class="[classA,classB]"></div>

data: {
    classA: 'class-a'
    classB: 'class-b'
}

// 渲染為

<div class="class-a class-b"></div>


<div :class="[classA, isB? classB : '']"></div>

// 始終添加classA對(duì)應(yīng)的類名,根據(jù)isB的值確認(rèn)是否添加classB對(duì)應(yīng)的值。

// 在1.0.19+之后,為了更明了的寫法,支持?jǐn)?shù)組里面嵌套對(duì)象語法

<div :class="[classA, {classB: isB, classC: isC}]"></div>

Style 對(duì)象語法

CSS 屬性名可以用駝峰式(camelCase)或短橫分隔命名(kebab-case),自動(dòng)添加瀏覽器的前綴。

<div :style="{color: activeColor, fontSize: fontSize + 'px' }"></div>

data: { 
    activeColor: 'red',
    fontSize: 30
}

<div :style="styleObject"></div>

data = {
    styleObject: {
        color: 'red',
        fontSize: '13px'
    }
}

Style 數(shù)組語法

<div :style="[styleObjectA,styleObjectB]"></div>

data = {
    styleObjectA: {
        fontSize: '15px'
    }
}

條件渲染

** Tip: v-else 元素必須立即跟在 v-if 或 v-show 元素的后面——否則它不能被識(shí)別。**

v-if

<h1 v-if="ok">yes</h1>
<h1 v-else>no</h1>

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

v-show

不支持 template 元素包裹

<h1 v-show="ok">Hello!</h1>

// 在組件上不能使用 v-else
<custom-component v-show="condition"></custom-component>
<p v-show="!condition">這可能也是一個(gè)組件</p>

if 與 show 之間的戰(zhàn)爭(zhēng)

如果需要頻繁切換 v-show 較好,如果在運(yùn)行時(shí)條件不大可能改變 v-if 較好。

列表渲染

<ul id="list">
    <li v-for="item in items">
        {{ item.message }}
    </li>
</ul>


var vm = new Vue({
    el: '#list',
    data: {
        items: [
            { message: 'Foo' },
            { message: 'Bar'}
        ]
    }
}) 

通過$index可以訪問索引,且在v-for塊內(nèi)可以訪問的到其他屬性。

<ul id="list">
    <li v-for="item in items">
        {{ parentMessage }} - {{ $index }} - {{ item.message }}
    </li>
</ul>


var vm = new Vue({
    el: '#list',
    data: {
        parentMessage: 'Parent',
        items: [
            {message: 'Foo'},
            {message: 'Bar'}
        ]
    }
})


為索引設(shè)置一個(gè)別名,且 1.0.17+ 之后可以使用 for of

<div v-for="(key,value) of items">
</div>


// 使用一層 template 包裹
<template v-for="item in items">
    <span>{{ item.id }}</span>
    <span>{{ item.content }}</span>
</template>

數(shù)組變動(dòng)檢測(cè)

以下是vue提供的一些數(shù)組上的方法,能觸發(fā)視圖更新。

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

替換數(shù)組

當(dāng)我們使用一些不改變數(shù)組本身的方法的時(shí)候(純函數(shù)),我們可以直接賦值給自身,雖然替換了原始的數(shù)組,但是vue不會(huì)重新渲染所有,他會(huì)去進(jìn)行對(duì)比。

track-by

通過此選項(xiàng)設(shè)置參考特征,用特征對(duì)比,一樣就進(jìn)行復(fù)用

{
    items: [
        {_uid: '339a99', ... }
        {_uid: '2r9c92', ... }
    ]
}

<div v-for="item in items" track-by="_uid">
  <!-- content -->
</div>

// _uid 就說明可以復(fù)用 

track-by="$index"

這樣讓數(shù)據(jù)替換高效,此時(shí)DOM節(jié)點(diǎn)不再映射數(shù)組順序變化,不能同步臨時(shí)狀態(tài)。
v-for 包含 <input>元素或者子組件,要小心使用

更新問題

vue不能檢測(cè)下面數(shù)組的變化

  • 直接用索引設(shè)置元素,如 vm.items[0] = {};
  • 修改數(shù)據(jù)的長(zhǎng)度,如 vm.items.length = 0。
(1) 解決方法
vm.items.$set(0, {})

(2) 解決方法
vm.items = []

對(duì)象v-for

<ul id="repeat-object" class="demo">
    <li v-for="value in object">
        {{ $key }} : {{ value }}
    </li>
</ul>


<div>
  <span v-for="n in 10">{{ n }} </span>
</div>

方法與事件處理

<div id="example">
    <button @click="greet">Greet</button>
</div>

let vm = new Vue({
    el: '#example',
    data: {
        name: 'Vue.js'
    },
    methods: {
        greet: function(event) {
            alert('hello'+this.name+'!')
            console.log(event.target.tagName)
        }
    }

})

<div id="example">
    <button :click="say('hi')">Say Hi</button>
    <button :click="say('what')">Say What</button>
</div>


new Vue({
    el: '#example',
    methods: {
        say:  function(msg) {
            alert(msg)
        }
    }
})


事件修飾符

在事件處理器中經(jīng)常需要調(diào)用event.preventDefaultevent.stopPropagation

// 阻止單擊事件冒泡
<a @click.stop="do"></a>

// 提交事件不再重載頁面
<a @submit.prevent="submit"></a>

// 修飾符可以串聯(lián)
<a @click.stop.prevent="do"></a>

// 只有修飾符
<form @submit.prevent></form>

按鍵修飾符

  • enter
  • tab
  • delete
  • esc
  • space
  • up
  • down
  • left
  • right
<!-- 只有在 keyCode 是 13 時(shí)調(diào)用 vm.submit() -->
<input v-on:keyup.13="submit">

<!-- 同上 -->
<input v-on:keyup.enter="submit">

<!-- 縮寫語法 -->
<input @keyup.enter="submit">

自定義按鍵別名


// 可以使用 @keyup.f1

Vue.directive('on').keyCodes.f1 = 112

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1.安裝 可以簡(jiǎn)單地在頁面引入Vue.js作為獨(dú)立版本,Vue即被注冊(cè)為全局變量,可以在頁面使用了。 如果希望搭建...
    Awey閱讀 11,074評(píng)論 4 129
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,074評(píng)論 0 29
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,241評(píng)論 0 6
  • 下載安裝搭建環(huán)境 可以選npm安裝,或者簡(jiǎn)單下載一個(gè)開發(fā)版的vue.js文件 瀏覽器打開加載有vue的文檔時(shí),控制...
    冥冥2017閱讀 6,081評(píng)論 0 42
  • vue.js官網(wǎng)教程學(xué)習(xí)筆記和學(xué)習(xí)摘要 起步 安裝 一個(gè)簡(jiǎn)單的方法,直接把一個(gè)vue.js引入你的HTML頁面中,...
    恰皮閱讀 3,400評(píng)論 2 22