Vue非父子级通信

2022-05-05 16:23:35 浏览数 (1)

代码语言: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>

0 人点赞