单文件组件传值案例详解(父传子,子传父,非父子组件传值)

首先我们把父传子,子传父结合在一起讲

  1. 父传子---------------props和$attrs:
    父传子内嵌传值,子用props接收

  2. 子传父--------------$emit
    子组件用 $emit向父组件传值
    话不多说直接上例子,简单易懂

浏览器界面:

在这里插入图片描述

Father.vue

<template>
    <div>
      <div class='father'>
        <input type="text" v-model='message'><br>
        {{ cMessage }}
        <div>
            其他传值:data : {{ data }}
        </div>
      </div>
        <Children :pre='message' :data='data'  @del='deleteOne'></Children>

    </div>
</template>

以上代码,father用predata向子组件传值,用@del接收子组件发送的请求

<script>
import Children from '@/components/Children.vue'

export default {
  name: 'Father',
  data: function (){
    return {
      message: '我是谁呀',
      data:{
          'name': 'Ace',
          'age': 18
      }
    }
  },
  components:{
    Children,
  },
  computed: {
      cMessage(){
          return 'Father Message: '+ this.message
      }
  },
  methods: {
    deleteOne () {
      this.message = this.message.slice(0,this.message.length-1)
    },
  }
}
</script>

以上代码,把message和data通过pre和data传出去,如果接受到子组件的del请求,删除message最后一个字

Children.vue

<template>
  <div class="children">
      {{ childrenMessage }} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button @click='deleteOne'>del</button>
      <br>
      The leftover props: {{ messageLeft }}
  </div>
</template>

以上代码,展示子组件接受的数据,通过计算属性输出,在用户点击删除按钮后出发click时间调用deleteOne方法

export default {
  name: 'Children',
  props:['pre'],
  data: function (){
    return {
      left: ''
    }
  },
  methods:{
    deleteOne(){
      this.$emit('del')
    }
  },
  computed:{
      childrenMessage(){
          return 'Children Message Received: ' + this.pre
      },
      messageLeft(){
          return  this.$attrs
      }
  }

}

以上代码,用props[‘pre’]接收了父组件传来的pre(此处名字要相同),但是父组件传来的不止pre还有data,这时候没有用的data就会存在$attrs里面,以上代码同样把$attrs放在了页面。deleteOne方法会向父组件emit一个del,达到子组件向父组件传值的效果,注意此处子组件的del名字一定要与父组件接收的名字一样,如果子组件是:

this.$emit('delOne')

那么父组件就要用:

<children @delOne='anyOtherFuncName'> </children>

3. 非父子组件

页面展示:

输入down向下移,top向上移,left,right向左右移动,reset回归原点

main.js

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
  data: {
    bus: new Vue()
  }
})

首先我们要在main.js里面加上一个Vue实例bus来达到传值目的

emit_test.vue

<template>
  <div>
    <input type="text" v-model="message">
    <button @click="send">change</button><br>
  </div>
</template>

input输入双向绑定message,点击change按钮执行send方法

export default {
  name: 'Emit',
  data: function (){
    return {
      message: ''
    }
  },
  methods: {
    send () {
      this.$root.bus.$emit('change',this.message)
    },
  }
}

this.$root找到根实例然后用bus.$emit向另一个组件发送数据
(‘change’, this.message)
this.message是要发送出去的数据

receive_test.vue

<template>
    <div class="bigBox">
        <button @click='reset'>reset</button>
        <div ref='toMove' class='block' :style="position"></div>
    </div>

</template>
export default {
    name: 'Rec',
    data(){
        return {
            position:{
                'top': '20px',
                'left': '150px'}
            }
    },
    /* 用$on接收 */
    created(){
        let that = this;
        this.$root.bus.$on('change', t => {
            switch (t){
                case 'right':
                    that.moveRight();
                    break;
                case 'left': 
                    that.moveLeft();
                    break;
                case 'down': 
                    that.moveDown();
                    break;
                case 'top': 
                    that.moveTop();
                    break;
                default:
                    break;
            }
        })
    },
    methods:{
        moveRight(){
            if (parseInt(this.position.left) >= 300) {
                console.log('nonono');
                return
            }
            let right = parseInt(this.position.left) + 5;
            this.position.left = right + 'px';
        },
        moveLeft(){
            if (parseInt(this.position.left) <= 0) {
                console.log('nonono');
                return
            }
            let left = parseInt(this.position.left) - 5;
            this.position.left = left + 'px';
        },
        moveDown(){
            if (parseInt(this.position.top) >= 580) {
                console.log('nonono');
                return
            }
           let top = parseInt(this.position.top) + 10;
            this.position.top = top + 'px';
        },
        moveTop(){
            if (parseInt(this.position.top) <= 20) {
                console.log('nonono');
                return
            }
            let top = parseInt(this.position.top) - 5;
            this.position.top = top + 'px';
        },
        reset(){
            this.$router.go('/');
        }
    }
}

以上用如下格式接收另一个组件发送的数据:
this.$root.bus.$on(‘change’, funcName(t){

})
首先,‘change’一定要和$emit的第一个参数相同
其次, funcName里面的t就是传过来的this.message

GOOD LUCK

猜你喜欢

转载自blog.csdn.net/weixin_43873005/article/details/89918285
今日推荐