组件传值
父组件向子组件传值
组件内部通过props接收传递过来的值,父组件通过属性将值传递给子组件。
- 静态绑定
<body>
<div id="app">
<test title="来自父组件的值"></test>
</div>
</body>
<script>
Vue.component('test', {
props: ['title'],
data: function() {
return {
msg: '子组件的数据'
}
},
template: '<div>{{title + "-" + msg}}</div>'
})
var vm = new Vue({
el:'#app',
data: {
pmsg: '内容'
}
})
</script>
- 动态绑定
<test :title="title"></test>
props属性名规则:
- 在props中使用驼峰形式,模板中需要使用短横线的形式
Vue.component('test', {
//驼峰
props: ['titleName'],
data: function() {
return {
msg: '子组件的数据'
}
},
template: '<div>{{titleName + "-" + msg}}</div>'
})
//短横线形式
<div id="app">
<test title-name="来自父组件的值"></test>
</div>
- 字符串形式的模板中没有这个规则
Vue.component('test', {
props: ['titleName'],
data: function() {
return {
msg: '子组件的数据'
}
},
//在字符串中可以使用驼峰形式myName
template: '<div>{{titleName + "-" + msg}}<test1 myName="yc"></test1></div>'
})
Vue.component('test1', {
props: ['myName'],
template: '<div>{{myName}}</div>'
})
props属性值类型:
<body>
<div id="app">
<test :pstr="pstr" :pnum="12" :pboo="pboo" :parr="parr" :pobj="pobj"></test>
</div>
</body>
<script>
Vue.component('test', {
props: ['pstr','pnum','pboo','parr','pobj'],
template: `
<div>
<div>{{pstr}}</div>
<div>{{pnum}}</div>
<div>{{pboo}}</div>
<ul>
<li :key="index" v-for='(item,index) in parr'>{{item}}</li>
</ul>
<div>{{pobj.name}}</div>
</div>
`
})
var vm = new Vue({
el:'#app',
data: {
pstr: '内容',
pboo:true,
parr:[1,2,34],
pobj: {
name: 'yc',
age: 24
}
}
})
</script>
子组件向父组件传值
props传递数据原则,单向数据流。
- 子组件通过自定义事件向父组件传递信息
//触发方法$emit enlarge-text自定义事件
<button v-on:click='$emit("enlarge-text")'>扩大字体</button>
- 父组件监听子组件的事件
<menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>
<body>
<div id="app">
<div :style="{fontSize: fontSize + 'px'}">{{msg}}</div>
<test @enlarge-text="onLarge"></test>
</div>
</body>
<script>
Vue.component('test', {
template: `
<div>
<button @click='$emit("enlarge-text")'>扩大字号</button>
</div>
`
})
var vm = new Vue({
el:'#app',
data: {
msg: '遥岑',
fontSize: 10
},
methods: {
onLarge:function() {
this.fontSize += 5
}
}
})
</script>
传参:
- 子组件通过自定义事件向父组件传递信息
//第二个参数传参
<button v-on:click='$emit("enlarge-text",0.1)'>扩大字体</button>
- 父组件监听子组件的事件
//$event接收值
//如果绑定的函数 可以将$event作为参数传递给函数
<menu-item v-on:enlarge-text='fontSize += $event'></menu-item>
<body>
<div id="app">
<div :style="{fontSize: fontSize + 'px'}">{{msg}}</div>
<test @enlarge-text="onLarge($event)"></test>
</div>
</body>
<script>
Vue.component('test', {
template: `
<div>
<button @click='$emit("enlarge-text",5)'>扩大字号</button>
</div>
`
})
var vm = new Vue({
el:'#app',
data: {
msg: '遥岑',
fontSize: 10
},
methods: {
onLarge:function(val) {
this.fontSize += val
}
}
})
</script>
兄弟组件间传值
- 单独事件中心管理组件间的通信
//扮演事件中心角色
var eventHub = new Vue()
- 监听事件与销毁事件
//第一个参数:自定义事件名称 第二个参数:自定义函数
eventHub.$on('add-todo', addTodo)
eventHub.$off('add-todo')
- 触发事件
eventHub.$emit('add-todo', id)
<body>
<div id="app">
<div>父组件</div>
<button @click="destory">销毁</button>
<test></test>
<test1></test1>
</div>
</body>
<script>
//事件中心
var hub = new Vue()
Vue.component('test',{
data: function() {
return {
num:0
}
},
template: `
<div>
<div>Tom:{{num}}</div>
<button @click="handle">点击</button>
</div>
`,
methods: {
handle: function() {
hub.$emit('jerry-event',2)
}
},
mounted: function() {
//监听事件
hub.$on('tom-event',(val)=> {
this.num += val
})
}
})
Vue.component('test1',{
data: function() {
return {
num:0
}
},
template: `
<div>
<div>Jerry:{{num}}</div>
<button @click='handle'>点击</button>
</div>
`,
methods: {
handle: function() {
hub.$emit('tom-event',1)
}
},
mounted: function() {
//监听事件
hub.$on('jerry-event',(val)=> {
this.num += val
})
}
})
var vm = new Vue({
el:'#app',
methods: {
destory:function() {
hub.$off('tom-event')
hub.$off('jerry-event')
}
}
})
</script>
组件插槽
父组件向子组件传递内容
<body>
<div id="app">
<alert-box>有bug</alert-box>
<alert-box>有问题</alert-box>
<alert-box></alert-box>
</div>
</body>
<script>
Vue.component('alert-box', {
template: `
<div>
<strong>Error:</strong>
<slot>默认内容</slot>
</div>
`
})
var vm = new Vue({
el:'#app',
data: {
}
})
</script>
具名插槽
根据名称进行匹配,没有匹配到的放在默认插槽中。
<body>
<div id="app">
<alert-box>
<p slot="header">标题</p>
<p>内容</p>
<p slot="footer">底部</p>
</alert-box>
</div>
</body>
<script>
Vue.component('alert-box', {
template: `
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
`
})
var vm = new Vue({
el:'#app',
data: {
}
})
</script>
作用域插槽
父组件对子组件进行加工处理,在父组件中获得子组件的数据对它进行加工。
<body>
<div id="app">
<fruit-box :list="list">
<!-- slotProps接收子组件自定义属性传过来的值 -->
<template slot-scope="slotProps">
<strong v-if="slotProps.info.id === 1" class="current">{{slotProps.info.name}}</strong>
<span v-else>{{slotProps.info.name}}</span>
</template>
</fruit-box>
</div>
</body>
<script>
Vue.component('fruit-box', {
props: ['list'],
//info子组件自定义属性
template: `
<div>
<li :key="item.id" v-for="item in list">
<slot :info='item'>{{item.name}}</slot>
</li>
</div>
`
})
var vm = new Vue({
el:'#app',
data: {
list: [{
id:1,
name: 'apple'
},{
id: 2,
name: 'orange'
},{
id: 3,
name: 'banana'
}]
}
})
</script>