Vue自定义组件

0 注意

1 Object 或 Array类型要用函数接收

如果传递的为ObjectArray类型则是用函数接收且要用return返回如:

props: {
			show: {
				type: Boolean,
				default: null
			},

			dialog: {
				type: Object,
				default: () => {return {}}
			}

		},

1 传递方法的放在最后

传递的方法后面放不了传递的数据,会变成灰色且不会被传递。
在这里插入图片描述

1 传值

1 单向绑定传值

值只能由父组件向子组件单向传递
父组件标签中定义 :path="src" ,子组件用props['path'] 接收。

2 双向绑定传值

改动子组件或父组件任何一方的值都会引起另一个值的改变

父组件标签中定义 v-model="form.file" ,子组件用只能用value接收 如props['value'] ,用this.$emit('input',file.raw)修改,即把src的值改为file.raw中的值。

3 同步传值 (vbind + .sync

一般用于传递属性
父组件标签中定义 :show.sync="dialog.show" ,子组件用show接收 type用于定义属性 即数据类型。
this.$emit('update:show', false)修改,即把dialog.show的值改为false

props: {
			show: {
				type: Boolean,
				default: null
			}
		},

3 用v-bind 传的值,没有被props接收的话

用v-bind(等价于:) 传的值,没有被props接收的话,那么就会被放入,$attrs中。
如果还需要向下传递的话那么就v-bind="$attrs"

2 传递方法

父组件标签中定义 @getTableData="getTableData()" ,子组件用this.$emit('getTableData')调用

3 用@ 传递的方法,没有被props接收的话

用@ 传递的方法,没有被props接收的话,会被放置到$listenersthis.$listeners调用。
如果还需要向下传递的话那么就v-on="$listeners"

1 自定义静态组件(此处为一个文件上传组件)

1 在components目录下建一个.vue文件

<template>
	<el-upload 
		action="https://jsonplaceholder.typicode.com/posts/" 
		list-type="picture" :show-file-list="false"
		:auto-upload="false" 
		:on-change="filechange">
		<img v-if="src" :src="src" width="80" height="80" />
		<i v-else style="font-size: 30px;" class="el-icon-picture-outline"></i>
	</el-upload>
</template>

<script>
	export default {
		
//  接收父组件传来的值   
// 第一个是V-modle 双向绑定的值,必须用value接收 (如 v-model="form.file")
//  第二个是v-bind (简写为:)  单向绑定的值   (如   :path="src"  用path 接收 )
		props:['value','path'],
		
		data(){
			return{
				src: ''
			}
			
			
		},
		
//  监控path变量,当path变化时src(图片地址)也跟着变化 
		
		watch: {
			path: {
				handler(newval,oldval){
					this.src = newval
				}
			}
		},
		
// 	绑定 on-change事件(:on-change="filechange")
//  当选照片后,把本第的照片地址放入<img>标签中的 src 下 这样就能显示图片了
//  然后把file文件传输给父组件
		methods:{
			filechange(file){
				this.src = file.url
				this.$emit('input',file.raw)
			}
		}
	}
</script>

<style scoped lang="less">
</style>

2 注册组件

1 注册全局组件(只注册一次)

如果组件要被调用很多次的话,那么就注册在 main.js中。

1 引入组件
import myFileUpload from '@/components/myFileUpload.vue'
2 注册组件
Vue.component('my-fileUpload',myFileUpload)
3 调用组件

注意文件上传要在调用组件的data(){}中定义 filesrc两个变量 来接收值

<my-fileUpload v-model="form.file" :path="src"></my-fileUpload>

2 注册局部组件(每次用的时候都要注册)

<script>
	import myFileUpload from '@/components/myFileUpload.vue'
	
	export default {
		components: {
					myFileUpload
				},
	}			
</script>

1 自定义动态组件(自定义弹窗组件)

意思就是把组件B当成一个属性传入组件A中,并且被组件A调用。

1 创建被传入的组件B

B中一定要有一个prop来接收传递过来的数据,show用来控制弹窗的开启或关闭,dialog属性用来传值的,此处用来传递id这个属性用this.dialog.id来调用。

props: {
			show: {
				type: Boolean,
				default: null
			},

			dialog: {
				type: Object,
				default: () => {return {}}
			}

		},
<template>
	<div>
		<el-button type="primary" plain @click="save">保存</el-button>
	</div>
</template>

<script>
		
	
	export default {
		name: 'brandEdit',
		
	
		//  props 是用于接收父组件传递过来的属性 名称和父组件绑定的属性名一致

		props: {
			show: {
				type: Boolean,
				default: null
			},

			dialog: {
				type: Object,
				default: () => {return {}}
			}

		},


			
		methods: {
			save() {
				this.$refs['edit-form'].validate(valid => {
					if (valid) {
						this.post(this.url.save, this.form, () => {
							this.$emit('update:show', false)
							this.$emit('getTableData')
						})
					}
				})
			},
		}
		

	}
</script>

<style scoped=" lang=" less">

</style>
</script>


2 创建组件A(这个是模板组件 B可以任意换,只要被当成属性放在A中就行)

组件A中的组件用<component>标签来存放,用:is="dialog.component"来绑定

<template>
	<div>
		
		
		
	<el-dialog		
		 :visible.sync="dialog.show" 
		 :title="dialog.title"
		 :close-on-click-modal="false"
		 :width="dialog.width">	
		 
		 <!-- component 动态组件标签  :is专门用来绑定父组件传过来的 组件对象 -->
		 
		 <component 		 
			 :is="dialog.component"
			 :show.sync="dialog.show"
			 :dialog="dialog"
			 v-bind="$attrs"
			 v-on="$listeners">		 
		 </component>
	</el-dialog>
	
	
		
	</div>
</template>

<script>
	
	export default{		
		name: 'MyDialog',		
		
//  接收传递过来的数据 
		props:['dialog'],
		
	}
</script>
	
<style scoped lang="less">
</style>

3 引入组件A并定义属性

标签中一定要包括 v-if="dialog.show":dialog="dialog" @getTableData="getTableData"这三个属性。

	<MyDialog
			v-if="dialog.show" 
			:dialog="dialog" 
			@getTableData="getTableData">
	</MyDialog>

定义一个dialog属性用来传值,B组件被插入dialog.component属性中,此次还传递了一个用于修改的id属性。

<template>
	<div>
	
		
		<MyDialog
			v-if="dialog.show" 
			:dialog="dialog" 
			@getTableData="getTableData">
		</MyDialog>
		
	</div>
</template>

<script>

//引入组件A
	import MyDialog  from '@/components/mydialog.vue'
	
	export default {
		name: 'brandIndex',

//注册组件A
		components: {
			MyDialog,
			
				
		},


		data() {			

//被传递的属性
				dialog: {
					title: '添加品牌',
					show: false,
					id: null,
					width:"600px",
					//被传递的组件
					component: () => import ('./eidt')
				},
				

			}
		},


		methods: {
//被传递的方法
			getTableData() {
				this.get(this.url.page, this.params, response => {
					this.tableData = response
					console.log(response)
				})
			},

		}

	}
</script>

<style scoped lang="less">
		
</style>

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值