[Vue]组件自定义事件(二)

简介: [Vue]组件自定义事件(二)

2.4 触发自定义事件向处理函数传递多个参数

在接收参数时,不想书写多个形参,可以使用...扩展运算符将多个参数进行接收。

App.vue

<template>
  <div class="app">
    <h1>{{msg}}</h1>
    <School :getSchoolName="getSchoolName"></School>
    <!-- 
      1. 为子组件绑定自定义事件 MyEvent
          当自定义事件 MyEvent 被触发时,
          会调用事件的处理函数 getStudentName
    -->
    <!-- <Student @MyEvent="getStudentName"></Student> -->
    <!-- 
      2. 使用 ref 进行自定义事件的绑定
    -->
    <Student ref="student"></Student>
  </div>
</template>
<script>
//导入子组件
import Student from './components/Student'
import School from './components/School'
export default {
  name: 'App',
  components: { School, Student },
  data() {
    return {
      msg: '你好啊!'
    }
  },
  methods: {
    getSchoolName(name) {
      console.log('App收到了学校名:', name)
    },
    getStudentName(name, ...params) {
      console.log('App收到了学生名:', name)
      console.log('其他参数:', params)
    }
  },
  mounted() {
    // 为子组件 Student 绑定自定义事件
    this.$refs.student.$on('MyEvent', this.getStudentName)
  }
}
</script>
<style scoped>
.app {
  background-color: gray;
  padding: 5px;
}
</style>

Student.vue

<template>
  <div class="student">
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{sex}}</h2>
    <button @click="sendStudentName">把学生姓名给App</button>
  </div>
</template>
<script>
  export default {
    name:'Student',
    data() {
      return {
        name:'张三',
        sex:'男'
      }
    },
    methods: {
      sendStudentName() {
        console.log('点击了按钮"把学生姓名给App"')
        // 触发自定义事件
        // 将学生姓名传递给自定义事件的处理函数
        // 传递多个参数
        this.$emit('MyEvent', this.name, 1, 2, 3)
      }
    },
  }
</script>
<style scoped>
  .student{
    background-color: pink;
    padding: 5px;
    margin-top: 30px;
  }
</style>

2.5 自定义事件只触发一次

实现方法与使用vue的内置事件一样,使用事件修饰符

App.vue

<template>
  <div class="app">
    <h1>{{msg}}</h1>
    <School :getSchoolName="getSchoolName"></School>
    <Student @MyEvent.once="getStudentName"></Student>
    <!-- <Student ref="student"></Student> -->
  </div>
</template>
<script>
//导入子组件
import Student from './components/Student'
import School from './components/School'
export default {
  name: 'App',
  components: { School, Student },
  data() {
    return {
      msg: '你好啊!'
    }
  },
  methods: {
    getSchoolName(name) {
      console.log('App收到了学校名:', name)
    },
    getStudentName(name, ...params) {
      console.log('App收到了学生名:', name)
      console.log('其他参数:', params)
    }
  },
  mounted() {
    // 为子组件 Student 绑定自定义事件
    // 自定义事件只被触发一次
    // this.$refs.student.$once('MyEvent', this.getStudentName)
  }
}
</script>
<style scoped>
.app {
  background-color: gray;
  padding: 5px;
}
</style>

2.6 解绑自定义事件

解绑自定义事件,需要在被绑定自定义事件的子组件实例对象上进行自定义事件的解绑。

2.6.1 语法

解绑自定义事件,调用被绑定自定义事件的子组件实例对象上的$off()方法。

this.$off(自定义事件)

2.6.2 解绑一个自定义事件

// 解绑 MyEvent 自定义事件
this.$off('MyEvent')

Student.vue

<template>
  <div class="student">
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{sex}}</h2>
    <button @click="sendStudentName">把学生姓名给App</button>
    <button @click="offEvent">点击解绑自定义事件</button>
  </div>
</template>
<script>
  export default {
    name:'Student',
    data() {
      return {
        name:'张三',
        sex:'男'
      }
    },
    methods: {
      sendStudentName() {
        console.log('点击了按钮"把学生姓名给App"')
        this.$emit('MyEvent', this.name)
      },
      offEvent() {
        // 解绑 MyEvent 自定义事件
        console.log('解绑 MyEvent 自定义事件')
        this.$off('MyEvent')
      }
    },
  }
</script>
<style scoped>
  .student{
    background-color: pink;
    padding: 5px;
    margin-top: 30px;
  }
</style>

2.6.3 解绑多个自定义事件

解绑多个自定义事件,需要向$off()方法中传入一个数组,数组中的元素为需要解绑的自定义事件的名

// 解绑 MyEvent demo 自定义事件
this.$off(['MyEvent', 'demo'])

App.vue

<template>
  <div class="app">
    <h1>{{msg}}</h1>
    <School :getSchoolName="getSchoolName"></School>
    <Student 
      @MyEvent="getStudentName"
      @demo="demo"
    ></Student>
  </div>
</template>
<script>
//导入子组件
import Student from './components/Student'
import School from './components/School'
export default {
  name: 'App',
  components: { School, Student },
  data() {
    return {
      msg: '你好啊!'
    }
  },
  methods: {
    getSchoolName(name) {
      console.log('App收到了学校名:', name)
    },
    getStudentName(name) {
      console.log('App收到了学生名:', name)
    },
    demo() {
      console.log('自定义事件 demo 被触发...')
    }
  },
}
</script>
<style scoped>
.app {
  background-color: gray;
  padding: 5px;
}
</style>

Student.vue

<template>
  <div class="student">
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{sex}}</h2>
    <button @click="sendStudentName">把学生姓名给App</button>
    <button @click="offEvent">点击解绑自定义事件</button>
  </div>
</template>
<script>
  export default {
    name:'Student',
    data() {
      return {
        name:'张三',
        sex:'男'
      }
    },
    methods: {
      sendStudentName() {
        console.log('触发事件:')
        this.$emit('MyEvent', this.name)
        this.$emit('demo')
      },
      offEvent() {
        // 解绑 MyEvent demo 自定义事件
        console.log('解绑 MyEvent demo 自定义事件')
        this.$off(['MyEvent', 'demo'])
      }
    },
  }
</script>
<style scoped>
  .student{
    background-color: pink;
    padding: 5px;
    margin-top: 30px;
  }
</style>

2.6.4 解绑所有自定义事件

解绑所有自定义事件,向$off()方法中不传入参数即可

// 解绑所有自定义事件
this.$off()

Student.vue

<template>
  <div class="student">
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{sex}}</h2>
    <button @click="sendStudentName">把学生姓名给App</button>
    <button @click="offEvent">点击解绑自定义事件</button>
  </div>
</template>
<script>
  export default {
    name:'Student',
    data() {
      return {
        name:'张三',
        sex:'男'
      }
    },
    methods: {
      sendStudentName() {
        console.log('触发事件:')
        this.$emit('MyEvent', this.name)
        this.$emit('demo')
      },
      offEvent() {
        // 解绑 所有 自定义事件
        console.log('解绑 所有 自定义事件')
        this.$off()
      }
    },
  }
</script>
<style scoped>
  .student{
    background-color: pink;
    padding: 5px;
    margin-top: 30px;
  }
</style>

3. 自定义事件的注意点

3.1 使用 ref 绑定自定义事件中的 this

<template>
  <div class="app">
    <h1>{{msg}} 学生姓名:{{stuName}}</h1>
    <School :getSchoolName="getSchoolName"></School>
    <!-- <Student @MyEvent="getStudentName"></Student> -->
    <Student ref="stu"></Student>
  </div>
</template>
<script>
//导入子组件
import Student from './components/Student'
import School from './components/School'
export default {
  name: 'App',
  components: { School, Student },
  data() {
    return {
      msg: '你好啊!',
      stuName: ''
    }
  },
  methods: {
    getSchoolName(name) {
      console.log('App收到了学校名:', name)
    },
    getStudentName(name) {
      console.log('App收到了学生名:', name)
    },
  },
  mounted() {
    // 由于vue规定
    // 谁触发事件,对应的回调函数中的this就指向谁
    // 由于触发自定义事件 MyEvent 为Student组件,且普通函数拥有自己的this
    // 所以 this 指向 Student组件实例对象
    // this.stuName = name 所以相当于向Student组件中的stuName赋值
    this.$refs.stu.$on('MyEvent', function(name) {
      console.log('App收到了学生名:', name)
      this.stuName = name
    })
  },
}
</script>
<style scoped>
.app {
  background-color: gray;
  padding: 5px;
}
</style>

mounted() {
    // 由于vue规定
    // 谁触发事件,对应的回调函数中的this就指向谁
    // 更改为箭头函数
    // 由于箭头函数没有自己的this
    // 所以会在函数声明位置向外查找,即App组件实例对象
    // 所以箭头函数 this.stuName = name 就是向 App组件实例对象中的stuName赋值
    this.$refs.stu.$on('MyEvent', (name) => {
      console.log('App收到了学生名:', name)
      this.stuName = name
    })
  },

<template>
  <div class="app">
    <h1>{{msg}} 学生姓名:{{stuName}}</h1>
    <School :getSchoolName="getSchoolName"></School>
    <!-- <Student @MyEvent="getStudentName"></Student> -->
    <Student ref="stu"></Student>
  </div>
</template>
<script>
//导入子组件
import Student from './components/Student'
import School from './components/School'
export default {
  name: 'App',
  components: { School, Student },
  data() {
    return {
      msg: '你好啊!',
      stuName: ''
    }
  },
  methods: {
    getSchoolName(name) {
      console.log('App收到了学校名:', name)
    },
    getStudentName(name) {
      console.log('App收到了学生名:', name)
      this.stuName = name
    },
  },
  mounted() {
    // 此种写法,会先将getStudentName函数中的this指向Student组件实例对象
    // 但是由于getStudentName函数声明在App组件的methods中
    // 在methods中的方法,this一定指向所在组件的实例对象
    // 所以getStudentName中的this最终指向App组件实例对象
    this.$refs.stu.$on('MyEvent', this.getStudentName)
  },
}
</script>
<style scoped>
.app {
  background-color: gray;
  padding: 5px;
}
</style>

3.2 为子组件绑定内置事件

<!-- 这样子绑定内置事件,会被认为是自定义事件,只不过自定义事件名字是click -->
<Student ref="stu" @click="show"></Student>
• 1
• 2
// App组件 methods
    show() {
      alert(11111)
    }

为子组件绑定内置事件,且不让内置事件被认为是自定义事件,需要使用事件修饰符native,即可为子组件绑定内置事件。

<Student ref="stu" @click.native="show"></Student>

4. 组件自定义事件 总结

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件
  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
  3. 绑定自定义事件:
  1. 第一种方式,在父组件中:<Demo @atguigu="test"/><Demo v-on:atguigu="test"/>
  2. 第二种方式,在父组件中:
<Demo ref="demo"/>
......
mounted(){
   this.$refs.xxx.$on('atguigu',this.test)
}
  1. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。
  1. 触发自定义事件:this.$emit('atguigu',数据)
  2. 解绑自定义事件this.$off('atguigu')
  3. 组件上也可以绑定原生DOM事件,需要使用native修饰符。
  4. 注意:通过this.$refs.xxx.$on('atguigu',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!



相关文章
|
7天前
|
移动开发 JavaScript API
Vue Router 核心原理
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的路由功能。其核心原理包括路由配置、监听浏览器事件和组件渲染等。通过定义路径与组件的映射关系,Vue Router 将用户访问的路径与对应的组件关联,支持哈希和历史模式监听 URL 变化,确保页面导航时正确渲染组件。
|
10天前
|
监控 JavaScript 前端开发
ry-vue-flowable-xg:震撼来袭!这款基于 Vue 和 Flowable 的企业级工程项目管理项目,你绝不能错过
基于 Vue 和 Flowable 的企业级工程项目管理平台,免费开源且高度定制化。它覆盖投标管理、进度控制、财务核算等全流程需求,提供流程设计、部署、监控和任务管理等功能,适用于企业办公、生产制造、金融服务等多个场景,助力企业提升效率与竞争力。
61 12
|
6天前
|
JavaScript 前端开发 开发者
Vue中的class和style绑定
在 Vue 中,class 和 style 绑定是基于数据驱动视图的强大功能。通过 class 绑定,可以动态更新元素的 class 属性,支持对象和数组语法,适用于普通元素和组件。style 绑定则允许以对象或数组形式动态设置内联样式,Vue 会根据数据变化自动更新 DOM。
|
7天前
|
JavaScript 前端开发 数据安全/隐私保护
Vue Router 简介
Vue Router 是 Vue.js 官方的路由管理库,用于构建单页面应用(SPA)。它将不同页面映射到对应组件,支持嵌套路由、路由参数和导航守卫等功能,简化复杂前端应用的开发。主要特性包括路由映射、嵌套路由、路由参数、导航守卫和路由懒加载,提升性能和开发效率。安装命令:`npm install vue-router`。
|
28天前
|
JavaScript 安全 API
iframe嵌入页面实现免登录思路(以vue为例)
通过上述步骤,可以在Vue.js项目中通过 `iframe`实现不同应用间的免登录功能。利用Token传递和消息传递机制,可以确保安全、高效地在主应用和子应用间共享登录状态。这种方法在实际项目中具有广泛的应用前景,能够显著提升用户体验。
54 8
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1074 0
|
2月前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
147 1
|
28天前
|
存储 设计模式 JavaScript
Vue 组件化开发:构建高质量应用的核心
本文深入探讨了 Vue.js 组件化开发的核心概念与最佳实践。
74 1
|
3月前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
111 58
|
2月前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。

热门文章

最新文章