文章目录
- 需求及效果
- 遇到的问题
- 解决的办法
- 偷懒的写法
需求及效果
uView(1.x版本)中, 有Pop弹出层的组件, 现在有个需求是,进行简单封装,有些通用的设置不想每次都写(比如 :mask-custom-style="{background: 'rgba(0, 0, 0, 0.7)'}"
这种)
然后内部内容交给插槽去自己随意发挥.
遇到的问题
子组件封装内部
<template>
<!-- 通用搜索框-其内容自定义 -->
<u-popup v-model="isShow" mode="center" border-radius="20" :width="width"
:mask-custom-style="{background: 'rgba(0, 0, 0, 0.7)'}" @close="close">
<slot name="content"></slot>
</u-popup>
</template>
<script>
子组件调用
<!-- 清除搜索记录弹框 -->
<centerPopup :isShow="show">
</centerPopup>
然后说我们就可以通过 show这个状态去控制, 但此时我们会遇到一个报错
Avoid mutating a prop directly since the value will be overwritten whenever the parent component
简单来说
就是涉及到了 props单向传递, 与v-model产生了冲突
这里就相当于, 子组件也去更改了isShow
这个props,这显然是不允许的
解决的办法
网上搜索就能看到很多关于 props
+ v-model
双向绑定帖子
比如: props+v-model——父子双向通信
基本就可以处理解决了
偷懒的写法
再进一步, 上面的写法也有点麻烦
再看这个地方, 是不是想到.sync
语法糖
所以,进行双向绑定的办法如下:
子组件
<template>
<!-- 通用搜索框-其内容自定义 -->
<u-popup v-model="isShow" mode="center" border-radius="20" :width="width"
:mask-custom-style="{background: 'rgba(0, 0, 0, 0.7)'}" @close="close">
<!-- 自定义内容插槽 -->
<slot name="content"></slot>
</u-popup>
</template>
<script>
/**
* 通用 center型 - popup弹框, 其内容slot定义,
* 仅提供通用的样式
*
*/
export default {
name: 'centerPopup',
data() {
return {
isShow: false,
}
},
props: {
centerPopShow: {
type: Boolean,
default: false
},
width: {
type: [String, Number],
default: '590'
}
},
watch: {
centerPopShow: {
handler: function(nv, ov) {
this.isShow = nv;
}
}
},
methods: {
close() {
this.$emit("update:centerPopShow", false)
}
}
}
</script>
<style>
</style>
用watch观察props:centerPopShow
, 来驱动 v-mode:isShow
进行状态变更
用.sync
语法糖的写法, 来通知父组件的props:centerPopShow
来同步状态的变化
父组件
<centerPopup :centerPopShow.sync="cleanpopshow">
</centerPopup>
=>pop弹窗弹出, 只要设置 this.cleanpopshow=true
即可
=>pop弹窗隐藏, 只要设置 this.cleanpopshow=false
即可