iT邦幫忙

2021 iThome 鐵人賽

DAY 2
1
Modern Web

我的Vue學習筆記系列 第 2

Day02-Vue.js的實體

分解Vue

1. 實體物件

利用createApp({...})建立一個物件實體,也就是vue的本體。

2. option

實體物件的核心,用來定義狀態和事件還有之後要學的呼叫函式(例如methods)。

3. 掛載至DOM

有了實體之後就要去找到要控制的對象,使用mount()掛載節點。

目標節點可以是class name 或 tagName,沒有規定只能用id。所以若有多個符合條件的元素,他只會選出第一個來掛載

資料怎麼傳到畫面上

在Vue實體中用data()定義message的內容,網頁會將HTML模板內容進行解析,然後輸出結果,如下圖。

除了渲染data資料外,也可以做一些簡單的運算

<div id="app">
        <h1>{{name}} bought {{quantity}} ice cream, they cost NT.{{quantity*price}}</h1>
    </div>
<script src="https://unpkg.com/vue@next"></script>

<!-- Vue bought 2 ice cream, they cost NT.50 -->
const vm = Vue.createApp({
  data() {
      return {
          name: 'Vue',
          quantity: '2',
          price: '25'
      }
  }
})
vm.mount('#app');

響應式更新

當實體被建立後,可以透過vm.$data.XXX來操作內部狀態。

出現錯誤 : 在createApp時並未將此實體掛載到DOM上,此時的vm.$data是沒有被定義的

const vm = Vue.createApp({
    data() {
        return {
            name: 'Vue',
        }
    }
})
vm.mount('#app');
vm.$data.name = "Bob"
//Uncaught TypeError: Cannot set property 'name' of undefined

所以要在vm.mount('#app')執行後vm.$data才會出現。

const vm = Vue.createApp({
    data() {
        return {
            name: 'Vue',
        }
    }
})
const vMountedInstance = vm.mount('#app');
vMountedInstance.$data.name = "Bob"

被汙染的data

若頁面存在個多個Vue實體,且有共同的data屬性,可以在最外層幫他定義。

const dataObj = {
    message: 'Vue'
}

const vm1 = Vue.createApp({
    data() {
        return dataObj
    }
}).mount('#app1');

const vm2 = Vue.createApp({
    data() {
        return dataObj
    }
}).mount('#app2');

加入剛剛上一個段落的$data概念,想改變單一個實體時,加入以下內容,卻發現vm2的內容也被修改了!!!!

vm1.$data.message = 'Hello';

解決辦法 : ES6的物件解構,也就是將兩個物件從參考關係變成兩個互不影響的物件

const dataObj = {
    message: 'Vue'
}

const vm1 = Vue.createApp({
    data() {
        return {...dataObj}
    }
}).mount('#app1');

const vm2 = Vue.createApp({
    data() {
        return {...dataObj}
    }
}).mount('#app2');

模板template

options中放入template,效果就根HTML模板一樣,

const vm = Vue.createApp({
    template: `<h1>{{name}}</h1>`,
    data() {
        return {
            name: 'Vue',
        }
    }
}).mount('#app')

書中也提到過去的Vue 2.X有個特性,就是template中只能有一個根元素且必須要有一個根元素,因為同時有多個根元素就像是多個id ='#app'一樣,vue就會不知道要DOM是誰,固有此限制。

但在Vue 3.0中增加了fragments功能,也就是把多個根元素包在一個根元素裡面,看起來就符合只能有一個根元素且必須要有一個根元素。

參考資料

為什麼只能有一個根元素
https://juejin.cn/post/6844904074438000648
https://segmentfault.com/a/1190000019827095
Fragments
https://www.jianshu.com/p/977de733cadf
https://juejin.cn/post/6967259191299801124


上一篇
Day01-為什麼我要學Vue/Vue簡介
下一篇
Day03-資料加工與邏輯整合(methods v.s. computed)
系列文
我的Vue學習筆記30

尚未有邦友留言

立即登入留言