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)
    },
相关推荐
web打印社区7 小时前
HTML5 静默打印:前端页面怎么调用打印机且尽量不弹窗
前端·javascript·vue.js·pdf·html·html5
雪芽蓝域zzs8 小时前
第3节:el-select 弹窗定位、滚动穿透与挂载容器(popper-append-to-body /teleported)
vue.js·elementui
雪芽蓝域zzs17 小时前
第 2 节:基础扩展 - 下拉弹窗常用原生属性
vue.js·elementui
xxwl5851 天前
vue3的入门学习
前端·vue.js·学习
web打印社区1 天前
政务办事大厅:叫号小票、办理回执网页怎么静默出纸
前端·javascript·vue.js·pdf·html·政务
斯内普吖1 天前
(开源)水果蔬菜商城实战指南 基于 Java + SSM + Vue + MySQL
java·vue.js·mysql·开源
ss2731 天前
AI全栈实战 | 2.2-02 React 思维模型:数据不可变 vs Vue 数据可变,两种哲学把复杂度推给谁
前端·vue.js·react.js
天衍四九-1 天前
Docker Compose企业实战系列(三):Vue/React前端项目容器化完整部署
前端·vue.js·docker
墨鱼老师1 天前
SpringBoot+Vue 毕设项目开发踩坑记录(前后端分离)
vue.js·spring boot·毕业设计·课程设计·前后端分离·java 毕设
雪芽蓝域zzs1 天前
Vue3 + Element Plus el-select 下拉弹窗
vue.js·elementui