<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
<style>
.container{
padding: 10px;
border: 1px solid #AAA;
width: 300px;
box-sizing: border-box;
margin: 20px auto;
}
.container h3 {
font-size: 16px;
font-weight: bold;
line-height: 40px;
border-bottom: 1px dashed #aaa;
}
</style>
</head>
<body>
<!-- 父组件把信息传递给子组件:props 属性传递
默认传递给子组件的属性值都是字符串格式的, 如果 需要传递数据的格式是数据本身 应该具备的格式,
需要基于 v-bind 实现传递
-->
<div id="app">
<my-vote v-for="item in voteList" :key="item.id" :title="item.title"></my-vote>
</div>
<!-- template -->
<template id="MyVoteTemplate">
<div class="container">
<h3> <span v-text="title"></span> (<span v-text="num"></span>)</h3>
<vote-content :eventbus=‘eventBus‘></vote-content>
<!-- 基于自定义事件 把父组件中的某个方法注册到任务队列中 -->
<vote-button :eventbus=‘eventBus‘ @changeparent="changeParent"></vote-button>
</div>
</template>
<template id="VoteContentTemplate">
<div class="content">
<p>支持人数<span v-text="supNum"></span></p>
<p>反对人数<span v-text="oppNum"></span></p>
<p>支持率<span v-text="ratio"></span></p>
</div>
</template>
<template id="VoteButtonTemplate">
<div class="footer">
<button type="button" class="btn btn-primary" @click="handle(‘support‘)"> 支持 </button>
<button type="button" class="btn btn-danger" @click="handle(‘oppose‘)"> 反对 </button>
</div>
</template>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
const VoteContent = {
template:‘#VoteContentTemplate‘,
props:[‘eventbus‘],
data(){
return {
supNum:0,
oppNum:0
}
},
computed:{
ratio(){
let total = this.supNum + this.oppNum;
if(total === 0){
return ‘0%‘;
}
return (this.supNum/total * 100).toFixed(2) + ‘%‘;
}
},
methods:{
changeNum(type){
type === ‘support‘ ? this.supNum++ : this.oppNum++;
}
},
created(){
// 基于 $on 创建一个自定义事件 把指定的方法放到 任务队列中
this.eventbus.$on(‘changesupport‘,this.changeNum)
}
}
const VoteButton = {
template:‘#VoteButtonTemplate‘,
props:[‘eventbus‘],
data(){
return {}
},
methods:{
handle(type){
// 通知任务队列中 @changeParent这个自定义事件执行
// console.log(type)
this.$emit(‘changeparent‘,type)
// 通知 eventBus 任务队列中的 changesupport 自定义事件执行
this.eventbus.$emit(‘changesupport‘,type)
}
}
}
const MyVote = {
template:‘#MyVoteTemplate‘,
// 1 子组件设置props 用来接收父组件 基于属性传递进来的信息
// 2 注册 属性的校验
props:["title"],
data(){
return {
num:0,
eventBus: new Vue
}
},
components:{
VoteContent,
VoteButton
},
methods:{
changeParent(type){
// this.$emit通知执行的时候的参数传递
this.num++;
}
},
mounted(){
// 基于属性传递进来的值,只能获取使用,不能在子组件中修改
// this.title = ‘AAA‘
}
}
let vm = new Vue({
el: "#app",
data: {
voteList:[
{
id:1,
title:‘Eric‘
},
{
id:2,
title:‘小鱼‘
}
]
},
// 注册当前组件
components:{
MyVote
},
// mounted(){
// setTimeout(()=>{
// this.voteList = this.voteList.map(item =>{
// if(item.id === 1){
// item.title = ‘Ericlovefish‘
// }
// return item;
// })
// },1000)
// }
});
</script>
</body>
</html>