1. 程式人生 > 實用技巧 >Vue-基礎中的基礎-學習筆記

Vue-基礎中的基礎-學習筆記

參考資料:
Vue官方文件教程:https://cn.vuejs.org/v2/guide/installation.html

我現在做的工作的前端部分用到了Vue,但基本只是用一下Element UI,我也感覺Element UI框架很適合做一些xxx管理系統之類的東西。我不會前端,不會JavaScript和Vue,所以淺淺地學習一些基礎知識,以便快速加入工作專案的開發。但我本人並不是很喜歡Vue。

Element UI

這種前端UI框架一般由專業前端開發人員來做,我可能只需要看懂就可以了,需要改程式碼的時候可以查文件:https://element.eleme.cn/#/zh-CN/component/installation

宣告式渲染

大部分內容都可以在官方文件中找到,官方的介紹入門教程非常簡短但全面。我這裡記錄幾處東西用來方便自己速查。

javascript程式碼:

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})
HTML程式碼:

<div id="app">
  {{ message }}
</div>

可以注意到new的Vue物件中的el屬性的值對應著相應HTML程式碼的標籤的id屬性。雙大括號可以將Vue物件中data下的屬性輸出出來,這種方式叫做文字插值。

還有另外一種方式叫元素繫結:

javascript程式碼:

var app2 = new Vue({
  el: '#app-2',
  data: {
    message: '頁面加載於 ' + new Date().toLocaleString()
  }
})
HTML程式碼:

<div id="app-2">
  <span v-bind:title="message">
    滑鼠懸停幾秒鐘檢視此處動態繫結的提示資訊!
  </span>
</div>

使用了v-bind指令,將這個span標籤的title attribute與message property繫結在一起。attribute和property都可以翻譯為屬性,我自己把attribute理解為標籤的屬性,property理解為Vue示例的data下的屬性。

條件與迴圈

控制一個元素是否顯示:

javascript程式碼:

var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})
HTML程式碼:

<div id="app-3">
  <p v-if="seen">現在你看到我了</p>
</div>

使用了v-if指令,如果seen property的值為false,則不顯示。

我們不僅可以把資料繫結到 DOM 文字或 attribute,還可以繫結到 DOM 結構。此外,Vue 也提供一個強大的過渡效果系統,可以在 Vue 插入/更新/移除元素時自動應用過渡效果。 ——官方文件

v-for指令可以繫結陣列的資料來渲染一個專案列表:

javascript程式碼:

var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: '學習 JavaScript' },
      { text: '學習 Vue' },
      { text: '整個牛專案' }
    ]
  }
})
HTML程式碼:

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>

效果如下:

處理使用者輸入

表單輸入和應用狀態之間雙向繫結指令v-model:

JavaScript程式碼:

var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'
  }
})
HTML程式碼:

<div id="app-6">
  <p>{{ message }}</p>
  <input v-model="message">
</div>

這個程式碼會出現一個input輸入框,如果改動輸入框中的文字,實際就是直接改動message的值,上面p標籤展示的message的值也會隨之改動。

事件監聽器指令v-on,可以通過它呼叫在 Vue 例項中定義的method:

JavaScript程式碼:

var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
HTML程式碼:

<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">反轉訊息</button>
</div>

在 reverseMessage 方法中,我們更新了應用的狀態,但沒有觸碰 DOM——所有的 DOM 操作都由 Vue 來處理,你編寫的程式碼只需要關注邏輯層面即可。(來自文件)

可以看到我們的Vue例項中出現了第三個屬性methods,我把它理解為寫一些方法的地方。可以向上邊一樣用v-on:click把一個button等標籤的click事件繫結上methods: {}中的方法,每次點選這個button就會呼叫這個方法。

元件化應用構建

這部分我幾乎用不到,我工作中基本不會複用元件,也就沒必要建立一個元件。官方文件:https://cn.vuejs.org/v2/guide/index.html#元件化應用構建

生命週期

官方文件:https://cn.vuejs.org/v2/guide/instance.html#生命週期圖示

這個東西理解起來需要經驗,可以慢慢來。

計算屬性和偵聽器

有時候在HTML模板中展示的資料會做一些邏輯處理:

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

這種直接在模板中放入邏輯的方式會讓模板過重且難以維護,我們可以使用計算屬性(computed: {}):

JavaScript程式碼:

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 計算屬性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 例項
      return this.message.split('').reverse().join('')
    }
  }
})

實現翻轉功能的方法放到一個匿名函式裡,用作 property vm.reversedMessage 的 getter 函式:

HTML程式碼:

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>

Vue 提供了一種更通用的方式來觀察和響應 Vue 例項上的資料變動:偵聽屬性watch: {}。當有一些資料需要隨著其它資料變動而變動時很容易濫用 watch。然而,通常更好的做法是使用計算屬性而不是命令式的 watch 回撥。

但有時候我們可能有監聽一段內容是否被改變的需求,如果被改變,就呼叫一些函式。

HTML程式碼:

<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question">
  </p>
  <p>{{ answer }}</p>
</div>
JavaScript程式碼:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // 如果 `question` 發生改變,這個函式就會執行
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    // `_.debounce` 是一個通過 Lodash 限制操作頻率的函式。
    // 在這個例子中,我們希望限制訪問 yesno.wtf/api 的頻率
    // AJAX 請求直到使用者輸入完畢才會發出。想要了解更多關於
    // `_.debounce` 函式 (及其近親 `_.throttle`) 的知識,
    // 請參考:https://lodash.com/docs#debounce
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  },
  methods: {
    getAnswer: function () {
      if (this.question.indexOf('?') === -1) {
        this.answer = 'Questions usually contain a question mark. ;-)'
        return
      }
      this.answer = 'Thinking...'
      var vm = this
      axios.get('https://yesno.wtf/api')
        .then(function (response) {
          vm.answer = _.capitalize(response.data.answer)
        })
        .catch(function (error) {
          vm.answer = 'Error! Could not reach the API. ' + error
        })
    }
  }
})
</script>

使用 watch 選項允許我們執行非同步操作 (訪問一個 API),限制我們執行該操作的頻率,並在我們得到最終結果前,設定中間狀態。這些都是計算屬性無法做到的。除了 watch 選項之外,還可以使用命令式的 vm.$watch API。

<template> 元素

<template>這個元素像是個對頁面沒什麼影響的標籤,有時常結合 v-if 和 v-for 使用。

v-if,v-show,v-else,v-else-if與key

v-show 用法跟 v-if 差不多,區別是 v-if 只有條件為真時才開始渲染,v-show 卻始終在DOM中,當條件為真時就顯示出來。

可以使用 v-else 指令來表示 v-if 的 else 塊,v-else-if 充當 v-if 的 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>

key的部分我覺得官方文件的例子非常好,我直接搬過來:
https://cn.vuejs.org/v2/guide/conditional.html#用-key-管理可複用的元素

Vue 會盡可能高效地渲染元素,通常會複用已有元素而不是從頭開始渲染。這麼做除了使 Vue 變得非常快之外,還有其它一些好處。例如,如果你允許使用者在不同的登入方式之間切換:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>

那麼在上面的程式碼中切換 loginType 將不會清除使用者已經輸入的內容。因為兩個模板使用了相同的元素,<input> 不會被替換掉——僅僅是替換了它的 placeholder。

如果設計一個按按鈕,點選一下按鈕,輸入框就從 Username 的輸入框變成 Email 的輸入框,但內容並沒有變化。

這樣也不總是符合實際需求,所以 Vue 為你提供了一種方式來表達“這兩個元素是完全獨立的,不要複用它們”。只需新增一個具有唯一值的 key attribute 即可:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

現在,每次切換時,輸入框都將被重新渲染,內容就重新為空,只顯示佔位字串。<label> 元素仍然會被高效地複用,因為它們沒有新增 key attribute。

官方文件不推薦同時使用v-if 與 v-for。但當 v-if 與 v-for 一起使用時,v-for 具有比 v-if 更高的優先順序

列表渲染

這部分很簡單,用的也很多。可以直接看官方文件:
https://cn.vuejs.org/v2/guide/list.html

一般都是把需要展示的列表內容取到,對映到一個物件裡,把這個物件放在data中。在前端用 v-for 遍歷這個物件,不要忘記加一個key,方便Vue跟蹤每個節點的身份。

陣列更新檢測(這一部分感覺做分頁功能的時候用得到):
https://cn.vuejs.org/v2/guide/list.html#陣列更新檢測

事件處理

可以用 v-on 指令監聽 DOM 事件,並在觸發時執行一些 JavaScript 程式碼:

<div id="example-1">
  <button v-on:click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>

var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
})

一般不直接寫v-on:click="counter += 1"這種程式碼,而是繫結到一個方法,也可以在內聯 JavaScript 語句中呼叫方法。

<div id="example-3">
  <button v-on:click="say('hi')">Say hi</button>
  <button v-on:click="say('what')">Say what</button>
</div>

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

事件修飾符:https://cn.vuejs.org/v2/guide/events.html#事件修飾符

按鍵修飾符:https://cn.vuejs.org/v2/guide/events.html#按鍵修飾符

表單輸入繫結

這一部分可能常用,重點關注:https://cn.vuejs.org/v2/guide/forms.html

v-bind和v-model的區別

https://segmentfault.com/a/1190000014813168?utm_source=tag-newest
這篇文章寫得比較好,可以看一下。