Vue 組件/ Prop單向數據流 / $emit自定義方法

組件基礎


  1. 全局註冊組件
// 註冊組件
Vue.component('cpt-name', {})

// 使用
<cpt-name></cpt-name>
  1. 局部組件
// 註冊局部組件
const cpt = {}

// 在實例中定義局部組件
new Vue({
	components: {
		cpt-name: cpt
	}
})

// 使用
<cpt-name></cpt-name>

組件命名

  1. 大駝峯命名的組件 IButton;
    在html 中,只能通過烤串方式使用 i-button;
    在template中,可以通過 大駝峯IButton / 小駝峯iButton / 烤串i-button 方式使用;

  2. 小駝峯命名的組件 iButton;
    在html 中,只能通過烤串方式使用 i-button;
    在template中,可以通過 小駝峯iButton / 烤串i-button 方式使用;

  3. 烤串方式命名的組件 i-button;
    在html 和 template中都只能通過烤串命名方式使用 i-button;

所以,由上得出,給組件命名的時候,優先使用大駝峯命名;
但是,我個人感覺使用烤串命名會好一點,三方(組件名,html中使用時,template中使用時)保持一致,不容易混淆;

Prop


Prop的類型

  1. 字符串數組
Vue.component('my-component', {
	props: ['name', 'title', 'age']
})
  1. 對象形式
Vue.component('my-component', {
	props: {
		name: String,
		age: Number
	}
})

Prop 驗證

Vue.component('my-component', {
	props: {
		// 基礎的類型檢查('null' 和 'undefined' 會通過任何類型驗證)
		p1: String,
		// 多個可能的類型
		p2: [String, Number, Boolean],
		// 必填項
		p3: {
			type: String,
			required: true
		},
		// 默認值
		p4: {
			type: String,
			default: '宮鑫'
		},
	}
})

一般常用的就是如上四種,Prop還可以自定義驗證函數,這個想要詳細瞭解可以看手冊;
類型檢查時,type 值可以是下列原生構造函數的一個

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Function
  • Date
  • Symbol

Prop 單向數據流

父級prop的更新會向下流動到子組件中,但是反過來則不行;每次父級組件發生更新時,子組件中所有的prop都將刷新爲最新的值。這意味着你不應該在一個子組件中改變prop。

如果在子組件中改變prop的值,可以使用如下兩種辦法

  1. 在子組件中將prop通過data轉成本地數據來使用
Vue.component('my-component', {
	props: {
		name: String
	},
	data() {
		return {
			iName: this.name	
		}
	},
})
  1. 如果傳入的這個值需要轉換,可以使用計算屬性
props: ['name'],
computed: {
	iName() {
		return this.name + '你好';
	}
}

注意:在javascript 中,對象和數組是通過引入傳入的,所以如果將一個對象或數組通過prop傳入子組件,在子組件中改變這個對象或數組本身將影響到父組件的狀態;

Vue.component('test', {
    props: ['obj'],
    methods: {
        change(){
            this.obj.name = "路漫漫其修遠其"
        }
    },
    template: `
        <div>
            <p>子組件: {{obj.name}}</p>
            <a href="javascript:;" @click="change">change</a>
        </div>
    `
})
new Vue({
    el: "#app",
    data: {
        obj: { name: "任重道遠" }
    },
    template: `
        <div>
            <p>{{obj.name}}</p>
            <test :obj="obj"></test>
        </div>
    `
})
// 如上所示,在實例中定義了一個 obj 對象,傳入到了子組件中,在子組件中修改了這個對象,
// 但是實例中(父組件)中的 obj 也發生了變化;
//(其實如果不是對象也會修改,不過會報錯;就算將對象通過data轉成了本地數據,照樣會影響到父級)
// 所以,傳參數時,儘量避免傳遞對象(只是儘量)

// 但是如果我需要傳遞對象,又不想子組件的修改影響到父組件該怎麼辦呢?
// 通過深拷貝,將prop傳遞過來的對象徹底轉換成本地數據
props: ['obj'],
data(){
	return {
		iObj: JSON.parse(JSON.stringify(this.obj))
	}
}

自定義事件


我們可以通過 Prop 實現父組件向子組件傳遞數據,但是,子組件不能直接修改父組件的數據,那如果子組件修改數據後想要在父組件上體現出來,該怎麼處理呢?就通過自定義事件處理;

// 方法中
this.$emit('myEvent', 參數)
// 行間
<div @click="$emit('myEvent', 參數)"></div>

// 監聽
<my-component 
	v-on:myEvent='change'
>
</my-component>
methods: {
	change(str) {
		// str -> 參數
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章