Vue自定义组件
0 注意
1 Object 或 Array类型要用函数接收
如果传递的为Object
或 Array
类型则是用函数接收且要用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
接收的话,会被放置到$listeners
用this.$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(){}
中定义 file
和 src
两个变量 来接收值
<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>