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)
    },
相关推荐
计算机学姐9 分钟前
基于微信小程序的调查问卷管理系统
java·vue.js·spring boot·mysql·微信小程序·小程序·mybatis
黄尚圈圈4 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
一路向前的月光9 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   9 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Jiaberrr10 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
程序员大金13 小时前
基于SpringBoot+Vue+MySQL的装修公司管理系统
vue.js·spring boot·mysql
道爷我悟了14 小时前
Vue入门-指令学习-v-html
vue.js·学习·html
无咎.lsy14 小时前
vue之vuex的使用及举例
前端·javascript·vue.js
工业互联网专业14 小时前
毕业设计选题:基于ssm+vue+uniapp的校园水电费管理小程序
vue.js·小程序·uni-app·毕业设计·ssm·源码·课程设计
计算机学姐15 小时前
基于SpringBoot+Vue的在线投票系统
java·vue.js·spring boot·后端·学习·intellij-idea·mybatis