普通视图

发现新文章,点击刷新页面。
昨天 — 2025年11月20日首页

.sync 修饰符 | vue前端知识

2025年11月20日 01:32

.sync 修饰符

在 Vue 2 中,.sync 修饰符是实现父子组件双向数据绑定的语法糖,特别适合用于弹窗这类需要子组件修改父组件状态的场景。

基本概念

.sync 修饰符,实际上就是将父组件的属性,通过 .sync 修饰符,映射到子组件的 props 属性中,并监听子组件的 props 属性的修改,将修改后的值,通过 $emit 事件发送给父组件,从而实现父子组件的数据同步。

本质是自动为你扩展了一个 v-on 监听器。

<!-- 使用 .sync 的写法 -->
<ChildComponent :visible.sync="dialogVisible" />

<!-- 等效于完整写法 -->
<ChildComponent
    :visible="dialogVisible"
    @update:visible="val => dialogVisible = val"
/>

举例

1. 引入并注册弹窗组件

import MyDialog from "./MyDialog.vue";

export default {
    components: {
        MyDialog,
    },
    data() {
        return {
            showDialog: false,
        };
    },
};

2. 注册点击事件并绑定弹窗组件

<template>
    <div class="parent">
        <button @click="showDialog = true">打开弹窗</button>

        <!-- 使用 .sync 修饰符 -->
        <MyDialog :visible.sync="showDialog" title="示例弹窗" />
    </div>
</template>

3. 子组件:弹窗逻辑

3.1 定义接收的 props
props: {
  visible: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: '弹窗标题'
  }
},
3.2 使用 v-if 控制弹窗显示
<div class="dialog-overlay" v-if="visible">
    <div class="dialog-content">
        <div class="dialog-header">
            <h3>{{ title }}</h3>
            <button class="close-btn" @click="closeDialog">×</button>
        </div>
        <div class="dialog-body">
            <p>这是一个弹窗内容</p>
            <slot></slot>
            <!-- 支持插槽内容 -->
        </div>
        <div class="dialog-footer">
            <button @click="closeDialog">取消</button>
            <button @click="confirm">确定</button>
        </div>
    </div>
</div>
3.3 关闭弹窗逻辑
methods: {
  closeDialog() {
    // 关键:使用 update:visible 模式触发事件
    this.$emit('update:visible', false);
  },
  confirm() {
    console.log('确认操作');
    this.closeDialog();
  }
},
3.4 监听 visible 变化(可选)
watch: {
  // 监听 visible 变化,处理外部对弹窗的关闭
  visible(newVal) {
    if (!newVal) {
      // 弹窗关闭时的清理操作
    }
  }
}

详细代码

父组件(使用弹窗)
<template>
    <div class="parent">
        <button @click="showDialog = true">打开弹窗</button>

        <!-- 使用.sync修饰符 -->
        <MyDialog :visible.sync="showDialog" title="示例弹窗" />
    </div>
</template>

<script>
    import MyDialog from "./MyDialog.vue";

    export default {
        components: {
            MyDialog,
        },
        data() {
            return {
                showDialog: false,
            };
        },
    };
</script>
子组件弹窗(MyDialog.vue)
<template>
    <div class="dialog-overlay" v-if="visible">
        <div class="dialog-content">
            <div class="dialog-header">
                <h3>{{ title }}</h3>
                <button class="close-btn" @click="closeDialog">×</button>
            </div>
            <div class="dialog-body">
                <p>这是一个弹窗内容</p>
                <slot></slot>
                <!-- 支持插槽内容 -->
            </div>
            <div class="dialog-footer">
                <button @click="closeDialog">取消</button>
                <button @click="confirm">确定</button>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        props: {
            visible: {
                type: Boolean,
                default: false,
            },
            title: {
                type: String,
                default: "弹窗标题",
            },
        },
        methods: {
            closeDialog() {
                // 关键:使用update:visible模式触发事件
                this.$emit("update:visible", false);
            },
            confirm() {
                // 执行确认操作...
                console.log("确认操作");
                this.closeDialog();
            },
        },
        watch: {
            // 监听visible变化,处理外部对弹窗的关闭
            visible(newVal) {
                if (!newVal) {
                    // 弹窗关闭时的清理操作
                }
            },
        },
    };
</script>

<style scoped>
    // 样式
</style>

总结

  1. .sync 的作用

    • 实现父子组件双向绑定,简化代码。
    • 特别适合弹窗等需要频繁切换显示状态的场景。
  2. 核心逻辑

    • 父组件通过 .sync 将状态传递给子组件。
    • 子组件通过 $emit('update:visible', value) 修改父组件的状态。
  3. 可选功能

    • 如果需要在弹窗关闭时执行清理操作,可以使用 watch 监听 visible 的变化。
  4. 使用场景

    • 弹窗显示/隐藏控制

    • 表单编辑对话框

    • 确认对话框

    • 设置面板

    • 任何需要子组件修改父组件状态的场景

❌
❌