IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> element中el-dialog的:visible.sync理解 -> 正文阅读

[JavaScript知识库]element中el-dialog的:visible.sync理解

今天一直在纠结dialog中的sync有什么用??

因为在官方文档的在线运行中,没有发现其他方法;

所以一度认定,sync就是起一个关闭弹层的作用;原本在子组件中使用el-dialog时,去掉sync修饰

的visible点击关闭按钮无法关闭弹窗,更让我确信就是这个用处

但是********************

加上sync后再次点击右上角的关闭按钮,此处报了个警告,有道翻译后是:

【避免直接改变道具,因为每当父组件重新呈现时,道具的值会被覆盖。相反,应根据道具的值使用数据或计算属性。道具被突变:“showDialog”】

/*弹窗子组件*/  
<el-dialog
    title="提示"
    :visible.sync="showDialog"
    width="35%"
  >
/*父组件*/
 <add-dep :show-dialog.sync="showDialog" 
:current-node="currentNode" 
@addDepts="getDepartmentsList" />

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "showDialog"

found in

---> <AddDep> at src/views/departments/components/add-dep.vue

此处报错的原因在于,我的showDialog是从父组件中调用过来的,但是此时点击关闭按钮的时候:visible.sync修改了showDialog的值,与官网不同的地方在于,官网中的变量是声明在data中的;

翻看了这部分的源码后发现:

源码中在data中定义了一个closed属性来控制弹窗的开关并且监听了一个变量visible用来控制是否展示弹窗,此处就与我们使用的el-dialog关联起来了

不难看出,

在mounted 中判断了visible是否为true,为true且构建dom后调用了open打开弹窗并判断是否要追加到页面结构中;

watch中根据visible的val来控制closed的值从而来改变弹窗是否打开,与此同时,监听了在 Dialog 出现时锁定body 滚动

点击关闭按钮调用的handleClose方法,此方法中调用的hide才是点击关闭按钮真正关闭弹窗的方法

//copy部分源代码做解释,想看完整的建议问度娘
<template>
  <transition
    name="dialog-fade"
    @after-enter="afterEnter"
    @after-leave="afterLeave"
  >
    <div v-show="visible" class="el-dialog__wrapper" @click.self="handleWrapperClick">
      <div
        ref="dialog"
        role="dialog"
        aria-modal="true"
        :aria-label="title || 'dialog'"
        class="el-dialog"
        :class="[{ 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
        :style="style"
      >
        <div class="el-dialog__header">
          <slot name="title">
            <span class="el-dialog__title">{{ title }}</span>
          </slot>
          <button
            v-if="showClose"
            type="button"
            class="el-dialog__headerbtn"
            aria-label="Close"
            @click="handleClose"
          >
            <i class="el-dialog__close el-icon el-icon-close" />
          </button>
        </div>
        <div v-if="rendered" class="el-dialog__body"><slot /></div>
        <div v-if="$slots.footer" class="el-dialog__footer">
          <slot name="footer" />
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
  data() {
    return {
      closed: false
    }
  },
  watch: {
    // 是否显示 Dialog,支持 .sync 修饰符
    visible(val) {
      if (val) {
        this.closed = false
        this.$emit('open')
        this.$el.addEventListener('scroll', this.updatePopper)
        this.$nextTick(() => {
          this.$refs.dialog.scrollTop = 0
        })
        if (this.appendToBody) {
          document.body.appendChild(this.$el)
        }
      } else {
        this.$el.removeEventListener('scroll', this.updatePopper)
        if (!this.closed) this.$emit('close')
      }
    }
  },

  mounted() {
    if (this.visible) {
      this.rendered = true
      this.open()
      if (this.appendToBody) {
        document.body.appendChild(this.$el)
      }
    }
  }, 
methods: {
 // 关闭dialog
    handleClose() {
      // 如果有beforeClose,执行beforeClose
      if (typeof this.beforeClose === 'function') {
        this.beforeClose(this.hide)
      } else {
        // 否则隐藏
        this.hide()
      }
    },
    // 隐藏dialog
    hide(cancel) {
      if (cancel !== false) {
        this.$emit('update:visible', false)
        this.$emit('close')
        this.closed = true
      }
    }
}
</script>

结论:

将dialog直接使用时

<el-dialog>封装前(源码中)有一个visible属性来控制弹层是否显示,并且监听了弹层的值,sync是<el-dialog>里面定义的一个标识,用来双向绑定,修改了值就会触发源代码中的监听,从而运行$emit的逻辑

将dialog作为弹层子组件使用时,如果不对其进行一些设置,点击关闭后会以上警告且无法再次打开该弹窗。

可以去掉关闭按钮:show-close="false"和sync修饰符仅使用确认取消按钮中emit的方法来关闭弹层

<el-dialog

? ? title="提示"

? ? :visible="showDialog"

? ? width="35%"

? ? @close="closeFn"

? > 
// 添加子部门
    async addDepartment() {
      try {
        await this.$refs.departForm.validate()
        // 新增部门
        await addDepartments({ ...this.departForm, pid: this.currentNode.id })
        // 修改视图
        this.$emit('addDepts')
        // 提示消息
        this.$message.success('成功添加子部门')
        // 关闭弹层
        this.$emit('update:showDialog', false)
      } catch (error) {
        console.log(error)
      }
    },
    closeFn() {
      // 重置数据  因为resetFields 只能重置 表单上的数据 非表单上的 比如 编辑中id 不能重置
      this.departForm= {
        name: '',
        code: '',
        manager: '',
        introduce: ''
      }
      this.$refs.departForm.resetFields() // 重置校验字段
      // 关闭弹层
      this.$emit('update:showDialog', false)
    }

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:27:51  更:2022-07-05 23:28:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/11 11:35:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码