Vue之组件间传值

标签: Vuehtml


Vue之父子组件传值

  • 父向子传递经过props
  • 子向父传递经过$emit

演示地址vue

代码示例以下:vuex

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>父子组件传值</title>
    <script src="./bower_components/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <counter :count="num1" @add="handAddTotal"></counter>
        <counter :count="num2" @add="handAddTotal"></counter>
        求和:{{total}}
    </div>
    <script>
        //自定义组件
        var counter = {
            props:['count'],//经过属性由父向子传值
            data: function() {
                return {
                    number: this.count//子组件内接收父级传过来的值
                }
            },
            template: '<div @click="handleClick">{{number}}</div>',
            methods: {
                handleClick: function() {
                    this.number ++;
                    //经过向外触发事件由子级向父级传值
                    this.$emit('add',1);
                }
            }
        };
        var vm = new Vue({
            el: '#app',
            //组件注册
            components: {
                counter
            },
            data:{
                num1:1,
                num2:2,
                total: 3
            },
            methods:{
                //求和
                handAddTotal:function(step){
                    this.total += step;
                }
            }
        });
    </script>
</body>
</html>

注意事项:app

  • props传过来值,根据单向数据流原则子组件不可直接拿过来修改,能够在子组件的data里定义一个变量转存再来作修改
  • 为了保证各组件数据的独立性,子组件的data应该以一个函数返回一个对象的形式来定义,见上示例代码23行

Vue之非父子组件传值

  • 经过bus方式传递,也能够叫总线/发布订阅模式/观察者模式
  • 经过vuex传递

bus/总线/发布订阅模式/观察者模式演示地址
vuex演示地址
bus方式示例代码以下:函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>父子组件传值(bus/总线/发布订阅模式/观察者模式)</title>
    <script src="./bower_components/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <child-one content="hello"></child-one>
        <child-two content="world"></child-two>
    </div>
    <script>
        Vue.prototype.bus = new Vue();
        //自定义组件
        var childOne = {
            //经过属性由父向子传值
            props:{
                'content':String
            },
            data:function(){
                return {
                    contentIn:this.content
                }
            },
            template: '<div @click="handleClick">{{contentIn}}</div>',
            methods: {
                handleClick: function() {
                    //经过触发事件向各组件发送数据
                   this.bus.$emit('change',this.contentIn);
                }
            },
            mounted:function () {
                var that = this;
                //组件接收事件
                this.bus.$on('change',function(val){
                    that.contentIn = val;
                });
            }
        };
        //自定义组件
        var childTwo = {
            //经过属性由父向子传值
            props:{
                'content':String
            },
            data:function(){
                return {
                    contentIn:this.content
                }
            },
            template: '<div @click="handleClick">{{contentIn}}</div>',
            methods: {
                handleClick: function() {
                    //经过触发事件向各组件发送数据
                    this.bus.$emit('change',this.contentIn);
                }
            },
            mounted:function () {
                var that = this;
                //组件接收事件
                this.bus.$on('change',function(val){
                    that.contentIn = val;
                });
            }
        };
        var vm = new Vue({
            el: '#app',
            //注册组件
            components: {
                childOne,
                childTwo
            }
        });
    </script>
</body>
</html>

vuex方式示例代码以下:ui

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>父子组件传值(vuex)</title>
    <script src="./bower_components/vue/dist/vue.js"></script>
    <script src="./bower_components/vuex/dist/vuex.js"></script>
</head>
<body>
    <div id="app">
        <child-one></child-one>
        <child-two></child-two>
    </div>
    <script>
        Vue.use(Vuex);
        var store = new Vuex.Store({
            state: {
                count:0
            },
            mutations: {
                increment:function(state){
                    console.log(123);
                    state.count++;
                }
            },
            actions: {
                increment:function(context){
                    context.commit('increment')
                }
            },
            getters: {
                getCount:function(state){
                    return state.count;
                }
            }
        });
        //自定义组件
        var childOne = {
            computed: {
                countIn:function(){
                    return store.getters.getCount
                }
            },
            template: '<div @click="handleClick">{{countIn}}</div>',
            methods: {
                handleClick: function() {
                    store.dispatch('increment');
                }
            }
        };
        //自定义组件
        var childTwo = {
            computed: {
                countIn:function(){
                    return store.getters.getCount
                }
            },
            template: '<div @click="handleClick">{{countIn}}</div>',
            methods: {
                handleClick: function() {
                   store.dispatch('increment');
                }
            }
        };
        var vm = new Vue({
            el: '#app',
            store,
            //注册组件
            components: {
                childOne,
                childTwo
            }
        });
    </script>
</body>
</html>

附上vuex官网地址:https://vuex.vuejs.org/zh/this