vue组件之间传值

1.兄弟组件传值

使用 $on(event,callback) 监听事件
使用 $emit(event, […args]) 触发事件

现有子组件a.vue,b.vue,它两是平级,现在要让a组件给b组件传值,a组件中的按钮点击,改变b组件中的值。
第一步:新建一个bus.js,并把该js分别引入到a,b组件中

//bus.js代码如下
import Vue from 'vue'
const bus=new Vue();
export default bus

使用如下方法分别引入到a,b组件中:

<script>
import bus from "@/plugin/eventbus.js";
};
</script>

在a组件中点击按钮通过bus.$emit(),把值传递给b组件:

<template>
  <div>
    <span @click="fun">点击传值</span>
  </div>
</template>
<script>
import bus from "@/plugin/eventbus.js";
export default {
  data() {
    return {};
  },
  methods: {
    fun() {
     //通过bus.$emit进行发送事件,"myclick"表示事件名,第二个参数表示要传递的参数值
      bus.$emit("myclick", "我来自a");
    },
  },
};
</script>

在b组件中通过bus.$on()来接收a组件传递过来的值

<template>
    <div>
        {{cname}}
    </div>
</template>
<script>
import bus from "@/plugin/eventbus.js";
export default {
    data(){
        return{
            cname:""
        }
    },
    mounted(){
    //通过bus.$on()来接收a组件传递过来的值,第一个参数“myclick”表示事件名,第二个参数放要执行的方法,这个值需要如何处理,比如我把这个值赋值给b组件中的cname变量
        bus.$on('myclick',item=>{
            this.cname=item;
        })
    }
}
</script>

现在把a,b组件都放入通一个父组件father.vue中,就完成了。

<template>
<div>
<a></a>
<b></b>
</div>
</template>
<script>
import a from '../components/a.vue';
import b from '../components/b.vue';
export default{
components:{a,b}
}
</script>

2.父子组件传值

子组件的传值是通过props来传递数据,$emit来触发事件;

props

1.如果无需验证,可以使用字符串数组格式
例如:

props: ['childArray','myname','userinfo']

2.如果需要验证,则需要使用对象格式,可以为组件的 props 指定验证规格。如果传入的数据不符合规格,Vue会发出警告。当组件给其他人使用时,这很有用,要指定验证规格,需要用对象的形式,而不能用字符串数组。

 props: {
    // 基础类型检测 (`null` 意思是任何类型都可以)
    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 value > 10
      }
    }
  }

注意:prop是单向数据流
prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解

另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着不应该在子组件内部改变 prop。如果这么做了,Vue 会在控制台给出警告

实例:子组件要从父组件获取数据,并且子组件还要修改该内容?
解决办法:使用变量储存prop的初始值,并使用watch来观察prop的值的变化。发生变化时,更新变量的值

//在子组件中
<template>
    <div>
       获取父组件的传递过来的值:{{username}}
    </div>
</template>
<script>
export default{
    props:["fatherinfo"],
    data(){
        return{
            username:this.fatherinfo
        }
    },
    watch:{
    //监听父组件的数据有无变化,如果变化,及时传递给子组件
      fatherinfo(val){
          this.username=val
      }  
    }
}
</script>
//父组件中
<template>
  <div>
    <myvuea :fatherinfo="info"></myvuea>
  </div>
</template>
<script>
import myvuea from "@/components/a.vue";
export default {
  components: {
    myvuea,
  },
  data(){
	return{
		info:"我的数据"
		}
	}
};
</script>

$emit

子组件可以使用 $emit,让父组件监听到自定义事件 。$emit 绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件,父组件通过@event监听并接收参数。

//在子组件中
<template>
    <div>
       <span @click="sendfather">向父组件发送数据</span>
    </div>
</template>
<script>
export default{
    methods:{
      sendfather(){
      //通过$emit发送数据到父组件,'childfun'表示事件名,第二个参数表示要发送给父组件的数据,可以传递多个参数this.$emit('childfun','x1','x2','x3');
          this.$emit('childfun','今天天气不错');
      }  
    }
}
</script>
//父组件中
<template>
  <div>
  // @childfun是子组件传递过来的事件名
    <myvuea @childfun="getFun"></myvuea>
  </div>
</template>
<script>
import myvuea from "@/components/a.vue";
export default {
  components: {
    myvuea,
  },
  methods: {
    getFun(v) {
    //参数v就是子组件传递过来的数据,当点击子组件中的按钮,就可以获取v的值
      console.log(v);
    },
  },
};
</script>

3.父组件获取子组件中的所有函数和方法ref

  • 如果ref用在子组件上,指向的是组件实例,可以理解为对子组件的索引,通过$ref可能获取到在子组件里定义的属性和方法。
  • 如果ref在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,通过$ref可能获取到该DOM 的属性集合,轻松访问到DOM元素,作用与JQ选择器类似。

要点:父组件中可以通过this.$refs.refName来访问元素或子组件的实例。

注意:this.$refs是一个对象,持有当前组件中注册过 ref特性的所有 DOM 元素和子组件实例
注意:
$refs只有在组件渲染完成后才填充,在初始渲染的时候不能访问它们,并且它是非响应式的,因此不能用它在模板中做数据绑定
1.ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。
2.如果ref 是循环出来的,有多个重名,那么ref的值会是一个数组 ,此时要拿到单个的ref 只需要循环就可以了。

现在有子组件children.vue

<script>
export default{
    data(){
        return{
            userinfo:{
                name:"丽丽",
                age:12
            }
        }
    },
    methods:{
        myage(){
            console.log("haha");
        }
    }
}
</script>

现在有父组件father.vue

<template>
  <div>
  //在父组件中给子组件添加一个ref
    <myvuea ref="children"></myvuea>
  </div>
</template>
<script>
import myvuea from "@/components/a.vue";

export default {
  components: {
    myvuea,
  },
  data() {
    return {};
  },
  mounted(){
  //获取子组件中的对象
    let myuser=this.$refs.children.userinfo;
    //获取并执行子组件中的方法
      this.$refs.children.myage();
  }
};
</script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值