vue學習筆記

.$data .#$el

$data表示vue實例中data的值
$el表示vue實例中el的值,注意 el效果等同getElementById.遇到多個同樣classname,只處理第一個

  <div class="box">
    {{ a }}     //此處值為1
  </div>
  <div class="box">{{ a }}</div>
  <div class="box">{{ a }}</div>
  <script>
    var data = { a: 1 }
    var vm = new Vue({
    el: '.box',
    data: data
    })
    vm.$data === data // => true
    vm.$el === document.getElementById('.box') //     => true
    // $watch 是一個實例方法
  </script>

vue生命周期圖

vue生命周期圖

上圖原文地址

每個 Vue 實例在被創建之前都要經過一系列的初始化過程。例如需要設置數據監聽、編譯模板、掛載實例到 DOM、在數據變化時更新 DOM 等。同時在這個過程中也會運行一些叫做生命周期鉤子的函數,給予用戶機會在一些特定的場景下添加他們自己的代碼。

例:

  • created鉤子

created鉤子用在一個vue實例創建之后執行代碼:

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 實例
    console.log('a is: ' + this.a)
  }
})
// => "a is: 1"

vue模版語法

文本

數據綁定最常見的形式就是使用“Mustache”語法 (雙大括號) 的文本插值:

<span>Message: {{ msg }}</span>

Mustache 標簽將會被替代為對應數據對象上 msg 屬性的值。無論何時,綁定的數據對象上 msg 屬性發生了改變,插值處的內容都會更新。

通過使用 v-once 指令,你也能執行一次性地插值,當數據改變時,插值處的內容不會更新。但請留心這會影響到該節點上所有的數據綁定:

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

原始HTML

雙大括號會將數據解釋為普通文本,而非 HTML 代碼。為了輸出真正的 HTML ,你需要使用 v-html 指令:

<div v-html="rawHtml"></div>

以下是{{ Mustache }}語法與v-html的區別實例:



{{}}的語法會被解析成普通文本,v-html則會解析為HTML

特性

Mustache 語法不能作用在 HTML 特性上,遇到這種情況應該使用 v-bind 指令:

<div v-bind:id="dynamicId"></div>

延伸: vue的作用域和js作用域類似
示例:

<body>
    <div class="app-5">
        for
        <span v-bind:id="src" v-bind:title="src">number</span>
        <span v-bind:title="yeah">helloworld</span>
        <div class="third">
            <div v-bind:title="yeah">
                div-next
            </div>
        </div>
        <script>
            var app5 = new Vue({
                el: ".app-5",
                data: {
                    src: "nice",
                    yeah: "good job"
                }
            })
        </script>
</body>

//生成如下頁面
<div class="third">
    <div title="good job">
        div-next
    </div>
</div>

上圖示例中,在<div class="app-5">下聲明一個new Vue,.app-5下的元素使用vue中變量yeah時,若自己的作用域下未找到,則到上級作用域去找,直到找到為止,若找不到,則報錯

使用js表達式

vue支持所有原生js表達式

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>

但有個限制,每個綁定只能包含單個表達式,以下例子不會生效

<!-- 這是語句,不是表達式 -->
<!-- 表達式是由運算符構成,并運算產生結果的語法結構。

程序是由語句構成,語句則是由“;(分號)”分隔的句子或命令。

如果在表達式后面加上一個“;”分隔符,這就被稱為“表達式語句”。它表明“只有表達式,而沒有其他語法元素的語句” -->
{{ var a = 1 }}
<!-- 流控制也不會生效,請使用三元表達式 -->
{{ if (ok) { return message } }}

指令

指令 (Directives) 是帶有 v- 前綴的特殊屬性。指令屬性的值預期是單個 JavaScript 表達式 (v-for 是例外情況。指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地作用于 DOM。

<p v-if="seen">現在你看到我了</p>
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})
//若seen=true,則p內文字可見,若seen=false,p內文字消失

這里,v-if 指令將根據表達式 seen 的值的真假來插入/移除 <p> 元素。

參數

一些指令能夠接收一個“參數”,在指令名稱之后以冒號表示。例如,v-bind 指令可以用于響應式地更新 HTML 屬性:

<a v-bind:href="url"></a>

在這里 href 是參數,告知 v-bind 指令將該元素的 href 屬性與表達式 url 的值綁定。
另一個例子是 v-on 指令,它用于監聽 DOM 事件:

<a v-on:click="doSomething">

在這里參數是監聽的事件名

修飾符

修飾符 (Modifiers) 是以半角句號 . 指明的特殊后綴,用于指出一個指令應該以特殊方式綁定。例如,.prevent 修飾符告訴 v-on 指令對于觸發的事件調用 event.preventDefault():

<form v-on:submit.prevent="onSubmit"></form>

之后當我們更深入地了解 v-on 與 v-model時,會看到更多修飾符的使用

縮寫

v- 前綴作為一種視覺提示,用來識別模板中 Vue 特定的特性。當你在使用 Vue.js 為現有標簽添加動態行為 (dynamic behavior) 時,v- 前綴很有幫助,然而,對于一些頻繁用到的指令來說,就會感到使用繁瑣。同時,在構建由 Vue.js 管理所有模板的單頁面應用程序 (SPA - single page application) 時,v- 前綴也變得沒那么重要了。因此,Vue.js 為 v-bind 和 v-on 這兩個最常用的指令,提供了特定簡寫:

v-bind縮寫

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

v-on縮寫

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

它們看起來可能與普通的 HTML 略有不同,但 : 與 @ 對于特性名來說都是合法字符,在所有支持 Vue.js 的瀏覽器都能被正確地解析。而且,它們不會出現在最終渲染的標記中。縮寫語法是完全可選的

計算屬性

模板內的表達式是非常便利的,但是它們實際上是用于簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護。例如:

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

在這個地方,模板不再簡單和清晰。你必須看一段時間才能意識到,這里是想要顯示變量 message 的翻轉字符串。當你想要在模板中多次引用此處的翻轉字符串時,就會更加難以處理。

這就是對于任何復雜邏輯,你都應當使用計算屬性的原因。

基礎例子

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // a computed getter
    reversedMessage: function () {
      // `this` points to the vm instance
      return this.message.split('').reverse().join('')
    }
  }
})

結果:
Original message: "Hello"

Computed reversed message: "olleH"

這里我們聲明了一個計算屬性 reversedMessage。我們提供的函數將用作屬性 vm.reversedMessage 的 getter 函數:

console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'

你可以打開瀏覽器的控制臺,自行修改例子中的 vm。vm.reversedMessage 的值始終取決于 vm.message 的值。

你可以像綁定普通屬性一樣在模板中綁定計算屬性。Vue 知道 vm.reversedMessage 依賴于 vm.message,因此當 vm.message 發生改變時,所有依賴于 vm.reversedMessage 的綁定也會更新。而且最妙的是我們已經以聲明的方式創建了這種依賴關系:計算屬性的 getter 函數是沒有連帶影響 (side effect),這使得它易于測試和推理。

計算屬性的緩存 vs 方法

你可能已經注意到我們可以通過在表達式中調用方法來達到同樣的效果:

  <p>Reversed message: "{{ reversedMessage() }}"</p>
  <script>
    var vm = new Vue({
      el: "p",
      data: {
        message: "happy"
      },
      methods: {
        reversedMessage: function(){
          return this.message.split("").reverse().join("")
        }
      }
    })
  </script>

我們可以將同一函數定義為一個方法而不是一個計算屬性。對于最終的結果,兩種方式確實是相同的。然而,不同的是計算屬性是基于它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時才會重新求值。這就意味著只要 message 還沒有發生改變,多次訪問 reversedMessage 計算屬性會立即返回之前的計算結果,而不必再次執行函數。

這也同樣意味著下面的計算屬性將不再更新,因為 Date.now() 不是響應式依賴:

computed: {
  now: function () {
    return Date.now()
  }
}

相比之下,每當觸發重新渲染時,方法的調用方式將總是再次執行函數。

我們為什么需要緩存?假設我們有一個性能開銷比較大的的計算屬性 A,它需要遍歷一個極大的數組和做大量的計算。然后我們可能有其他的計算屬性依賴于 A 。如果沒有緩存,我們將不可避免的多次執行 A 的 getter!如果你不希望有緩存,請用方法來替代。

計算屬性 vs 被觀察的屬性

Vue 確實提供了一種更通用的方式來觀察和響應 Vue 實例上的數據變動:watch 屬性。當你有一些數據需要隨著其它數據變動而變動時,你很容易濫用 watch——特別是如果你之前使用過 AngularJS。然而,通常更好的想法是使用計算屬性而不是命令式的 watch 回調。細想一下這個例子:

<div id="demo">{{ fullName }}</div>
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
    }
  }
})

上面代碼是命令式的和重復的。將它與計算屬性的版本進行比較:

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

好得多了,不是嗎?

computed與methods

學到這里遇到了computed和methods兩個方法

用以下代碼對比

<body>
  <div class="box">
    <div class="child">
      {{ message}}
    </div>
    <div class="child">
      {{ timing }}
    </div>
    <div class="fn">
      {{ timed() }}
    </div>
  </div>
  <script>
    var vm = new Vue({
      el: ".box",
      data: {
        message: "hello"
      },
      methods: {
        timed: function(){
          return Date.now()
        }
      },
      computed: {
        timing: function(){
          return Date.now()
        }
      }
    })
  </script>
</body>
//在控制臺改變vm.message結果時。div.fn的結果會改變,div.child的結果不會改變

methods方法返回的結果,在message改變時也會從新計算。computed則不會

計算屬性的 setter

計算屬性默認只有 getter ,不過在需要時你也可以提供一個 setter :

<body>
  <div class="box">
    {{ fullName }}
  </div>
  <script>
    var vm = new Vue({
      el: ".box",
      data: {
        firstName: "nick",
        lastName: "song"
      },
      computed: {
  fullName: {
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
    })
  </script>
</body>

現在再運行 vm.fullName = 'John Doe' 時,setter 會被調用,vm.firstName 和 vm.lastName 也相應地會被更新。

Class 與 Style 綁定

數據綁定的一個常見需求是操作元素的 class 列表和它的內聯樣式。因為它們都是屬性 ,我們可以用v-bind 處理它們:只需要計算出表達式最終的字符串。不過,字符串拼接麻煩又易錯。因此,在 v-bind 用于 class 和 style 時,Vue.js 專門增強了它。表達式的結果類型除了字符串之外,還可以是對象或數組。

綁定 HTML Class

對象語法

我們可以傳給 v-bind:class 一個對象,以動態地切換 class:

<div v-bind:class="{ active: isActive }"></div>

上面的語法表示 classactive 的更新將取決于數據屬性 isActive 是否為真值。

你可以在對象中傳入更多屬性用來動態切換多個 class。此外,v-bind:class 指令也可以與普通的 class 屬性共存。如下模板:

<div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>

如下 data :

data: {
  isActive: true,
  hasError: false
}

渲染為:

<div class="static active"></div>

當 isActive 或者 hasError 變化時,class 列表將相應地更新。例如,如果 hasError 的值為 true ,class 列表將變為 "static active text-danger" 。

你也可以直接綁定數據里的一個對象:

<div v-bind:class="classObject"></div>
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

渲染的結果和上面一樣。我們也可以在這里綁定返回對象的計算屬性。這是一個常用且強大的模式:

<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
//expr1 && expr2   如果expr1 能轉換成false則返回expr1,否則返回expr2. 因此, 在Boolean環境中使用時, 兩個操作結果都為true時返回true,否則返回false.

數組語法

我們可以把一個數組傳給 v-bind:class,以應用一個 class 列表:

<div v-bind:class="[activeClass, errorClass]"></div>
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

渲染為:

<div class="active text-danger"></div>

如果你也想根據條件切換列表中的 class,可以用三元表達式

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

此例始終添加 errorClass ,但是只有在 isActive 是 true 時添加 activeClass。

不過,當有多個條件 class 時這樣寫有些繁瑣。可以在數組語法中使用對象語法:

    <div v-bind:class="[{ active: isActive }, errorClass]"></div>    
  <script>
    var vm = new Vue({
      el: "div",
      data: {
       isActive: false,
       errorClass: "error"
      }
    })
  </script>
<div v-bind:class="[{ active: isActive }, errorClass]"></div>

渲染為:

<div class="error"></div>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容

  • 1.安裝 可以簡單地在頁面引入Vue.js作為獨立版本,Vue即被注冊為全局變量,可以在頁面使用了。 如果希望搭建...
    Awey閱讀 11,067評論 4 129
  • Vue學習筆記 Vue初始化對象 data和methods里面的屬性都是Vue這個實例對象的代理屬性,例:vm.m...
    土豪碼農閱讀 1,004評論 1 1
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內容,還有我對于 Vue 1.0 印象不深的內容。關于...
    云之外閱讀 5,069評論 0 29
  • 一、vue生命周期 vue實例從創建到銷毀的過程,稱為生命周期,共有八個階段。 這八個階段里分別有一個叫做鉤子函數...
    間陽幕賓閱讀 415評論 0 1
  • 正如許多人所詬病的那樣,現代教育確實局限了學生們的想象力,也局限了學生們的思考問題的思路 首先,聲明的是,...
    向小宋閱讀 1,712評論 0 0