(1)组件之间传递数据:
1、父组件向子组件
方式一:使用props传递
(1)在父组件中,在子组件的标签上写上键值对,可以传递多个键值对
若要传递一个对象的所有属性,可以简写为
<blog-post v-bind="对象"></blog-post>
post: {
id: 1,
title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>
等价于:
<blog-post
v-bind:id="post.id"
v-bind:title="post.title"
></blog-post>
(2)子组件接收,在script中和data同级
props:['键名1','键名2',...]
若父组件传递的是methods内的方法
(1)< 子组件 :键名='方法名'/>
(2)子组件接收
props:['键名']
(3)子组件调用父组件的方法
this.键名()
其中:
传入函数中的this是父组件的this,可以直接修改父组件的内容
方式二:使用provide
provide可以无视后代组件的层级,无论是多个层后代,都能获取到
export default{
provide(){
return{
参数键值对
}
}
}
后代组件中:
export default{
inject:['键名']
}
2、子组件向父组件
方式一:
(1)子组件必须通过事件才能向父组件传递参数
(2)在事件的回调函数中
this.$emit('键名',键值1,键值2,...);
其中:
键值可以通过v-model='变量',中的变量来实时传递
配置验证$emit规则,和methods同级配置
emits:['$emit事件名',...],
emits:{
'$emit事件名':null, 没有验证函数
'$emit事件名':(val)=>{
val为$emit向外传递的值
return true/false; 返回false表明$emit验证未通过,会报一个警告
}
}
(3)在父组件中的子组件标签上,通过自定义事件接收
如:父组件中的子组件:
<Vue1 @键名='自定义函数' />
(3)接收传递的参数
函数接收:函数的参数和$emit传递的参数一一对应
非函数接收:使用$event
@键名="xx+$event"
方式二:
子组件:相同实例对象.$emit('名称',数据);
父组件:相同实例对象.$on('名称',回调函数(参数即为数据){...})
如在main.js中,给Vue挂载一个空对象
Vue.prototype.$x=new Vue(); new的Vue实例上会有$emit和$on方法
this.$x.$emit(...);
this.$x.$on(...);
this.$x.$off('名称',on监听的函数); 取消监听
方式三:
父组件:<xx :msg.sync='变量'></xx>
若传递对象的所有属性
<xx v-bind.sync='对象'></xx>
对象中的每一个属性都作为一个独立的 prop 传进去,然后各自监听
对象不能是一个字符串常量,例如 v-bind.sync=”{ title: doc.title }”错误
子组件:this.$emit('update:msg',值)
加.sync:对应父组件驼峰变量
不加.sync:对应父组件x-xx格式的变量
方式四:
子组件上使用v-model,和方式四类似写法
方式五:
使用ref
父组件中:this.$refs.xx.子组件的方法名();
(2)事件监听:
监听自定义名称事件:
this.$emit('test','hi')
this.$on('test',fn)
this.$once('test',fn) 只监听一次,监听器就会被移除
this.$off(['test',fn]) 移除自定义事件监听器
如果没有提供参数,则移除所有的事件监听器;
如果只提供了事件,则移除该事件所有的监听器;
如果同时提供了事件与回调,则只移除这个回调的监听器。
监听内部钩子变化:
$on/$once('hook:生命周期函数名称':fn);
如:this.$on("hook:updated",(res)=>{})
代码示例:
子组件:
<template lang='html'>
<div>
组件1
{{uname}},{{upwd}},{{info.address+'+'+info.sex}}
<button @click='clicks'>传递数据</button>
来自父组件的v-model方式:{{inp}}
</div>
</template>
<script>
export default{
name:'vue1',
data()
{
return{
}
},
props:['uname','upwd','info','inp'],
methods:{
clicks:function()
{
this.$emit("getMsg",'来自子组件');
}
}
}
</script>
<style lang='css'>
</style>
父组件:
<template>
<div id="app">
<img src="./assets/logo.png">
<Vuedemo />
<Vue1 @getMsg='get' uname='jeff' upwd='123' :info='info' :inp='inp'/>
{{data}}
<input type='text' v-model='inp'>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
import Vuedemo from './components/Vuedemo'
import Vue1 from './components/Vuee'
export default {
name: 'App',
data()
{
return{
info:{
address:'where',
sex:'male',
},
inp:'',
data:''
}
},
methods:{
get(msg)
{
this.data=msg;
}
},
components: {
HelloWorld,
Vuedemo,
Vue1
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>