上篇介绍了组件的注册、模板和嵌套组件的写法,这篇主要介绍组件之间的传值和操作,包括父子组件传值、平行组件传值、父组件操作子组件,子组件操作父组件。
- 父组件传值给子组件
父组件->子组件 通过在子组件标签上绑定自定义属性名,父组件数据为属性值。
子组件内部通过props属性 数组形势 接收属性名 模版内部通过解析属性名加载数据。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="out">
<h2>父组件传值子组件</h2>
<v-parent></v-parent>
</div>
<template id="parent">
<div>
<h1>父组件</h1>
<p>{{str}}</p>
<button @click="tap()">发送给子组件</button>
<hr />
<v-child :name="str1"></v-child>
</div>
</template>
<template id="child">
<div>
<h2>子组件</h2>
<p>{{str}}</p>
<h3>接收父组件传递的数据--{{name}}</h3>
<button @click="tap()">子组件事件</button>
</div>
</template>
</body>
<script type="text/javascript">
var vm=new Vue({
el:'#out',
data:{
},
methods:{
},
components:{
'v-parent':{
template:'#parent',
data:function(){
return{
str:'这是父组件的数据',
str1:''
}
},
methods:{
tap(){
this.str1=this.str
}
},
components:{
'v-child':{
props:['name'],
template:'#child',
data:function(){
return{
str:'this is child infos'
}
},
methods:{
tap(){
console.log(this.str)
}
}
}
}
}
}
})
</script>
</html>
- 子组件传值父组件
子组件-父组件 通过在子组件标签上绑定自定义事件名,事件调用的函数(不能加())声明
在父组件内部,函数参数为接收的数据值,子组件内部通过$emit进行推送
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="out">
<h2>子组件传值父组件</h2>
<v-parent></v-parent>
</div>
<template id="parent">
<div>
<h1>父组件</h1>
<h3>接收子组件的数据--{{str}}</h3>
<hr />
<v-child @toparent="getdata"></v-child>
</div>
</template>
<template id="child">
<div>
<h2>子组件</h2>
<p>{{str}}</p>
<button @click="tap()">发送给父组件</button>
</div>
</template>
</body>
<script type="text/javascript">
var vm=new Vue({
el:'#out',
data:{
},
methods:{
},
components:{
'v-parent':{
template:'#parent',
data:function(){
return{
str:''
}
},
methods:{
getdata(msg){
this.str=msg
}
},
components:{
'v-child':{
template:'#child',
data:function(){
return{
str:'this is child infos'
}
},
methods:{
tap(){
this.$emit('toparent',this.str)
}
}
}
}
}
}
})
</script>
</html>
- 父子传值(父到子,子到父)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>父子传值</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="out">
<h1>{{str}}</h1>
<v-parent></v-parent>
</div>
<template id="parent">
<div>
<h2>{{tit}}</h2>
<p>这是父组件的数据-----{{str}}</p>
<p>我要接受子组件的传值------{{str2}}</p>
<button @click="tap()">发送给子组件</button>
<hr />
<v-child :name="str1" @toparent="getdata"></v-child>
</div>
</template>
<template id="child">
<div>
<h2>{{tit}}</h2>
<p>这是子组件的数据-----{{str}}</p>
<p>我要接受父组件的传值------{{name}}</p>
<button @click="tap()">发送给父组件</button>
</div>
</template>
</body>
<script type="text/javascript">
var vm = new Vue({
el:"#out",
data:{
str:"组件嵌套"
},
methods:{
},
components:{
"v-parent":{
template:"#parent",
data:function(){
return{
tit:"父组件",
str:"哈哈哈哈,我是父组件",
str1:"",
str2:""
}
},
methods:{
tap(){
this.str1=this.str
},
getdata(msg){
this.str2 = msg
}
},
components:{
"v-child":{
props:["name"],
template:"#child",
data:function(){
return{
tit:"子组件",
str:"啦啦啦啦,我是子组件",
}
},
methods:{
tap(){
this.$emit("toparent",this.str)
}
}
}
}
}
}
})
</script>
<!--父到子---属性;子到父---事件;平行---新的vue对象-->
</html>
- 平行组件之间传值
平行组件-- 核心 空vue对象 调用 $emit 推送 $on 接收
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>平行组件</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="out">
<h1>平行组件传值</h1>
<hr />
<v-a></v-a>
<hr />
<v-b></v-b>
<hr />
<v-c></v-c>
</div>
<template id="aa">
<div>
<h2>{{str}}</h2>
<p>这是a组件的数据------{{str1}}</p>
<button @click="tap()">发送给c组件</button>
</div>
</template>
<template id="bb">
<div>
<h2>{{str}}</h2>
<p>这是b组件的数据-----{{str1}}</p>
<button @click="tap()">发送给c组件</button>
</div>
</template>
<template id="cc">
<div>
<h2>{{str}}</h2>
<p>接收A组件的传值-----{{stra}}</p>
<p>接收B组件的传值-----{{strb}}</p>
</div>
</template>
</body>
<script type="text/javascript">
var vm1 = new Vue({})
var vm = new Vue({
el:"#out",
data:{
},
methods:{
},
components:{
"v-a":{
template:"#aa",
data:function(){
return{
str:"a组件",
str1:"aaaaaa"
}
},
methods:{
tap(){
// console.log(this.str1)
vm1.$emit("isa",this.str1)
}
}
},
"v-b":{
template:"#bb",
data:function(){
return{
str:"b组件",
str1:"bbbbb"
}
},
methods:{
tap(){
// console.log(this.str1)
vm1.$emit("isb",this.str1)
}
}
},
"v-c":{
template:"#cc",
data:function(){
return{
str:"c组件",
stra:"",
strb:""
}
},
mounted(){
var _this = this
vm1.$on("isa",function(msg){
_this.stra = msg
})
vm1.$on("isb",function(msg){
_this.strb = msg
})
}
}
}
})
</script>
</html>
- 组件间的操作
父组件操作子组件---$refs $parent----子组件操作父组件数据
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>组件操作</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="out">
<h1 ref="s1">{{tit}}</h1>
<button @click="tap()">操作dom</button>
<hr />
<v-parent></v-parent>
</div>
<template id="parent">
<div>
<h2>父组件</h2>
<button @click="tap()">操作子组件</button>
<hr />
<v-child ref="childs"></v-child>
</div>
</template>
<template id="child">
<div>
<h2>子组件</h2>
<button @click="tap()">操作父组件</button>
</div>
</template>
</body>
<script type="text/javascript">
var vm = new Vue({
el:"#out",
data:{
tit:"组件操作"
},
methods:{
tap(){
console.log(this.$refs.s1.innerHTML)
}
},
components:{
"v-parent":{
template:"#parent",
data:function(){
return{
str:"父组件数据"
}
},
methods:{
tap(){
console.log(this.$refs.childs.str) //子组件数据
}
},
components:{
"v-child":{
template:"#child",
data:function(){
return{
str:"子组件数据"
}
},
methods:{
tap(){
console.log(this.$parent.str)
}
}
}
}
}
}
})
</script>
</html>
注: 在mounted函数中,使用$refs获取dom 时候,dom树有时候未更新,这就需要用到$ nextTick
/*nextTick里面的代码会在DOM更新后执行*/---mounted函数中执行
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>最新dom</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="out">
<h1>最新dom</h1>
<p ref="tit">{{str}}</p>
</div>
</body>
<script type="text/javascript">
var vm = new Vue({
el:"#out",
data:{
str:"hello world"
},
mounted(){
this.str="你好 世界"
// console.log(this.$refs.tit.innerHTML) //hello world
this.$nextTick(function(){
console.log(this.$refs.tit.innerHTML)
})
}
})
</script>
</html>
- solt分发(插槽)
使用slot发布内容
Slot标签添加 属性 <slot name="ul-slot">
扫描二维码关注公众号,回复:
2893001 查看本文章
内容可通过 slot属性值查找是否显示默认<ul slot="ul-slot">
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>slot分发(插槽)</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="out">
<h2>slot插槽</h2>
<v-header>
<ol slot="oll">
<li>1</li>
<li>2</li>
<li>3</li>
</ol>
<!--不用slot,相当于组件标签内没有内容,显示slot注册的内容-->
<!--<ul>
<li>111</li>
</ul>-->
<!--有内容显示内容-->
<ul slot="hi">
<li>222</li>
</ul>
</v-header>
</div>
<template id="header">
<div>
<h3>组件---</h3>
<slot name="oll">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate consectetur accusantium incidunt ex modi itaque alias magni quo aperiam dolorum hic dolor facere optio vero porro explicabo facilis error! Esse.</slot>
<slot name="hi">哈哈哈</slot>
</div>
</template>
</body>
<script type="text/javascript">
var vm = new Vue({
el:"#out",
data:{
},
components:{
"v-header":{
template:"#header"
}
}
})
</script>
</html>
solt用于在组件标签内写入内容显示出来,没有内容的时候展示solt里面的内容。