Vue学习第五周,组件

1 组件与复用

通过使用组件,实现代码复用。需求变更需要修改功能时,只需要修改一处即可完全修改。但是当一个组件复用的次数变多后,不同的功能就会因为组件耦合在一起。遇到需要针对单个功能进行修改组件的时候,就需要慎之又慎,防止对其他功能造成影响。
vue组件创建

<div>
	<test></test>
</div>
	Vue.component('test',{
		template:'<div>测试</div>'
	})

以上是定义在页面内部的组件。但是我通常使用webpack结构的工程,组件直接定义成一个单独的*.vue文件,当需要使用组件时直接在对应的页面通过import关键字引入,然后注册在components属性中。
vue文件格式如下

<template>
	<div></div>
</template>
<script>
	//这里可以使用import引入方法、对象、组件等等,或者定义方法、属性
	export defaut{
	//这里定义组件相关的属性。包括数据、方法、生命周期函数、父组件传入数据、组件名等
	}
</script>

一个template中最多只能有一层div,其他的元素都需要定义在该div中。另外如果没有export关键字,组件无法被其他的页面调用。组件的data属性需要定义成function的形式,data中定义的数据只对当前组件有效。当组件被复制了多份,组件之间的数据相互独立,如果需要进行数据共享可以将数据定义在外部。

外部调用组件的时候还可以通过is关键字将dom元素替换为组件定义的元素。

2 组件传值

2.1 父组件向子组件传值

当一个组件中调用另一个组件,则前者被称为父组件,后者称为子组件。父组件通过props关键字传值到子组件,如果不用v-bind绑定则该值只会被传一次,不会数据双向绑定(即父组件的数据如果改变了,不会对已经渲染后的子组件产生效果)。不用v-bind还会导致传入的值的数据类型变成String。

<test msg="message"></test>
<test :msg="message"></test>
<template>
	<div>{{msg}}</div>
</template>
<script>
export default{
props:[msg]
//props:{
//		msg:String,
//		hasMes:[Boolean,Number],
//		msgDetail:{
//			type:Array,
//			required:true
//		}
//}
}
子组件的props属性可以定义为数组或者对象。定义为对象时,需要设置传入字段的数据类型,数据类型可以定义多个。

• String
• Number
• Boolean
• Object
• Array
• Function

props属性传值,默认是从父到子组件单向的。vue1的时候,可以通过.sync关键字双向绑定,当时vue2取消了这个。

2.2 子组件向父组件传值

子组件通过 e m i t 函 数 将 数 据 提 交 到 父 组 件 。 emit函数将数据提交到父组件。 emitemit方法有两个参数,第一个是字符串,代表事件名,第二个是提交的数据。当父组件中定义了v-on对应的事件后,可以直接使用方法获取子组件提交的值。

<test @submit="sumbitValue"></test>

methods:{
	submitValue(value){
		console.log(value);
	}
}

this.$emit('submit',123);

$emit也可以提交input事件,父组件中使用v-model来将子组件中的值绑定到父组件的值上。

2.3 非父子组件之间传值

vue1的时候,定义了 d i s p a t c h ( ) 和 dispatch()和 dispatch()broadcast(),分别用于向上级、下级进行广播事件,事件发出后按就近原则被该方向上最近的组件捕获,且被接受一次后就停止广播。Vue2的时候把这些都废除了,按树形结构传值理解不方便且不能解决同级组件之间传值的问题。
vue2推出了bus的方式,通过创建一个空的vue实例(bus,中央事件总线)用于管理所有事件。所有事件通过bus进行寻找或者接受事件。

var bus = new Vue();

bus.$emit('submit',123);
bue.$on('submit',function(value){
	console.log(value);
})

当协同开发时,需要共享值或者方法等等,可以使用bus。但是eventbus这个东西也差不多不怎么用到,我用vuex插件会比较多一些。

还可以通过以下两个函数直接获取父子组件,从而获取并修改其中的值。但是这样会导致逻辑混乱,各个组件之间耦合在一起。所以最好还是通过props和$emit传值。

this.$parent().message
this.$children()

因为子组件可能有多个,所以$children函数用起来不是很方便。

为了精确定位子组件,还有一个$ref函数。

<test ref = "child"></test>
this.$refs.child.message="i am a child";

$refs 渲染完成后才填充,并且它是非响应式的. 它仅仅作为一个直接访问子组件的应急方案,应当避免在模板或计算属性中使用。

3 内容分发slot

当需要让组件组合使用,混合父组件的内容与子组件的模板时,就会用到slot, 这个过程叫作内容分发(transclusion)

<child-component> 
	{{message }} 
</child-component> 

这里的message是一个slot,绑定父组件的数据。当父组件定义了slot,子组件的内容中如果定义了元素就会被替代掉。slot可以定义name属性,当父组件中指定了slot属性后,子组件就会根据slot关联替换对应的元素。

<div slot="footer">底部信息</div>

<slot name = "footer"></slot>

slot还可以通过props来传值。

<child-component>
	<p>{{ props.msg }}</p>
</child-component>
<slot msg="来自子组件的内容"></slot>

4 组件递归

组件可以递归调用自己本身,但是需要设置name属性,并且搭配v-if限制递归次数。

5内联模板

组件标签可以添加inline-template属性,从而将内容当做模板,而不将内容分发。在父组件中声明的数据message和子组件中声明的数据msg,两个都可以渲染(如果同名,优先使用子组件的数据)。
这是内联模板的缺点,作用域比较难理解,如果不是非常特殊的场景,不要轻易使用内联模板。

6 动态组件

通过is属性,可以实现组件动态切换。

<component :is="currentView"></component>

components:{
	comA:{
		template:"<div>A</div>"
	},
	comB:{
		template:"<div>B</div>"
	}
}

change:funciton(componentName){
	this.currentView = componentName;
}

7 异步组件

组件可以通过resolve,reject方法实现异步加载。但是有了webpack和.vue类型的文件,直接写路由会更加方便。

8 $nextTick

vue会异步更新dom元素,$nextTick能在异步更新完毕后执行js。主要用于搭配第三方库,我主要用到swiper,echarts。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值