项目需求:点击页面的 品牌型号 按钮,打开弹框,将 车架号码 参数传入接口获取到对应的 品牌型号列表,在进行选择后关闭弹框。
实际开发中,我在父组件里面引入了弹框子组件;诡异的事情发生了:
在小程序页面有两个问题1.已开始进入到父组件时候,就自动触发了子组件弹框的created()事件;2.但是在使用uni-app的弹框组件uni-popup-dialog时候,当点击父组件打开弹框时候,子组件弹框是打开了,但此时既不触发created(),也不触发onLoad();
在H5浏览器页面,点击打开按钮,是正常触发created(),但是也不触发onload();
此时我就不知道在小程序的什么位置写打开弹框调用接口事件了;
H5解决方法:就是通过正常的created()即可: 暂未书写
小程序的解决办法通过refs解决: 如下
1.父组件A代码:
1.1打开弹框的按钮和事件
<view v-if="!typeval" @click="changeCarnum" class="libox">
<uni-icons type="arrowright" color="#ddd" />
<text class="t1" v-if="formData.car_model_no">{{car_model_noInfo}}</text>
<text class="t2" v-else>请选择</text>
</view>
changeCarnum() {
console.log('点击打开');
this.$refs.dialogCarnum.open()
console.log(this.$refs);//打印发现当前页的所有弹框
console.log(this.$refs.dialogSonName);//自己的ref
console.log(this.$refs.dialogCarnum);
/* #ifdef MP-WEIXIN */
// 只兼容微信小程序的弹框触发事件
this.$refs.dialogSonName.first()//调用自己的接口方法
/* #endif */
},
1.2父组件A中引入的弹框代码子组件(注意点:原来uni-app只会给uni-popup加ref,但是这里需要同时给引入的子组件加上自己的ref,既ref=“dialogSonName”)
<!-- 车辆型号弹框 -->
<uni-popup id="dialogCarnum" ref="dialogCarnum" type="dialog" @change="change">
<mycarnum ref="dialogSonName" mode="input" :frame_no='formData.frame_no' :car_model_no="formData.car_model_no" :value="inputValue" @close="dialogCloseCarnum" @confirm="dialogInputConfirmCarnum"></mycarnum>
</uni-popup>
**2.自己的子组件B代码:**引入了接口方法和uni-app弹框的popup.js文件,子组件内存在first()方法,每次打开弹框都会触发first();其实就相当于自己的created()效果;如果想要做一些初始化就在first()方法内调用既可以。
<template>
<view class="uni-popup-dialog">
<view v-if="mode === 'base'" class="uni-dialog-content">
<slot>
<text class="uni-dialog-content-text">{{content}}</text>
</slot>
</view>
<view v-else class="uni-dialog-content">
<view class="allbox">
<view class="top">
<view @click="changeNum(1)" :class="{bgblue:indexNum == 1}" class="l">用车架号码搜索</view>
<view @click="changeNum(2)" :class="{bgblue:indexNum == 2}" class="r">用品牌型号搜索</view>
</view>
<view class="bot">
<view class="all">
<uni-easyinput v-if="indexNum == 1" class="myinput" prefixIcon="search" v-model="searchval" :placeholder="placeholder1"></uni-easyinput>
<uni-easyinput v-if="indexNum == 2" class="myinput" prefixIcon="search" v-model="searchval2" :placeholder="placeholder1"></uni-easyinput>
<text class="sreachbtn" @click="scan">搜索</text>
</view>
<!-- <view class="searbox">搜索</view> -->
</view>
<scroll-view class="listbox" scroll-y="true">
<view @click="selectInfo(item)" class="li" v-for="(item ,index) in listArr" :key="index">
{{item.description}}
</view>
</scroll-view>
</view>
</view>
<view v-if="point" class="uni-dialog-content-point">
<view>提示:{{point}}</view>
</view>
<view class="uni-dialog-button-group">
<view class="uni-dialog-button delbtn" @click="closeDialog">
<uni-icons class="uni-dialog-button-text" type="close" size="25" color="#fff" />
</view>
<!-- <view class="uni-dialog-button uni-border-left" @click="onOk">
<text class="uni-dialog-button-text uni-button-color">保存</text>
</view> -->
</view>
</view>
</template>
<script>
import { etCarModelNoInfo } from "@/pages/api/add-car"
import popup from '../../uni-popup/popup.js'
/**
* PopUp 弹出层-对话框样式
* @description 弹出层-对话框样式
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} value input 模式下的默认值
* @property {String} placeholder input 模式下输入提示
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} mode = [base|input] 模式、
* @value base 基础对话框
* @value input 可输入对话框
* @property {String} content 对话框内容
* @property {Boolean} beforeClose 是否拦截取消事件
* @event {Function} confirm 点击确认按钮触发
* @event {Function} close 点击取消按钮触发
*/
export default {
name: "uniPopupDialog",
mixins: [popup],
props: {
car_model_no: {
type: [String, Number],
default: ''
},
frame_no: {
type: [String, Number],
default: ''
},
value: {
type: [String, Number],
default: ''
},
placeholder: {
type: [String, Number],
default: '请输入内容'
},
type: {
type: String,
default: 'error'
},
mode: {
type: String,
default: 'base'
},
title: {
type: String,
default: '提示'
},
point: {
type: String,
default: ''
},
content: {
type: String,
default: ''
},
beforeClose: {
type: Boolean,
default: false
}
},
data() {
return {
searchval: '',
searchval2: '',
dialogType: 'error',
focus: false,
val: "",
indexNum: 1,
placeholder1: '输入车架号',
infObj: {},
listArr: [
]
}
},
watch: {
// frame_no(val) {
// console.log('车架号码frame_no ', val);
// },
type(val) {
this.dialogType = val
},
mode(val) {
if (val === 'input') {
this.dialogType = 'info'
}
},
value(val) {
this.val = val
}
},
onLoad() {
console.log('弹框的onloaa');
uni.$on('eventfirst', this.first())
// // 对话框遮罩不可点击
// this.popup.disableMask()
// // this.popup.closeMask()
// if (this.mode === 'input') {
// this.dialogType = 'info'
// this.val = this.value
// } else {
// this.dialogType = this.type
// }
// if (this.indexNum == 1) {
// this.searchval = this.frame_no || ''
// } else if (this.indexNum == 2) {
// this.searchval2 = this.car_model_no || ''
// }
// this.getlist()
},
created() {
console.log('弹框的created');
// // 对话框遮罩不可点击
// this.popup.disableMask()
// // this.popup.closeMask()
// if (this.mode === 'input') {
// this.dialogType = 'info'
// this.val = this.value
// } else {
// this.dialogType = this.type
// }
// if (this.indexNum == 1) {
// this.searchval = this.frame_no || ''
// } else if (this.indexNum == 2) {
// this.searchval2 = this.car_model_no || ''
// }
// this.getlist()
},
mounted() {
this.focus = true
},
methods: {
first() {
console.log('父组件触发子组件的first方法');
// 对话框遮罩不可点击
this.popup.disableMask()
// this.popup.closeMask()
if (this.mode === 'input') {
this.dialogType = 'info'
this.val = this.value
} else {
this.dialogType = this.type
}
// if (this.indexNum == 1) {
this.searchval = this.frame_no || ''
// } else if (this.indexNum == 2) {
this.searchval2 = this.car_model_no || ''
// }
this.getlist()
},
scan() {
console.log('点击搜搜');
this.getlist()
},
confirm(e) {
console.log(e.detail.value);
},
getlist() {
let params = {}
if (this.indexNum == 1) {
params = {
query_type: 'FRAME_NO',
frame_no: this.searchval,
}
} else if (this.indexNum == 2) {
params = {
query_type: 'CAR_MODEL_NO',
car_model_no: this.searchval2,
}
}
etCarModelNoInfo(params).then(res => {
this.listArr = res.data
if (res.return_code == '-1') {
uni.showToast({
title: res.return_message,
duration: 1500,
icon: 'none'
});
}
})
},
changeNum(num) {
this.indexNum = num
if (num == 1) {
this.placeholder1 = '输入车架号'
} else if (num == 2) {
this.placeholder1 = '输入品牌型号的部分英文和数字'
}
this.getlist()
},
iconClick(type) {
uni.showToast({
title: `点击了${type === 'prefix' ? '左侧' : '右侧'}的图标`,
icon: 'none'
})
},
selectInfo(item) {
console.log(item);
this.infObj = item
this.onOk()
},
/**
* 点击确认按钮
*/
onOk() {
if (this.mode === 'input') {
this.$emit('confirm', this.infObj)
} else {
this.$emit('confirm')
}
// 这个是真正的关闭弹框操作
// if (this.beforeClose) return
// this.popup.close()
},
/**
* 点击取消按钮
*/
closeDialog() {
this.$emit('close')
if (this.beforeClose) return
this.popup.close()
},
close() {
this.popup.close()
}
}
}
</script>
<style lang="scss" scoped>
.bgblue {
height: 86rpx;
color: #108ee9 !important;
border-bottom: 2px solid #108ee9 !important;
box-sizing: border-box !important;
}
.uni-popup-dialog {
width: 300px;
border-radius: 15px;
background-color: #fff;
}
.uni-dialog-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 15px;
padding-bottom: 5px;
}
.uni-dialog-title-text {
font-weight: 700;
font-family: PingFangSC-Regular;
font-size: 36rpx;
color: #000 !important;
letter-spacing: 0;
text-align: center;
line-height: 36rpx;
}
.uni-dialog-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
padding: 5px 15px 15px 15px;
}
.uni-dialog-content-text {
font-size: 14px;
color: #6e6e6e;
}
.uni-dialog-content-point {
color: #f86e21;
padding: 0 15px 15px 15px;
view {
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: #f86e21;
letter-spacing: -0.58px;
}
}
/deep/.uni-dialog-button-group {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
border-top-color: #f5f5f5;
border-top-style: solid;
border-top-width: 1px;
border-top: none !important;
position: relative !important;
}
// 自定义样式
.delbtn {
position: absolute !important;
top: 50rpx !important;
transform: translate(-50%, 0) !important;
margin-left: 50% !important;
}
// 自定义样式
.uni-border-left {
border-left: none !important;
}
.uni-dialog-button {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
height: 45px;
}
.uni-border-left {
border-left-color: #f0f0f0;
border-left-style: solid;
border-left-width: 1px;
}
.uni-dialog-button-text {
font-family: PingFangSC-Regular;
font-size: 36rpx;
color: #108ee9;
letter-spacing: 0;
text-align: center;
line-height: 36rpx;
}
.uni-button-color {
color: #007aff;
}
.uni-dialog-input {
flex: 1;
font-size: 14px;
border-top: 1px #eee solid;
height: 40px;
padding: 0 10px;
color: #555;
}
.uni-popup__success {
color: #4cd964;
}
.uni-popup__warn {
color: #f0ad4e;
}
.uni-popup__error {
color: #dd524d;
}
.uni-popup__info {
color: #909399;
}
//
.uni-dialog-content {
width: 100% !important;
padding: 0 !important;
}
.allbox {
width: 100% !important;
height: 750rpx;
.top {
height: 84rpx;
line-height: 84rpx;
overflow: hidden;
.l,
.r {
text-align: center;
float: left;
width: 50%;
border-bottom: 1px solid #ddd;
font-family: PingFangSC-Regular;
font-size: 30rpx;
color: #303030;
}
}
.bot {
padding: 30rpx;
display: flex;
.all {
width: 100%;
// /deep/.uni-navbar__header-btns-left {
// display: none !important;
// }
/deep/.myinput {
// flex: 1;
width: 80%;
display: inline-block;
border-radius: 20px !important;
}
.sreachbtn {
width: 15%;
padding-left: 5%;
display: inline-block;
color: #108ee9;
}
}
/deep/.uni-easyinput__content {
border-radius: 20px !important;
}
.searbox {
width: 70rpx;
line-height: 70rpx;
text-align: center;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #108ee9;
}
}
.listbox {
width: 100%;
// padding: 0 30rpx!important;
height: 500rpx;
overflow: scroll;
.li {
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #212121;
letter-spacing: 0;
line-height: 40rpx;
padding: 30rpx 30rpx;
border-bottom: 1px solid #ccc;
}
}
.input-view {
/* #ifndef APP-PLUS-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex: 1;
background-color: #f8f8f8;
height: 30px;
border-radius: 15px;
padding: 0 15px;
flex-wrap: nowrap;
margin: 7px 0;
line-height: 30px;
}
.input-uni-icon {
line-height: 30px;
}
.nav-bar-input {
height: 30px;
line-height: 30px;
/* #ifdef APP-PLUS-NVUE */
width: 370rpx;
/* #endif */
padding: 0 5px;
font-size: 14px;
background-color: #f8f8f8;
}
.example-body {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
padding: 0;
}
}
</style>