Vue之元件間傳值

weixin_30639719發表於2020-04-05

標籤: Vue


Vue之父子元件傳值

  • 父向子傳遞通過props
  • 子向父傳遞通過$emit

演示地址

程式碼示例如下:

<!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>

注意事項:

  • 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方式示例程式碼如下:

<!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/

轉載於:https://www.cnblogs.com/xwwin/p/9273623.html

相關文章