1. 父组件给子组件传值

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

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

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

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

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

props:{
    'title':String      
}

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

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

注意:

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

示例:

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 中的值提供一个带有验证需求的对象,而不是一个字符串数组。
例如:

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 可以是下面原生构造器:

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

type 也可以是一个自定义构造器,使用 instanceof 检测。

2.父子组件主动通信

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

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

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

2.在父组件里面通过

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

备注:在任一组件中,通过设置 ref 的方法可以获取该标签的DOM节点。

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

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

示例:

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) 触发事件

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

VueEvent.js
import Vue from "vue";

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

2、在要广播的文件中引入刚才定义的实例。并在 methods:{}中,通过 VueEmit.$emit('名称','数据') 进行广播。
3、在接收收数据的文件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>

梁柱
135 声望12 粉丝

« 上一篇
3.vue请求数据
下一篇 »
5.vue路由