代码语言:javascript复制
1 <div id="app">
2 <xz-todo></xz-todo>
3 </div>
4 <!--1. 为每个组件定义HTML 模板,有几个组件,就要创建几个template-->
5 <template id="tplTodo">
6 <div>
7 <h3>父组件xz-todo: 代办事项列表</h3>
8 <xz-todo-input></xz-todo-input>
9 <!--父要给子tasks(右),绑定在子的tasks属性(左)中-->
10 <xz-todo-list :tasks="tasks"></xz-todo-list>
11 </div>
12 </template>
13 <template id="tplTodoInput">
14 <div>
15 <h6>子组件xz-todo-input</h6>
16 <input v-model="input" @keyup.13="addFun"><button @click="addFun">添加</button>
17 </div>
18 </template>
19 <template id="tplTodoList">
20 <div>
21 <h6>子组件xz-todo-list</h6>
22 <ul>
23 <xz-todo-item v-for="(t,i) in tasks" :t="t" :i="i" @remove="removeHandler">
24 <!--当子组件触发remove时,就自动执行handler-->
25 </xz-todo-item>
26 </ul>
27 </div>
28 </template>
29 <template id="tplTodoItem">
30 <li>
31 <p>孙子组件xz-todo-item</p>
32 <span>{{t}}</span><button @click="removeFun">x</button>
33 </li>
34 </template>
35 <script>
36 var bus=new Vue();//先建公交车
37 //2. 除全局父组件外,为每个子组件创建对象
38 var xzTodoInput={
39 template:"#tplTodoInput",
40 data:function(){
41 return { input:"" }
42 },
43 methods:{
44 addFun(){
45 if(this.input.trim()!==""){
46 bus.$emit("add",this.input)
47 this.input="";
48 }
49 }
50 }
51 };
52 var xzTodoItem={//强调: 子组件对象必须先于父组件定义
53 template:"#tplTodoItem",
54 //因为子想要任务名(显示)和下标(删除)
55 props:["t","i"],
56 methods:{
57 removeFun(){
58 if(confirm("是否删除?"))
59 this.$emit("remove",this.i);
60 }
61 }
62 };
63 var xzTodoList={
64 template:"#tplTodoList",
65 props:["tasks"],//因为子想要tasks列表
66 components:{
67 //可用components继续包含更子级组件
68 xzTodoItem
69 },
70 methods:{
71 //当remove发生时,自动调用handler,获得子组件传来的i
72 removeHandler(i){
73 this.tasks.splice(i,1);
74 }
75 },
76 mounted(){
77 //this->Vue
78 bus.$on("add",input=>{//必须用=>
79 this.tasks.push(input)
80 })
81 }
82 };
83 //3. 定义全局父组件,components中仅包含直接子组件
84 Vue.component("xz-todo",{
85 template:"#tplTodo",
86 data:function(){
87 return {//1. 因为整个组件需要一个任务列表,所以:
88 tasks:[]
89 }
90 },
91 components:{//子组件
92 xzTodoInput,//xz-todo-input
93 xzTodoList //xz-todo-list
94 },
95 mounted(){//2. 在全局父组件中,加载并保存列表数据
96 this.tasks=["吃饭","睡觉","打豆豆"];
97 }
98 })
99 //4. new Vue()
100 new Vue({
101 el:"#app",
102 data:{}
103 })
104 </script>