封装elUI-dialog弹窗
新建教师(teacher.vue)弹窗增删改查
(以教师弹窗增删改查为例)
在弹窗里(index.vue)引入组件 由于组件会越来越多
于是建立了一个collections.js用来输出所有组件
(这个collection.js用来收集内容组件的)
import Teacher from './contents/Teacher'
import Activity from './contents/Activity'
import Examination from './contents/Examination'
import SchoolOrganization from './contents/SchoolOrganization'
import StudentCadre from './contents/StudentCadre'
import UserAccount from './contents/UserAccount'
export default {
Teacher,
Activity,
Examination,
SchoolOrganization,
StudentCadre,
UserAccount
}
在弹窗里(index.vue)引入组件
import Contents from './collection'
可是我们会发现问题
如果我有很多类型的弹窗
例如修改教师内容的弹窗,或者修改学生内容的弹窗
那么就要引入很多个组件
所以我们这里换成另一种方式
首先,我们在调用$dialog的时候加多个参数 界面下的方法,比如view/teacher.vue
// 新增
add () {
this.$dialog({
// 我们想把这些信息传入弹窗内容里面 定义成一个对象---
name: 'Teacher',
title: '新增教师',
propsData: {
teacherName: '黄老师',
age: 18,
sex: 'Female'
},
methods: {
sayHello () {
console.log('Hello')
},
sayWorld () {
console.log('World')
}
}
})
},
告诉弹窗说我要打开教师的弹窗
然后弹窗接收到这个name
之后,就去动态的去读取组件,然后添加进去
这是我们的思路
接下来,接收参数的方法
在封装弹窗(register.js)里面
用propsData
去接收参数
小结:
- 调用this.$dialog就是register.js注册的方法
- 然后register.js动态挂载了 Dialog/index.vue 的组件进去html
- 现在name参数接收到了
- 我们就要通过name,去实现,显示不同的组件
上面提及:这个collection.js用来收集内容组件的
如何显示呢
新知识点 component 标签
这个name就是你调用的时候,传入进来的name
然后页面上
你想打开什么样的弹窗,只需要传递name
想要显示什么样的title,只需要传递过去就好了
例如我们弹窗的使用就通过$dialog 方法去打开
那我现在有个需求
就是我调用的时候要传递参数进去到你的内容组件里
我弹窗想接收一个参数,要怎么做
因为,我们每个弹窗可能的应用场景都不一样
例如有些弹窗显示一些内容,
有的弹窗显示一些按钮或者输入框
所以,我们弹窗内容要接收调用时传递进来的参数
例如我们想把这些信息传入弹窗内容里面
我们定义成一个对象
然后让注册器(register.js–封装弹窗的地方)帮忙接收一下
顺便设置一个默认值把
如果调用的时候不传递参数的话,就默认是个空对象
这样,我们就实现了,在调用的时候,直接传递参数给内容了
新知识点,就是v-bind=""
这个可以绑定一个对象
就不用像之前那样,我们传递参数还要一个一个写 :teacherName="" :age="" :sex=""
在弹窗里面(index.vue)进行相对应的绑定和接收
界面中的propsData
与组件对应
例如这 name, title, propsData
分别是,弹窗内容组件的Name,弹窗的标题,还有弹窗接收的参数
例如我们组件传参有父传子,子传父
那我们这里,我们子组件接收了 props,
实现了类似父传子的传参了
我们想子传父怎么办
用emit:就是自定义事件
我们子组件里面先给个按钮,绑定个事件,然后执行emit,我们想执行传入的方法
<script>
export default {
// props 接收父组件传递的参数
props: ['teacherName', 'age', 'sex'],
methods: {
submit () {
this.$emit('sayHello')
this.$emit('sayWorld')
},
close () {
this.$emit('hide')
}
}
}
</script>
例如这里
我们用一个方法对象用来存放方法
然后,我想在内容组件里执行这个方法
所以,这里,我们还是要通过注册器帮忙传递一下
我们通过show方法传递
然后我再这里去接收我传递进来的方法
然后我再这里去接收我传递进来的方法
然后我们需要循环这个对象,然后动态的绑定进去
我们要给组件用js绑定事件的前提是事件要先挂在到dom上
首先,我们先获取内容的节点发现输出的是undefined
说明,我们在执行这个show方法的时候,这个内容没有被挂载上去
获取不到怎么办
用一个知识点—叫nextTick
- 因为$nextTick里面是在下一次事件循环的时候执行的
- 所以,在下一次事件循环的时候,内容组件已经被挂载了
- 所以就能获取到内容
控制台打印出来之后显示:
说明
这个就是一个组件对象来的
是个VueComponent对象
然后循环
然后用$on 把 方法绑定进去
this.$nextTick(() => {
// console.log(this.$refs.content)
for (let key in methods) {
// 用$on 把 方法绑定进去
this.$refs.content.$on(key, methods[key])
}
})
这样,我们就能在emit 去调用了
再添加一个小功能
我想在内容组件里面去关闭弹窗
我们只需要单独的,再注册多一个事件给内容 @hide=‘hide’
然后内容里面调用$emit(‘hide’)就能触发
<template>
<el-dialog :title="title" :visible.sync="visible" @close="closed" :append-to-body="true">
<components ref="content" :is="name" v-bind="contentPropsData" @hide='hide'></components>
</el-dialog>
</template>
hide () {
this.visible = false
},
思考:
1:为什么这样去用element-ui的弹窗
2:怎么使用
3:怎么实现
如果不封装成方法去调用,你使用这个弹窗是需要el-dialog标签的
正常情况下,我们使用element-ui的弹窗,是要在使用的页面去写入这个组件的
封装之后
页面 、弹窗、弹窗内容 分开了
这样,我们只需要关心,页面跟弹窗的内容,就行了
页面通过$dialog 方法去唤起弹窗,然后我们只需要在弹窗内容里面写我们弹窗的东西
就不用再去关心给弹窗绑定这个visible,等等多余的东西
没有了这些,页面代码看起来更加清爽
即:只需要在contents文件里面添加组件,就能通过$dialog传入不同的name,打开这个弹窗,就能自动把这个组件引入了
我这样封装好之后,我打开弹窗就不需要再去碰el-dialog了
- 我只需要在contents文件夹里面添加好组件
- 在collection.js里面引入注册好这个组件就行了
- 页面里就能把这个组件用弹窗的方式打开