14-自定义事件与todolist案例

6/3/2022

# 1, 自定义事件

# 1.1, 子组件传递给父组件

什么情况下子组件需要传递内容到父组件呢

  • 当子组件有一些事件发生的时候,比如在组件中发生了点击,父组件需要切换内容
  • 子组件有一些内容想要传递给父组件的时候

自定义事件的操作步骤

  • 首先,我们需要在子组件中定义好在某些情况下触发的事件名称
  • 其次,在父组件中以v-on的方式传入要监听的事件名称,并且绑定到对应的方法中
  • 最后,在子组件中发生某个事件的时候,根据事件名称触发对应的事件
// App.vue
<template>
  <div class="app">
    <h1>我是父组件 王健林</h1>
    <hr>
    <!-- 
      在使用子组件的位置绑定自定义事件

      事件源:MySon
      事件类型:wc
      监听器:handler

      如何触发MySon事件?
      答:在事件源(组件)内部通过$emit手动写代码触发!!!
          $emit("wc",500)
     -->
    <MySon @wc="handler" ref="cur"></MySon>
  </div>
</template>

<script>
import MySon from "./components/MySon.vue"
export default {
  name: 'App',
  components: {
    MySon
  },
  // 当组件挂载完毕执行一次mounted
  mounted(){  
    // 当代码走到这里,说明,组件都挂载,渲染完毕
    // 问:能不能获取组件实例? 答:可以

    // console.log(this.$refs.cur); // 得到VC实例

    // 可以通过$on绑定自定义事件
    // 当xq事件发生了,处罚监听器
    this.$refs.cur.$on("xq",(val)=>{
      // 谁触发了xq事件,就可以传递数据
      console.log("val:",val);
    })
  },  
  methods:{
    handler(val){
      // val是子传递给父的数据
      console.log("val:",val);
    }
  }
}
</script>

<style lang="less">
*{
  margin: 0;
  padding: 0;
}
html,body{
  width: 100%;
  height: 100%;
}
.app{
  width: 100%;
  height: 100%;
  background-color: pink;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// MySon.vue
<template>
  <div class="son">
      <h1>我是子组件 王思聪</h1>
      <!-- @click="clickHandler" 不叫自定义事件 -->
      <button @click="clickHandler">触发自定义事件</button>
  </div>
</template>

<script>
export default {
  name: "MySon",
  props:[],
  data() {
    return {
        money:500,
        car:"凤凰牌自行车"
    };
  },
  methods: {
      clickHandler(){
        //   console.log("clickHandler...");
        // 在这里,触发自定义事件

        // 在vc身上没有是$emit,沿着原型链可以去Vue的原型对象上找到$emit
        // console.log(this);

        // this.$emit("wc",this.money)

        this.$emit("xq",this.car)
      }
  },
};
</script>

<style lang="less" scoped>
div.son{
    width: 300px;
    height: 200px;
    background-color: gold;
    margin: 50px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 2, 自定义事件应用于TodoList

// App.vue
<TodoHeader @addTodo="addTodo"></TodoHeader>
1
2
// TodoHeader.vue
<template>
  <div class="todo-header">
    <input 
      type="text" 
      placeholder="请输入你的任务名称,按回车键确认" 
      @keyup.enter="enterHandler"
    />
  </div>
</template>

<script>
export default {
  name: "TodoHeader",
  data() {
    return {};
  },
  methods: {
    enterHandler(e){
      if(e.target.value.trim() === ""){
        alert("输入内容不能为空~")
        return;
      }

      // 拼装一个todo
      let newTodo = {id:Date.now(), title:e.target.value, done:false};

      // 触发自定义事件
      this.$emit("addTodo",newTodo)

      e.target.value = ""; // 清空输入框
    }
  },
};
</script>

<style lang="less" scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Last Updated: 12/25/2022, 10:02:14 PM