4.vue组件通讯

1. 父组件给子组件传值

父组件给子组件通讯的步骤:

1.父组件调用子组件的时候绑定动态属性。vue

<v-header :title="title"></v-header>

二、在子组件里面经过props接收父组件传过来的数据。数组

//两种方式
props:['title']

props:{
    'title':String      
}

父组件给子组件通讯的形式:

  1. 父组件给子组件传值。
  2. 父组件给子组件传方法。
  3. 父组件把整个实例传给子组件。

注意:函数

  1. 不要使得父子组件中的属性/方法重复了。当重复时,会使用父组件的属性/方法。
  2. prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,可是不会反过来。

示例:ui

Home.vue(父组件)
<template>
    <div>
        <p class="first">我是Home组件:{{msg}}</p>
        <hr>
        <v-info v-bind:homeTitle="title" :homeRun="run" :homeThis="this"></v-info>
    </div>
</template>

<script>
    import Info from "./Info";

    export default {
        name: "Home",
        components: {
            "v-info": Info,
        },
        data() {
            return {
                msg: "我是Home组件",
                title: "首页"
            }
        },
        methods: {
            run: function (data) {
                alert("这是Home组件的方法" + data);
            }
        },

    }
</script>

<style scoped>
    p {
        color: #42b983;
    }
</style>
Info.vue(子组件)
<template>
    <div id="info">
        <p>我是Home的子组件info</p>
        <button @click="getTitle">获取父组件的title</button>
        <button @click="getParentRun(123)">调用父组件的run方法</button>
        <button @click="getHome">父组件经过this把整个实例传给子组件</button>
    </div>
</template>

<script>
    export default {
        name: "Info",
        data() {
            return {
                
            }
        },
        methods: {
            getTitle: function () {
                alert(this.homeTitle);
            },
            getHome: function () {
                alert(this.homeThis.msg);
            },
            getParentRun: function (data) {
                this.homeRun(data);
            }
        },
        props: {
            "homeTitle": {
                type: String,
                required: true,
                default: "HomeA"
            },
            "homeRun": {
                type: Function,
                required: true,
            },
            "homeThis": {
                type: Object,
                required: true,
            },
        }
        //props: ["homeTitle", "homeRun", "homeThis"],
    }
</script>

Prop 验证

组件能够为 props 指定验证要求。
为了定制 prop 的验证方式,你能够为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。
例如:this

Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会经过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
type 能够是下面原生构造器:code

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

type 也能够是一个自定义构造器,使用 instanceof 检测。component

2.父子组件主动通讯

父组件主动获取子组件的数据和方法:

1.调用子组件的时候定义一个ref对象

<v-header ref="header"></v-header>

2.在父组件里面经过事件

this.$refs.header.属性
this.$refs.header.方法

子组件主动获取父组件的数据和方法:

this.$parent.数据
this.$parent.方法

示例:ip

Home.vue
<template>
    <div>
        <p class="first">我是Home组件:{{msg}}</p>
        <button @click="getChildMsg">获取子组件Info的msg</button>
        <button @click="getChildRun">获取子组件Info的run()</button>
        <hr>
        <v-info ref="info" v-bind:homeTitle="title" :homeRun="run" :homeThis="this"></v-info>
    </div>
</template>

<script>
    import Info from "./Info";

    export default {
        name: "Home",
        components: {
            "v-info": Info,
        },
        data() {
            return {
                msg: "我是Home组件",
                title: "首页",
                color: "red",
            }
        },
        methods: {
            run: function (data) {
                alert("这是Home组件的方法" + data);
            },
            getChildMsg: function () {
                alert(this.$refs.info.msg);
            },
            getChildRun: function () {
                this.$refs.info.run();
            }
        },

    }
</script>
Info.vue
<template>
    <div id="info">
        <p>我是Home的子组件info</p>
        <button @click="autoGetParent">子组件主动获取父组件的数据和方法</button>
    </div>
</template>

<script>
    export default {
        name: "Info",
        data() {
            return {
                msg:"我是Home的子组件info",
            }
        },
        methods: {
            run:function(){
                alert("我是子组件info的方法");
            },
            autoGetParent:function(){
                alert(this.$parent.color);
                this.$parent.run('123');
            }
        },
    }
</script>

非父子组件传值

使用 \$on(eventName) 监听事件
使用 \$emit(eventName) 触发事件

一、新建一个js文件,而后引入vue,实例化vue,最后暴露这个实例。

VueEvent.js
import Vue from "vue";

const VueEvent = new Vue();
export default VueEvent;

二、在要广播的文件中引入刚才定义的实例。并在 methods:{}中,经过 VueEmit.$emit('名称','数据') 进行广播。
三、在接收收数据的文件mounted(){}中经过 VueEmit.$on('名称',function(){}) 接收广播的数据。

Home.vue
<template>
    <div>
        <p>我是Home组件</p>
        <button @click="emitNews">点击给News传消息</button>
    </div>
</template>

<script>
    import VueEvent from "../../model/VueEvent"

    export default {
        name: "Home",
        data() {
            return {
                msg: "我是Home组件",
            }
        },
        methods: {
            emitNews: function () {
                VueEvent.$emit("to-news", this.msg);
            }
        },
        mounted() {
            VueEvent.$on("to-home", (data) => {
                alert(data);
            })
        }
    }
</script>

News.vue

<template>
    <div id="news">
        <p>我是新闻组件</p>
        <button @click="emitHome">点击给home传消息</button>
    </div>
</template>

<script>
    //引入vue实例
    import VueEvent from "../../model/VueEvent"
    export default {
        name: "News",
        data(){
            return {
                msg:"我是新闻组件"
            }
        },
        methods:{
            emitHome:function(){
                VueEvent.$emit("to-home",this.msg);
            }
        },
        mounted() {
            VueEvent.$on("to-news",(data)=>{
                alert(data);
            })
        }
    }
</script>
相关文章
相关标签/搜索