Vue开发中遇到问题记录

Vue开发中遇到问题记录


本篇是记录Vue真实开发中遇到的一些问题的记录,本人并非前端开发工程师,在Vue开发中也是摸爬滚打,博客为了不遗忘和加深记忆,所以本篇博客会随时更新。
注意:以下代码经过封装并且精简过的伪代码,不能够直接使用,仅提供思路

实现弹窗问题记录

场景:两个按钮点击之后出现的两个弹窗属于同一组件,通过dialogType来判断弹窗类型,然后通过传递不同的参数来控制隐藏、必填等操作。
需求:整个功能由三个组件构成:list、card、dialog,其中list是card列表,card展示内容,dialog是自定义弹窗。card上面存在两个按钮,分别是"退订",“退款”,要求是点击退订按钮时弹窗,弹窗内容为退订原因选择列表和退订说明输入框,同时退订原因必选;点击退款按钮时弹窗,弹窗内容为退订说明,退订说明要根据已存在的退订原因来判断是否必填(退订原因不展示)。
实现思路:退订按钮和退款按钮因为在同一个card中,所以需要的数据和内容基本上都是一样的,所以退订弹窗和退款弹窗共用一个自定义弹窗组件
弹窗实现: 弹窗实现以下几个步骤:
1、弹窗组件创建
通过需求进行组件内容组合,退订说明二者都需要,所以必须保留,其次退订原因是退订弹窗需要的,也必须保留,代码如下:

<template>
  <div class="compose">
    <div class="yd-confirm-hd label" >
      <strong class="inputWriteMust tips">请选择退订原因</strong>
      <!-- <p class="tipsText">请选择退订原因:</p> -->
    </div>
    <yd-radio-group
      class="confirmbds"
      v-model="checkId"
    >
      <div v-for="(item, index) in radioList" :key="index">
        <div class="flex">
          <yd-radio class="radios" :val="item.ID"></yd-radio>
          <div>
            {{ item.ID}}
          </div>
        </div>
      </div>
    </yd-radio-group>
    <div class="confirmbds">
      <input-cell
        label="退订说明"
        v-model="textContent"
        type="textarea"
        rows="5"
        cols="3"
      />
    </div>
    <div class="confirmSelect">
      <button @click="cancel()" class="cancel">取 消</button>
      <button @click="define(checkId)" class="define">确 定</button>
    </div>
  </div>
</template>

2、弹窗展示
弹窗展示使用popup公共组件,该组件通过v-model:visible=“” 来控制隐藏/显示,在代码中通过对isPopupDisplay的改变就能够来控制弹窗展示了。
在下述代码中,使用card通过this.$emit(“showPopup”, data)向list传递dialog需要的数据,此时我们可以通过在传递的数据中添加dialogType属性让dialog来判断弹窗类型是退订还是退款。
同时通过this.$refs.dialog.getReasonsList()调用dialog中的获取退订原因的请求。
3、数据传递
完成数据传递,弹窗功能就算完成了,但是在控制必选的过程中出现了问题。因为mounted使用props属性不起作用,原因通过百度说是props可能会通过请求获取数据再传递给子组件,而mounted使用时props可能还没有完成请求而导致mounted使用的数据是默认数据(null)。
针对这个问题我试验过多个方案,但是都没有完美解决,比如通过监视props数据,发现props有值时给mustWriteTag(必填校验字段)和textContent(退订说明)的赋值,但会出现只触发一次的情况(props传值是在list触发的,需要刷新list页面才会再次传值,这显然不符合需求)。
最终我通过$refs传递数据,发现完美解决了该问题。通过this.$refs.dialog定位到子组件,然后可以获取到对应属性,这样就能够完成mustWriteTag和textContent的条件赋值了。

总结:
可以使用很多方式进行传值,常见的this.$emit(),prosp、this.$refs.xxx.xxx。
1、之所以不能够使用props传递数据原因:必填校验的控制以及退订说明的赋值不是简单的v-if和v-model就能实现的(如果能使用v-if和v-model实现就可以直接通过props传递数据就行了),而是条件赋值
2、可以通过this.$refs.ref调用对应子组件的方法和属性,完成属性赋值和方法调用
list.vue

		<card
            type="check"
            @showPopup="isShowPopup"
          />
    <yd-popup v-model="isPopupDisplay" position="center" width="80%">
      <Dialog ref="dialog"
        @backHandles="isPopupDisplay = false" />
    </yd-popup>
<script>
method:{
    isShowPopup(data){
      if(data.dialogType == '1'){
        this.$refs.dialog.getReasonsList();
      }
      setTimeout(() =>{
        this.isPopupDisplay = true;
      }, 200)

      // 将card回传过来的客户信息赋值并传给弹窗
      this.currentDialogInfo = data;
      if (this.currentDialogInfo.dialogType == '0' && this.currentDialogInfo.paramCategory == '10041001'){
        this.$refs.dialog.mustWriteTag = this.currentDialogInfo.paramCategory;
      }
      // 当弹窗类型为同意退款,并且存在退订说明时,textContent修改为当前退订说明
      if(this.currentDialogInfo.dialogType == '0' && this.currentDialogInfo.unsubscriptionExplain != ''){
        this.$refs.dialog.textContent = this.currentDialogInfo.unsubscriptionExplain;
      }
},
    updateDataList() {
      this.resetData(xxx)  //重置页数数据
      this.getData()
    },
     </script>

card.vue

<template>
        <div class="buttonList flex" >
          <hz-button  
            name="退款"
            @handleClick="setRefundConfirm(data)"
          />
        <div>
            <hz-button
              name="退订"
              @handleClick="setCancel(data)"
            />
</template>
<script>
method:{
	setRefundConfirm(data) {
      if (!data.soNo) {
        this.showDialog(this.soNoError);
        return;
      }
      data.dialogType = '0';
      this.$emit("showPopup", data);
},
    setCancel(data) {
      if (!data.soNo) {
        this.showDialog(this.soNoError);
        return;
      }
      data.dialogType = '1';
      this.$emit("showPopup", data);
</script>

dialog.vue

<template>
  <div class="compose">
    <div class="yd-confirm-hd label" >
      <strong class="inputWriteMust tips">请选择退订原因</strong>
      <!-- <p class="tipsText">请选择退订原因:</p> -->
    </div>
    <yd-radio-group
      class="confirmbds"
      v-model="checkId"
    >
      <div v-for="(item, index) in radioList" :key="index">
        <div class="flex">
          <yd-radio class="radios" :val="item.ID"></yd-radio>
          <div>
            {{ item.ID}}
          </div>
        </div>
      </div>
    </yd-radio-group>
    <div class="confirmbds">
      <input-cell
        label="退订说明"
        v-model="textContent"
        type="textarea"
        rows="5"
        cols="3"
        :inputWriteMust="this.mustWriteTag == 10041001" 
      />
      <!-- inputWriteMust是必填字段校验 -->
    </div>
    <div class="confirmSelect">
      <button @click="cancel()" class="cancel">取 消</button>
      <button @click="define(checkId)" class="define">确 定</button>
    </div>
  </div>
</template>
<script>
data() {
        return {
            checkId:"",
            mustWriteTag: "",
            radioList:[],
            textContent:'',
        };
    },
    props:{
        tipsText:{
            type:String
        },
        currentDialogInfo: {
            type: Object,
            default:()=>{ }
        },
        isShowExplain:{
            type: Boolean
        }
    },
	method:{
	    // 获取退订原因
        getReasonsList(){
            let vm = this;
            this.$api.list.getReasonsList().then((result) => {
                vm.radioList = result.dataInfo;
            }).catch((err) => {
                console.log(err);
            });
        },
	}
</script>

4、关闭弹窗
通过this.$emit(‘backHandles’)将弹窗隐藏/显示字段置为false,弹窗就关闭了,发送请求,根据请求成功/失败来进行不同的操作。
值得注意的是要将data中使用的控制字段、输入字段置空,否则会出现下次点击,弹窗展示的数据依旧是上次的数据。

<script>
method:{
// 取消按钮
cancel(){
  this.checkId = "";
  this.textContent = "";
  this.mustWriteTag = "";
  this.$emit("backHandles");
},
// 确定按钮,处理逻辑
define(checkId){
            if (this.currentDialogInfo.dialogType == '1'){
                if(!checkId){
                    this.showDialog("请选择退订原因!");
                    return;
                }
                if(this.mustWriteTag == "10041001" && isNull(this.textContent)){
                    this.showDialog("请填写退订说明");
                    return;
                }
                // 关闭当前页面
                this.$emit('backHandles');
                let _this = this;
                //需传入线索ID,订单号,操作类型, 驳回操作时选用户填了驳回备注也需要传入
                let v = this.currentDialogInfo;
                const params = {
                };
                _this.$dialog.loading.open("处理中");
                _this.$api.retailOrder
                .retailOrderPost("xxx", params)
                .then((res) => {
                    _this.$dialog.loading.close();
                    let icon = "";
                    if (res.code == 1001) {
                        _this.$dialog.toast({
                            mes: res.message,
                            timeout: 1000,
                            icon: "success",
                            callback: () => {
                                // 处理完毕修改选项以及说明为空
                                this.checkId = "";
                                this.textContent = "";
                                this.mustWriteTag = "";
                                _this.$emit("updateDataList");
                            },
                        });
                    }
                }).catch(() => {
                    // 处理完毕修改选项以及说明为空
                    this.checkId = "";
                    this.textContent = "";
                    this.mustWriteTag = "";
                    _this.$dialog.loading.close();
                });
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值