父→子传值

父组件以属性的形式绑定值到子组件身上(传)

子组件通过使用属性props接收(收)

props是单向绑定的(只读属性):

当父组件的属性变化时,将传导给子组件,但是反过来不会

props属性支持两种常见的写法形式

数组(推荐)

优点:书写简单

缺点:不能设置默认值、数据类型

对象

优点:可以设置数据默认值与数据类型

缺点:写法复杂

实例

<div id="app">
    <child :day="day" :time="time"></child>
</div>
<script src="./js/vue.js"></script>
<script>
    Vue.component("child", {
        // 数组写法
        // props: ["day", "time"],
        // 对象写法
        props: {
            day: {
                default: "八", //如果没传,则使用默认值
                type: String,
            },
            time: {
                default: "1970-01-01 00:00:00",
                type: String,
            },
        },
        template: `<div>今天是星期{{day}},当前时间是:{{time}}</div>`,
        created() {
            console.log(this.day);
            console.log(this.time);
            // this.day = "六"; // 千万别这么写,千万别这么写,千万别这么写
        },
    });
    new Vue({
        el: "#app",
        data: {
            day: "五",
            time: "2020-12-11 10:27:48",
        },
    });
</script>

子→父传值

 

子组件模版

内容中用$emit()定义自定义事件$emit()方法至少有2个参数

第一个参数为自定义的事件名称(不要和内置的事件重名,例如click、change等)abc

第二个参数为需要传递的数据(可选,如果传可以是任何格式的数据)

父组件模板

内容中的子组件占位标签上用v-on(或@)绑定子组件定义的自定义事件名,监听子组件的事件,实现通信

实例

<div id="app">
    <!-- 监听子组件 bianda事件 点击进行bigger方法-->
    <child @bianda="bigger"></child>
    <div :style="{fontSize: fontSize + 'px',color: color}">{{msg}}</div>
</div>
<script src="./js/vue.js"></script>
<script>
    // 定义全局组件用于当子组件
    Vue.component("child", {
        data: function () {
            return {
                size: 11,
                color: "red",
            };
        },
        template: `<div><button @click="$emit('bianda',size,color)">点我给父组件中的文字加{{size}}像素</button></div>`,
    });
    new Vue({
        el: "#app",
        data: {
            msg: "黑色星期五",
            fontSize: 23,
            color: "black",
        },
        methods: {
            bigger: function (size, color) {
                this.fontSize += size;
                this.color = color;
            },
        },
    });
</script>

EventBus 中央事件总线

在Vue中通过单独的事件中心来管理非父子关系组件(兄弟)间的通信

核心步骤

建立事件中心

const eventBus = new Vue()

传递数据

eventBus.$emit('自定义事件名',传递的数据)

接收数据

eventBus.$on('自定义事件名'[,callback])

销毁事件中心

eventBus.$off('自定义事件名')

实例

<div id="app">
    <laoma></laoma>
    <hr />
    <laowang></laowang>

    <hr />
    <button @click="gg">离开游戏</button>
</div>
<script src="./js/vue.js"></script>
<script>
    // 事件中心
    const eventBus = new Vue();

    // 人物:老马
    Vue.component("laoma", {
        data: function () {
            return {
                hp: 100, // 老马的血量
                time:1,  //老马的复活次数
                damage: 8, // 老马的武力值
            };
        },
        template: `<div>
                <div>老马(心悦会员3级)当前的hp是:{{hp}}</div>
                <button @click="wlb">发动闪电五连鞭</button>
            </div>`,
        methods: {
            // 技能:五连鞭
            wlb: function () {
                eventBus.$emit("mbg", this.damage);
            },
        },
        created() {
            eventBus.$on("gdl", (val) => {
                if (this.hp - val < 0) {
                    if(this.time){
                        alert("老马冲钱, 满血复活!");
                        this.hp = 100;
                        this.time-=1;
                    }else{
                        this.hp = 0;
                        alert("Game over!老王获胜!");
                    }
                } else {
                    this.hp -= val;
                }
            });
        },
    });

    // 人物:老王
    Vue.component("laowang", {
        data: function () {
            return {
                hp: 100, // 老王的血量
                damage: 12, // 老王的武力值
            };
        },
        template: `<div>
                <div>老王当前的hp是:{{hp}}</div>
                <button @click="cqj">发动大力出奇迹</button>
            </div>`,
        created() {
            // 让老王自己拿本本记录hp的扣减情况
            eventBus.$on("mbg", (val) => {
                if (this.hp - val < 0) {
                    this.hp = 0;
                    alert("Game over!老马获胜!");
                } else {
                    this.hp -= val;
                }
            });
        },
        methods: {
            cqj: function () {
                eventBus.$emit("gdl", this.damage);
            },
        },
    });
    new Vue({
        el: "#app",
        data: {},
        methods: {
            gg: function () {
                eventBus.$off("mbg");
                eventBus.$off("gdl");
            },
        },
    });
</script>

试一试

ref(子→父)(了解)

ref属性被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs 对象上。

如果在普通的 DOM 元素上使用ref属性,则引用指向的就是 DOM 元素;

如果ref属性用在子组件上,引用就指向子组件实例

原理:

在父组件中通过ref属性(会被注册到父组件的$refs对象上)拿到组件/DOM对象,

从而得到组件/DOM中的所有的信息,也包括值

实例

<div id="app">
    <div ref="cc">今天天气很好</div>
    <child ref="cd"></child>
</div>
<script src="./js/vue.js"></script>
<script>
    Vue.component('child',{
        data: function () {
            return {
                msg: "33℃"
            }
        },
        template: `<div>温度:{{msg}}</div>`
    })
    new Vue({
        el: "#app",
        data: {
            
        },
        mounted() {
            // 可以   为所欲为
            console.log(this.$refs.cc); // 获取dom对象
            console.log(this.$refs.cd); // 获取vue组件实例(权限比较大,谨慎啊)
        },
    })
</script>

一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。