iT邦幫忙

2022 iThome 鐵人賽

DAY 9
0
Modern Web

淺入淺出 Rails with Vue系列 第 9

【Day 09】淺入淺出 Rails with Vue - Vue 的基本概念 - 8

  • 分享至 

  • xImage
  •  

前言

本系列將介紹 Rails with Vue 的基本概念,並且以一個簡單的專案 Todo 來說明如何使用 Rails with Vue。我將透過這一系列的文章記錄我學習的過程,並且將我所學到的知識分享給大家。


Watchers

在 Vue 中,在運算資料時大部分都是透過 computed properties 來達成,但有某些時候用 watchers 會比較方便,例如執行 asynchronouscostly 的運算時,這時候就可以使用 watchers 來達成。

<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question">
  </p>
  <p>{{ answer }}</p>
</div>
<!-- Since there is already a rich ecosystem of ajax libraries    -->
<!-- and collections of general-purpose utility methods, Vue core -->
<!-- is able to remain small by not reinventing them. This also   -->
<!-- gives you the freedom to use what you're familiar with.      -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/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: {
    // whenever question changes, this function will run
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    // _.debounce is a function provided by lodash to limit how
    // often a particularly expensive operation can be run.
    // In this case, we want to limit how often we access
    // yesno.wtf/api, waiting until the user has completely
    // finished typing before making the ajax request. To learn
    // more about the _.debounce function (and its cousin
    // _.throttle), visit: 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>

在這個範例中,我們使用了 watchers 來監聽 question 的變化,當 question 變化時,我們會呼叫 debouncedGetAnswer 來取得答案。debouncedGetAnswer 是透過 lodashdebounce 來達成,這個函式會在 500ms 後執行,這樣可以避免使用者在輸入時,每輸入一個字就會呼叫 getAnswer 來取得答案,這樣會造成效能上的問題。

Class and Style Bindings

在 Vue 中,比較常用的需求是根據資料的變化來改變元素的樣式,這時候就可以透過 v-bind:class 來綁定 class,也可以透過 v-bind:style 來綁定 style。

Binding HTML Classes

Object Syntax

我們可以 v-bind:class 來綁定 class 並動態改變 class 的值,這時候可以使用 object syntax 來達成。

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

在這個範例中,我們使用 v-bind:class 來綁定 class,並且使用 object syntax 來綁定 active 這個 class,當 isActive 的值為 true 時,active 這個 class 會被加入到元素中,當 isActive 的值為 false 時,active 這個 class 會被移除。
也可以有 多個 class 來綁定,只要在 object syntax 中加入多個 key-value,並且和 plain class 共存。

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

配合以下的資料:

data: {
  isActive: true,
  hasError: false
}

會產生以下的 HTML:

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

isActivehasError 的值改變時,activetext-danger 這個 class 也會跟著改變。例如當 hasError 的值改為 true 時,會產生以下的 HTML:

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

被綁定的 object 不一定要 inline,例如以下的 classObject,也會產生相同的結果:

<div v-bind:class="classObject"></div>

搭配以下的資料:

data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

除此之外我們也可以使用 computed property 來綁定 class,例如以下的 computedClassObject

<div v-bind:class="computedClassObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  computedClassObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

在這個範例中,我們使用 computed property 來綁定 computedClassObject,當 isActiveerror 的值改變時,computedClassObject 也會跟著改變。

Reference


上一篇
【Day 08】淺入淺出 Rails with Vue - Vue 的基本概念 - 7
下一篇
【Day 10】淺入淺出 Rails with Vue - Vue 的基本概念 -9
系列文
淺入淺出 Rails with Vue30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言