天天看点

Vue - 组件传值(父子组件间传值、非父子组件间传值)

推荐:​​Vue汇总​​

Vue - 组件传值(父子组件间传值、非父子组件间传值)

如果你对组件不太了解,推荐你先阅读它:​​Vue - Vue组件基础​​

父子组件间传值

父组件向子组件传值:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件传值</title>
    <script src="./js/vue.js"></script>
</head>
<body>
   <div id="div">
       <child :message="message"></child>
   </div>
</body>
</html>
<script>
    Vue.component('child' , {
        props:{
            message: String
        },
        template: '<div>{{message}}</div>'
    });

    var vue = new Vue({
        el: '#div',
        data: {
            message: 'Hello Jack'
        }
    })
</script>      

父组件向子组件传值通过Prop这种方式,​​Vue - Prop​​。

效果:

Vue - 组件传值(父子组件间传值、非父子组件间传值)

子组件向父组件传值:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件传值</title>
    <script src="./js/vue.js"></script>
</head>
<body>
   <div id="div">
       <child :message="message" @click-child="clickChild"></child>
       <p v-show="Boolean(value)">{{value + 'kaven'}}</p>
   </div>
</body>
</html>
<script>
    Vue.component('child' , {
        props:{
            message: String
        },
        data: function () {
            return {
                value: '你干嘛点我!'
            }
        },
        template: '<div @click="clickDiv">{{message}}</div>',
        methods: {
            clickDiv(){
                this.$emit('click-child' , this.value);
            }
        }
    });

    var vue = new Vue({
        el: '#div',
        data: {
            message: 'Hello Jack',
            value: null
        },
        methods: {
            clickChild(value) {
                this.value = value;
                console.log(this.value)
            }
        }
    })
</script>      

子组件向父组件传值通过​

​$emit(value)​

​这种方式。

效果:

Vue - 组件传值(父子组件间传值、非父子组件间传值)

触发点击事件。

Vue - 组件传值(父子组件间传值、非父子组件间传值)

非父子组件间传值

非父子组件间传值,如果通过一层一层的父子组件间传值来实现就太繁琐了,代码也会及其复杂。这里介绍通过发布订阅模式或者说观察者模式来实现非父子组件间传值。

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件传值</title>
    <script src="./js/vue.js"></script>
</head>
<body>
   <div id="div">
       <child :message="message"></child>
       <child message="我是另外一个子组件,和上面子组件不是父子关系。"></child>
   </div>
</body>
</html>
<script>

    Vue.prototype.bus = new Vue();

    Vue.component('child' , {
        props:{
            message: String
        },
        data: function(){
          return {
              value: this.message
          }
        },
        template: '<div @click="clickDiv">{{value}}</div>',
        methods: {
            clickDiv(){
                this.bus.$emit('click' , this.value);
            },
        },
        mounted: function () {
            // 作用域发生变化
            var _this = this;
            this.bus.$on('click' , function (value) {
                console.log(_this.value);
                _this.value = value;
            })
        }
    });

    var vue = new Vue({
        el: '#div',
        data: {
            message: 'Hello Jack'
        }
    })
</script>      

你可能会在很多组件里用到数据或者实用工具,但是不想污染全局作用域。这种情况下,你可以通过在​

​prototype​

​(原型)上定义它们,使其在每个Vue的实例中可用。

通过在​

​prototype​

​​(原型)上定义​

​bus​

​​(总线,其实就是一个Vue实例)来实现发布订阅模式,组件通过​

​bus​

​(总线)来进行发布和订阅消息,这样就实现了非父子组件间传值。

效果:

Vue - 组件传值(父子组件间传值、非父子组件间传值)

触发第一个子组件的点击事件。

Vue - 组件传值(父子组件间传值、非父子组件间传值)

触发第二个子组件的点击事件。

Vue - 组件传值(父子组件间传值、非父子组件间传值)