iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 14
0
Modern Web

Vue.js 30天系列 第 14

Vue.js 14 - 組件/元件(Component) - 包裝方式及內部狀態

利眼人應該發現 組件/元件(Component) 有些屬性,Vue Instance 不曾用過,這篇開始介紹差異之處,這些屬性如何用、用來幹嘛。


上一篇提過,組件存在意義是為了拆解邏輯、使得結構清晰好懂。

但原本功能間的協同運作都在同一層,拆成組件後,變成各個獨立的狀態了,我們仍然需要維持彼此間溝通暢通呀 (本是同根生,不能斷啊),有什麼方法讓

  • Vue Instance <--> 組件
  • 父組件 <--> 子組件
    之間溝通順暢呢?

如同所有漂亮的 JavaScript 模組一樣,需要訂出漂亮的對外介面(Interface),使其改動內部邏輯的同時,又不失其重用性(環保可回收),方便傳入外部資料。

建議包法

官方建議你props down, events up,透過prop傳入資料、透過組件事件(event)傳遞消息
http://ithelp.ithome.com.tw/upload/images/20161230/20103424eUaLJoQkAN.png

為什麼呢?
使得相依的資料便於傳入、Callback function具有彈性,且維持單向資料流。

<div id="#app">
    <record-element v-for="record in list"
                    :record="record"
                    @after-update="updateList"></record-element>
</div>
Vue.component('record-element', {
    template: '<div :disabled="recordHasChanged"><span>{{ record.author }}</span><button @click="changeAuthor('Raf')">change author</button></div>',
    props: ['record'],
    data: {
        recordHasChanged: false
    },
    methods: {
        changeAuthor: function(username) {
            /* 做了一些事 */
            /* 把該筆記錄變成Raf的,並存回後端 */
            this.$set('recordHasChanged', true);
            this.$emit('after-update');
        }
    }
})

new Vue({
    el: '#app',
    data: {
        list: []
    },
    methods: {
        updateList: function() {
            /* 前後端同步,跟後端要最新資料 */
            /* 寫回 list */
        }
    }
})

內部狀態 - data

它的用法跟Vue Instancedata一樣,用於內部狀態的宣告。
但使用情境不同,宣告方式些許不同。

借上一篇的範例

new Vue({
	/* ... */
	data: {},
	/* ... */
})

Vue.component('child', {
	/* .... */
	data: function() {
		return {};
	},
	/* ... */
})

Vue Instance作為根節點,通常只會有一個。
組件為了方便重用,通常會有多個。

function每次return不同的JSON物件,讓每個組件各有各的data 自己的小小天地
所有 共用同一個狀態,就像你跟長輩共用 apple 帳號,恐怖吧?

外部傳入資料 - Prop

除了組件自身的內部狀態 data,能夠與外部一刀兩斷,切得乾乾淨淨,總是有資料跟外部相依。
Prop 正是用於對外介面,將資料從外部傳入的專用接口。

宣告在 props 屬性內,使用方式與 data 相同

Vue.component('child', {
  props: ['type', 'myMessage'],
  template: '<span class="text-{{ type }}">{{ myMessage }}</span>'
})
<!-- 靜態綁法 -->
<!-- 傳入字串 'primary' 、 'hello!' -->
<child type="primary" my-message="hello!"></child>
<!-- 動態綁法 -->
<child :type="classType" :my-message="msg"></child>
<!--
    {
        data: {
            classType: 'primary',
            msg: 'hello!'
        }
    }
-->

若是命名為多字,因為html不分大小寫,對應屬性的命名慣例是
駝峰命名法(camelCase) --> 串聯命名法(kebab-case)
myMessage ---> my-message


圖片來源一


上一篇
Vue.js 13 - 組件/元件(Component) - 用途及使用方式
下一篇
Vue.js 15 - 組件/元件(Component) - 自訂事件及對外溝通
系列文
Vue.js 30天30

1 則留言

0
ledtorch
iT邦新手 5 級 ‧ 2018-05-26 06:02:39

想請問為什麼在component裡面用func可以達成每次返回"不同"的Json物件?

Ralph iT邦新手 5 級‧ 2018-05-29 23:37:45 檢舉

function 每次執行,return object 都是新的物件。

自然是"不同"的物件。

若是想知道更細,建議你去看 vue 原始碼的 getData 怎麼實作。

我要留言

立即登入留言