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 -> 参数
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章