vue3 + pinia + element plus 使用dialog组件

项目中通过pinia做状态管理,在dialog组件中使用,发现了一些问题,在此总结一下。

  • store
js 复制代码
//store.ts
import { defineStore } from "pinia"
const useTestStore = defineStore({
    id: 'testStore',
    state() {
        return {
            obj: {
                name: '张三'
            }
        }   
    },
})
export default useTestStore
  • dialog
js 复制代码
//dialog
<template>
  <div>
    <el-dialog
      v-model="dialogVisible"
      title="Tips"
      width="500"
      destroy-on-close
    >
      <span>This is a message</span>
      <child />
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">Cancel</el-button>
          <el-button type="primary" @click="cancel"> Confirm </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import child from "./child.vue"
import useTestStore from "../../store"
export default {
  components: {
    child,
  },
  data() {
    return {
      dialogVisible: false,
    }
  },
  computed: {
    ...mapState(useTestStore, ["obj"]),
  },
  methods: {
    open() {
      this.dialogVisible = true
    },
    cancel() {
      this.dialogVisible = false
      this.$emit("update:modelValue", new Date().getTime())
    },
  },
  unmounted() {
	//需要重置store
    useTestStore().$reset()
    console.log("弹窗销毁")
  },
}
</script>
  • dialog中的子组件
js 复制代码
//child
<template>
  <div>123 {{ obj.name }}</div>
</template>
<script>
import useTestStore from "../../store"
export default {
  computed: {
    ...mapState(useTestStore, ['obj'])
  },
  watch: {
    obj: {
      handler(newValue) {
        console.log('watch', newValue)
      },
      deep: true,
    }
  },
  unmounted() {
    console.log('弹窗中的组件销毁')
  }
}
</script>

一些情况下,在使用弹窗的时候,需要在弹窗上加一个key,保证弹窗关闭的时候,数据重置更新。代码如下:

js 复制代码
//页面中
<template>
  <div> 
    <button @click="cccOpen">打开弹窗</button>
    <ccc ref="cccDom" :key="num2" v-model="num2" />
  </div>
</template>
<script>

import ccc from "./components/ccc/index.vue"
export default {
  components: {

    ccc
  },
  data() {
    return {

      num2: 1
    }
  },
  methods: {
    cccOpen() {
      this.$refs.cccDom.open()
    }
  },
  unmounted() {
    console.log('页面销毁')
  }
}
</script>

最后运行发现,每次关闭弹窗,然后打开弹窗,child组件的watch方法累加,进而导致很多问题。 问题出现原因:

  1. useTestStore().$reset() (我也没想明白,反正和它有关)
  2. key 因为弹窗内部还未销毁的时候,弹窗本身已经销毁了,导致后续的销毁未继续执行,所以每次关闭弹窗的时候都会累加。 总而言之,就是因为store中reset方法key的双重作用下导致了这个问题。

在保留以上功能的情况下,如何修改呢? 解决方法如下:

js 复制代码
cancel() {
      this.dialogVisible = false

      setTimeout(() => {
        this.$emit("update:modelValue", new Date().getTime())
      }, 0)
    },
相关推荐
阿丰资源8 小时前
SpringBoot+Vue实战:打造企业级在线文档管理系统
vue.js·spring boot·后端
忆往wu前10 小时前
从0到1一步步拆解搭建,梳理一个 Vue3 简易图书后台全开发流程
前端·javascript·vue.js
光影少年10 小时前
大屏页面,一次多个请求,请求加密导致 点击 全局时间选择器 时出现卡顿咋解决(面板收起会延迟1~2秒)
前端·javascript·vue.js·学习·前端框架·echarts·reactjs
Mr.mjw10 小时前
vue中封装一个环形进度条组件,根据外部盒子大小自适应变化
前端·javascript·vue.js
唯火锅不可辜负11 小时前
uniapp开发公众号订阅功能踩坑小记
前端·vue.js
像我这样帅的人丶你还11 小时前
前端监控体系与实践(二):全局监控
前端·javascript·vue.js
前端那点事11 小时前
Vue3 超全复盘!30+前端高频核心知识点(开发+面试全覆盖)
前端·vue.js
FlyWIHTSKY12 小时前
Vue 3 中 RouteRecord 详解(Vue Router 4)
前端·javascript·vue.js
@菜菜_达13 小时前
Vue生命周期
前端·javascript·vue.js
前端那点事14 小时前
Vue线上代码调试全攻略(安全无侵入,新手也能上手)
前端·vue.js