直接上代码,代码中有注释
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>TODO</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
ol li {
text-decoration: line-through;
}
li {
list-style: none
}
</style>
</head>
<body>
<div id="app">
<h3>todo</h3>
<div>
<label for="content">Content:</label>
<!-- v-model 双向绑定 -->
<input type="text" id="content" v-model="inputValue">
<!-- @click 绑定点击事件 add -->
<button type="button" @click="add">add</button>
</div>
<!--
:content 子组件接受参数名
inputContent 父组传递参数
@call 父组件监听 子组件 call 事件,来完成 子组件对父组件传值
子组件触发后,父组件监听到 call 发布,后调用 handleAddCallBack
-->
<unfinished-item :content="this.inputContent" @call="handleAddCallBack"></unfinished-item>
<finished-item></finished-item>
</div>
<script>
//(Bus/总线/发布订阅/观察者模式)
//所有 vue 对象都有bus
Vue.prototype.bus = new Vue();
// 未完成组件
let unfinishedItem = {
// 接受父组件 传值
props: {
content: String // 校验参数必须为String,其他参数可看 Api
},
data: function () { // 子组件 data 必须为函数
return {
list: []
}
},
template: `<ul>
<li v-for="(item,index) of list" :key="item.id" @click="finish(item,index)">{{item.content}}</li>
</ul>`,
watch: {
content: function (val) {
console.log('watch')
if (val) {
var item = {
id: Math.random(),
content: val
};
this.list = [...this.list, item];
// 发布 call ,父组件可通过 v-on/@ 监听
this.$emit('call');
}
}
},
methods: {
finish: function (item, index) {
this.list.splice(index, 1);
// 发布 finish ,全局 bus 可通过 v-on/@ 监听
// 发布 finish
this.bus.$emit('finish', item);
}
}
}
//完成组件
let finishedItem = {
data: function () {
return {
list: []
}
},
template: `<ol>
<li v-for="item of list" :key="item.id">{{item.content}}</li>
</ol>`,
mounted: function () {
let this_ = this;
// 监听(观察)finish 全局 bus 可通过 v-on/@ 监听
this.bus.$on('finish', function (item) {
this_.list = [...this_.list, item]
})
}
}
let vm = new Vue({
el: '#app',
data: { //父组件 data 可为对象 子组件 data 必须为函数
inputValue: '',
inputContent: ''
},
components: {
unfinishedItem,
finishedItem
},
methods: {
add: function () {
//将 输入内容 赋值给 传递子组件 参数 inputContent
if (this.inputValue) {
this.inputContent = this.inputValue;
}
},
handleAddCallBack: function () {
this.inputValue = ''
this.inputContent = ''
}
}
});
</script>
</body>
</html>