数据的传递
每一部分的内容都需要父组件进行传递
- 1)如标题内容 直接使用传递字符串既可
父组件
<template>
<div>
<DialogDemo title="地址"/>
</div>
</template>
子组件
<template>
<div>
<button>阿迪达斯</button>
<div class="mask">
<div class="dialog">
<!-- 每一部分的内容都需要父组件传递 -->
<!-- 1.标题内容 直接传递字符串既可 -->
<div class="dialog-header">{{title}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
props:['title']
}
</script>
================================================================================================
- 2)对话框的内容部分,不确定性太确,它可以展示任何标签, 此时就需要父组件传递插槽给子组件,也就是传递 html 结构个子组件
父组件:
1.
父组件内写在子组件的标签中间
2.
给子组件进行传递 插槽 内容
3.
但需要把标签写成闭合标签
<template>
<div>
<!-- 父组件内写在子组件的标签中间 -->
<!-- 给子组件进行传递 插槽 内容 -->
<!-- 但需要把标签写成闭合标签 -->
<DialogDemo title="地址">
<form action="">
<input type="text">
<input type="text">
</form>
</DialogDemo>
</div>
</template>
子组件:需要在子组件内写
<slot />
进行接收
<template>
<div>
<button>阿迪达斯</button>
<div class="mask">
<div class="dialog">
<!-- 每一部分的内容都需要父组件传递 -->
<!-- 1.标题内容 直接传递字符串既可 -->
<div class="dialog-header">{{title}}</div>
<!-- 2.对话框的内容部分,不确定性太确,它可以展示任何标签,
此时就需要父组件传递插槽给子组件,也就是传递 html 结构个子组件 -->
<div class="dialog-content">
<slot />
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props:['title']
}
</script>
================================================================================================
- 3)当需要分类传递内容的时候
- 我们可以使用 具名插槽来区别(也就是给插槽起名字)
父组件:
1.
在父组件中利用 template 以及 v-slot 给插槽命名
2.
没有起名字的插槽部分 都称为默认插槽 default
<template>
<div>
<!-- 父组件内写在子组件的标签中间 -->
<!-- 给子组件进行传递 插槽 内容 -->
<!-- 但需要把标签写成闭合标签 -->
<DialogDemo title="地址">
<!-- 当需要分类传递内容的时候 -->
<!-- 我们可以使用 具名插槽来区别(也就是给插槽起名字) -->
<!-- 在父组件中利用 template 以及 v-slot 给插槽命名 -->
<template v-slot:cpntent>
<form action="">
<input type="text">
<input type="text">
</form>
</template>
<!-- 没有起名字的插槽部分 都称为默认插槽 default -->
<div>
<button>取消</button>
<button>确定</button>
</div>
</DialogDemo>
</div>
</template>
子组件:在子组件中使用父组件 命名
comtent
插槽
slot 也可以不起名字,因为它获取的是 默认插槽
<template>
<div>
<button>阿迪达斯</button>
<div class="mask">
<div class="dialog">
<!-- 对话框的三部分内容都不是固定的内容 -->
<!-- 每一部分的内容都需要父组件传递 -->
<!-- 1.标题内容 直接传递字符串既可 -->
<div class="dialog-header">{{title}}</div>
<!-- 2.对话框的内容部分,不确定性太确,它可以展示任何标签,
此时就需要父组件传递插槽给子组件,也就是传递 html 结构个子组件 -->
<div class="dialog-content">
<!-- 在子组件中使用父组件命名的 comtent 的插槽 -->
<slot name="cpntent" />
</div>
<div class="dialog-foot">
<!-- slot 可以不起名字,它获取的是 默认插槽 -->
<slot />
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props:['title']
}
</script>
================================================================================================
- 4)
子组件的样式
<style>
.mask {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 999;
background-color: rgba(0,0,0,0.5);
}
.mask .dialog{
position: absolute;
background-color: #fff;
width: 600px;
top: 160px;
left: 50%;
margin-left: -250px;
min-height: 200px;
display: flex;
flex-direction: column;
}
.mask .dialog .dialog-header , .mask .dialog .dialog-foot {
padding: 15px;
border-bottom: 1px solid #ccc;
flex-shrink: 0;
}
.mask .dialog .dialog-header {
display: flex;
justify-content: space-between;
}
.mask .dialog .dialog-header .close{
cursor: pointer;
}
.mask .dialog .dialog-content {
padding: 15px;
border-bottom: 1px solid #ccc;
flex-grow: 1;
}
.mask .dialog .dialog-foot {
display: flex;
justify-content: flex-end;
border-bottom: 0;
}
</style>
================================================================================================
- 5)让我们上面所写的东西先消失,在点击
阿迪达斯
后出现
父组件:
<template>
<div>
<button @click="show = true">阿迪达斯</button> <!--点击时出现-->
...
</div>
</template>
<script>
export default {
...
data() {
return {
show: false
}
}
}
</script>
================================================================================================
- 6)点击灰色的地方以及
×
关闭我们显示的东西
父组件:给父组件定义方法 并且传递给子组件
<template>
<div>
<button @click="show = true">阿迪达斯</button>
...
<!--将它传递给子组件-->
<DialogDemo title="地址" :show="show" @close="close">
<!---->
<!--<DialogDemo title="地址" :show.sync="show"> 也可简写成这样-->
...
</template>
<script>
import DialogDemo from "./components/DialogDemo.vue";
export default {
components: { DialogDemo },
// 定义方法
data() {
return {
show: false,
};
},
methods: {
close() {
this.show = false;
},
},
};
</script>
子组件:接收父组件传递过来的方法
<template>
<!-- 对话框 -->
<!--点击空白的地方 关闭-->
<div v-show="show" class="mask" @click.self="$emit('close')">
<!-- <div v-show="show" class="mask" @click.self="$emit('update:show',false)"> 也可简写成这样-->
.....
<div class="dialog-header">
<span>{{title}}</span>
<!--点击 × 的地方 关闭-->
<span class="close" @click.self="$emit('close')">×</span>
<!-- <span class="close" @click.self="$emit('update:show',false)">×</span> 也可简写成这样-->
</div>
.....
</template>
<script>
export default {
props:['title','show'],
}
</script>
...
================================================================================================
- 7)点击确定先完成信息的确定再关闭,点击取消直接关闭
父组件:
<template>
<div>
...
<div>
<button @click="show = false">取消</button>
<button @click="ok">确定</button>
</div>
</DialogDemo>
</div>
</template>
<script>
...
methods: {
...
// 对确认的信息进行 提示
ok(){
console.log('确定这样做')
this.show = false
}
},
};
</script>
================================================================================================
- 8)当出现弹窗的时候,滚动条不能滑动
在子组件内使用
updated
生命周期功能
<script>
export default {
props:['title','show'],
updated() {
if(this.show){
document.body.style.overflowY = 'hidden'
}
}
}
</script>
如果让滚动条消失,滚动条消失时 页面会重新进行渲染布局
<script>
export default {
props:['title','show'],
updated() {
if(this.show){
// 隐藏滚动条
document.body.style.overflowY = 'hidden'
document.body.style.paddingRight = '17px'
}else{
document.body.style.overflowY = 'scroll'
document.body.style.paddingRight = '0'
}
}
}
</script>
================================================================================================
- 9)使用生命周期来实现监听
使用生命周期
updated
来监听props
的变化
这里我们也可以利用 侦听器来监听,使用watch
侦听器props、data、computed
语法 watch:{监听的内容:函数}
<script>
export default {
props:['title','show'],
watch: {
show(newVal) {
if (newVal) {
document.body.style.overflowY = "hidden";
document.body.style.paddingRight = "17px";
} else {
document.body.style.overflowY = "scroll";
document.body.style.paddingRight = "0";
}
},
},
}
</script>
方法二:
watch:{监听的内容:{ handler:函数,deep:true,immediate:true}}
deep: true,
// 进行深层次侦听值,有些时候值是复杂数据的时候更新某个属性并不会导致侦听器触发,就可以加deep:true
immediate: true
//组件初始时就执行一次侦听函数 (例:打开某一个软件时候的 弹窗)
<script>
export default {
props:['title','show'],
watch: {
show: {
handler(newVal) {
if (newVal) {
document.body.style.overflowY = "hidden";
document.body.style.paddingRight = "17px";
} else {
document.body.style.overflowY = "scroll";
document.body.style.paddingRight = "0";
}
},
// deep: true, // 进行深层次侦听值,有些时候值是复杂数据的时候更新某个属性并不会导致侦听器触发,就可以加deep:true
immediate: true //组件初始时就执行一次侦听函数
},
},
}
</script>
总结
- 插槽的使用:
- 我们可以使用 具名插槽来区别(也就是给插槽起名字)
父组件:
1.
在父组件中利用 template 以及 v-slot 给插槽命名
2.
没有起名字的插槽部分 都称为默认插槽 default
子组件:在子组件中使用父组件 命名
comtent
插槽
slot 也可以不起名字,因为它获取的是 默认插槽
- 侦听器的使用
使用生命周期
updated
来监听props
的变化
这里我们也可以利用 侦听器来监听,使用watch
侦听器props、data、computed
语法 watch:{监听的内容:函数}
方法二:
watch:{监听的内容:{ handler:函数,deep:true,immediate:true}}
deep: true,
// 进行深层次侦听值,有些时候值是复杂数据的时候更新某个属性并不会导致侦听器触发,就可以加deep:true
immediate: true
//组件初始时就执行一次侦听函数 (例:打开某一个软件时候的 弹窗)
总代码
父组件
<template>
<div>
<button @click="show = true">阿迪达斯</button>
<!-- 父组件内写在子组件的标签中间 -->
<!-- 给子组件进行传递 插槽 内容 -->
<!-- 但需要把标签写成闭合标签 -->
<!-- <DialogDemo title="地址" :show="show" @close="close"> -->
<DialogDemo title="地址" :show.sync="show">
<!-- 当需要分类传递内容的时候 -->
<!-- 我们可以使用 具名插槽来区别(也就是给插槽起名字) -->
<!-- 在父组件中利用 template 以及 v-slot 给插槽命名 -->
<template v-slot:cpntent>
<form action="">
<input type="text" />
<input type="text" />
</form>
</template>
<!-- 没有起名字的插槽部分 都称为默认插槽 default -->
<div>
<button @click="show = false">取消</button>
<button @click="ok">确定</button>
</div>
</DialogDemo>
</div>
</template>
<script>
import DialogDemo from "./components/DialogDemo.vue";
export default {
components: { DialogDemo },
data() {
return {
show: false,
};
},
methods: {
// close() {
// this.show = false;
// },
ok(){
console.log('确定这样做')
this.show = false
}
},
};
</script>
<style>
</style>
子组件
<template>
<!-- 对话框 -->
<!--点击空白的地方 关闭-->
<div v-show="show" class="mask" @click.self="$emit('update:show', false)">
<div class="dialog">
<!-- 对话框的三部分内容都不是固定的内容 -->
<!-- 每一部分的内容都需要父组件传递 -->
<!-- 1.标题内容 直接传递字符串既可 -->
<div class="dialog-header">
<span>{{ title }}</span>
<!--点击 × 的地方 关闭-->
<span class="close" @click.self="$emit('update:show', false)">×</span>
</div>
<!-- 2.对话框的内容部分,不确定性太确,它可以展示任何标签,
此时就需要父组件传递插槽给子组件,也就是传递 html 结构个子组件 -->
<div class="dialog-content">
<!-- 在子组件中使用父组件命名的 comtent 的插槽 -->
<slot name="cpntent" />
</div>
<div class="dialog-foot">
<!-- slot 可以不起名字,它获取的是 默认插槽 -->
<slot />
</div>
</div>
</div>
</template>
<script>
export default {
props: ["title", "show"],
// updated() {
// if(this.show){
// // 隐藏滚动条
// document.body.style.overflowY = 'hidden'
// document.body.style.paddingRight = '17px'
// }else{
// document.body.style.overflowY = 'scroll'
// document.body.style.paddingRight = '0'
// }
// },
//> 使用生命周期 `updated` 来监听 `props` 的变化
// > 这里我们也可以利用 侦听器来监听,使用 `watch` 侦听器 一般用零监听 props data computed
// > 语法 watch:{监听的内容:函数}
// watch:{监听的内容:{ handler:函数,deep:true,immediate:true}}
watch: {
show: {
handler(newVal) {
if (newVal) {
document.body.style.overflowY = "hidden";
document.body.style.paddingRight = "17px";
} else {
document.body.style.overflowY = "scroll";
document.body.style.paddingRight = "0";
}
},
// deep: true, // 进行深层次侦听值,有些时候值是复杂数据的时候更新某个属性并不会导致侦听器触发,就可以加deep:true
immediate: true //组件初始时就执行一次侦听函数
},
},
};
</script>
<style>
.mask {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 999;
background-color: rgba(0, 0, 0, 0.5);
}
.mask .dialog {
position: absolute;
background-color: #fff;
width: 600px;
top: 160px;
left: 50%;
margin-left: -250px;
min-height: 200px;
display: flex;
flex-direction: column;
}
.mask .dialog .dialog-header,
.mask .dialog .dialog-foot {
padding: 15px;
border-bottom: 1px solid #ccc;
flex-shrink: 0;
}
.mask .dialog .dialog-header {
display: flex;
justify-content: space-between;
}
.mask .dialog .dialog-header .close {
cursor: pointer;
}
.mask .dialog .dialog-content {
padding: 15px;
border-bottom: 1px solid #ccc;
flex-grow: 1;
}
.mask .dialog .dialog-foot {
display: flex;
justify-content: flex-end;
border-bottom: 0;
}
</style>