weixin_36931308 2021-06-15 16:16 采纳率: 50%
浏览 36

Vue.extend().$mount()弹窗,数据如何从调用方异步刷新到弹窗组件中

最近在做vue项目有个需求,需要通过js来调起弹窗组件,从网上搜资料发现可以使用Vue.extend().$mount()的方式来实现,于是乎在网上搜索代码,找到了一位大佬的代码来改了改。

<template>
  <div class="popup">
    <div class="popup-main">
      <div class="popup-header">
        <div class="header-content">
          <span class="title">{{title}}</span>
          <span class="el-icon-close close" @click="cancel"></span>
        </div>
      </div>
      <DsLoading v-if="showDsLoading" class="popup-body"></DsLoading>
      <div v-else class="popup-body">
        <div class="popup-table" ref="popupTable">
          <el-table :data="dataList"
                    :height="tableHeight"
          >
            <el-table-column v-for="(item, i) in tableHeader" :key="i"
                             :property="item.prop"
                             :label="item.label"
                             align="center"
            >
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>
  </div>
</template>
import DsLoading from '@/components/loading/dsLoading.vue';
export default {
    name:'',
    data () {
        return {
            showDsLoading: true,
            title: '标题',
            pageAble: false,
            confirmText:'确定',
            cancelText:'取消',
            dataList: [], // 数据列表
            tableHeader: [], // 表头数据
            tableHeight: null, // 表格高度,数据超过这个高度出现滚动条
        };
    },
    components: {
        DsLoading,
    },
    watch: {
        dataList: {
            handler: function () {
                this.showDsLoading = false;
            },
            deep: true
        }
    },
    mounted() {
        this.$nextTick(()=>{
            this.tableHeight = this.$refs.popupTable? this.$refs.popupTable.offsetHeight: 0;
        })
    },
    methods: {
        show(cb){
            typeof cb === 'function' && cb.call(this,this)
            return new Promise(resolve=>{
                this.resolve = resolve
            })
        },
        confirm(){
            this.resolve('confirm')
            this.hide()
        },
        cancel(){
            this.resolve('cancel')
            this.hide()
        },
        hide(){
            document.body.removeChild(this.$el)
            this.$destroy()
        }
    },
}
import Vue from 'vue'
import popUpVue from './popup.vue'

let newInstance = null

//将vue组件变为构造函数
let PopUpConstructor = Vue.extend(popUpVue)

let init = (options)=>{
    console.log(options)
    //实例化组件
    newInstance = new PopUpConstructor()
    //合并配置选项
    Object.assign(newInstance,options)
    //使用$mount()后  可以理解为创建虚拟的dom
    document.body.appendChild(newInstance.$mount().$el)
}
let caller = (options)=>{
    //options 为调用组件方法时传入的配置选项
    if(!newInstance){
        init(options)
    }
    return newInstance.show(vm =>{newInstance = null})
}
export default {
    install(vue){
        vue.prototype.$popUp = caller
    }
}

调用代码

let list = [],
title = '标题';
axios.post(`/getList`, param)
.then(res=>{
        
    if (res.data.resultCode === '000000') {
        if (res.data.list && res.data.list.length > 0) {

            list = res.data.list;
            title = res.data.title;
        }
    }
    }).catch(
    err => reject(err)
);

let tableHeader = [{
        prop: 'name',
        label: '名称'
    }, {
        prop: 'value',
        label: '值'
    },],
    dataList = list;
that.$popUp({
    tableHeader,
    dataList,
    title
}).then(res=>{
    console.log(res)
})

执行结果发现table数据是可以异步刷新到弹窗dom里面的,但是标题是不能更新的。
是什么原因呢,想了很久突然想到字符串与列表对象在内存中存储的方式是不一样的,字符串在内存中存的是值,而引用数据类型在内存中存储的是地址,就是说list对应的内存地址跟dataList对应的内存地址是一样的,且vue的响应式原理data中的数据dataList属性被转为 getter/setter可以被追踪刷新的,当异步数据改变list的值时,dataList也跟着变化,所以列表数据被更新到dom中,但是弹窗中的title字符串的值未变化,所以不会被刷新。

对于一些场景中可能需要调用方的数据异步更新到弹窗组件中,对于如何更新还请路过大神给出宝贵的意见

  • 写回答

2条回答 默认 最新

  • 崽崽的谷雨 2021-06-15 16:52
    关注

    调用代码第二行title怎么没有声明let title=""

    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大