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)
    },
相关推荐
行云&流水25 分钟前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
三水气象台1 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue
盛夏绽放2 小时前
Vue3 中 Excel 导出的性能优化与实战指南
vue.js·excel
markyankee1015 小时前
Vue 响应式系统全面解析:从基础到高级实践
vue.js
翻滚吧键盘8 小时前
{{ }}和v-on:click
前端·vue.js
上单带刀不带妹8 小时前
手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程
开发语言·前端·javascript·vue.js·前端框架
Q_970956399 小时前
java+vue+SpringBoo校园失物招领网站(程序+数据库+报告+部署教程+答辩指导)
java·数据库·vue.js
翻滚吧键盘9 小时前
vue 条件渲染(v-if v-else-if v-else v-show)
前端·javascript·vue.js
叹一曲当时只道是寻常10 小时前
vue中添加原生右键菜单
javascript·vue.js
markyankee10112 小时前
Vue.js 入门指南:从零开始构建你的第一个应用
vue.js