1.$emit 的使用

在组件中注册自定义事件

$emit(事件名, 参数)    //该参数会当作第一个参数传入绑定的函数中

下面用一个菜单栏例子来说明,如下图所示

组件

Vue.component('menu-cmp', {//注册propprops: {menu: Object,isActive: Boolean,menuIndex: Number},template: `<div><div class="first-menu"//注册自定义事件,事件名为handle-second-menu,第二个参数则作为被绑定函数的第一个参数@click="$emit('handle-second-menu', {isActiev:menu.isActive,id:menuIndex})">{{menu.firstMenu}}</div><div v-show="menu.isActive" class="second-menu" v-for="secondMune in menu.secondMenuList">{{ secondMune }}</div></div>`
})

组件引用

<div id="app"><menu-cmp class="menu-list" v-for="(menu,menuIndex) in menuList" :menu='menu' :menu-index='menuIndex'@handle-second-menu="handleSecondMenu">    //给自定义事件绑定函数//注:这里的事件处理为函数handleSecondMenu,如果逻辑量少,无需函数处理,那么$emit的第二个参数可以通过$event访问</menu-cmp>
</div>

Vue实例

const vm = new Vue({el: '#app',data: {menuList: [{firstMenu: '一级菜单1',secondMenuList: ['二级菜单1', '二级菜单2', '二级菜单3'],isActive: true,}, {firstMenu: '一级菜单2',secondMenuList: ['二级菜单1', '二级菜单2', '二级菜单3'],isActive: true,}, {firstMenu: '一级菜单3',secondMenuList: ['二级菜单1', '二级菜单2', '二级菜单3'],isActive: true,},]},methods: {handleSecondMenu(res) {//res是$emit()的第二个参数this.menuList[res.id].isActive = !this.menuList[res.id].isActive}}
})

css

.menu-list {width: 200px;height: 50px;text-align: center;display: inline-block;vertical-align: top;background-color: brown;box-sizing: border-box;
}
.menu-list:not(:last-of-type) {border-right: 1px solid #eee;
}
.menu-list .first-menu {width: 100%;height: 50px;line-height: 50px;box-sizing: border-box;border-bottom: 1px solid #eee;
}
.menu-list .second-menu {width: 100%;height: 50px;line-height: 50px;
}
.menu-list .second-menu.active {display: block;
}

2.事件名

不同于组件和prop:

  1. 事件名不存在任何自动化的大小写转换,而是触发的事件名需要完全匹配监听这个事件所有的名称,即如果触发一个handleMenu 事件,那么监听 handle-menu 是没有效果的;
  2. 事件名不会被当作一个JS变量名或者属性名,所以就没有理由使用大驼峰或者小驼峰式命名

另外,v-on事件监听器在DOM模板中会被自动转换为全小写,所以@handleMenu 将会变为@handlemenu ,导致事件监听失败,因此,应当使用短横线命名法

3.修饰符.native _ 将原生事件绑定到组件

在组件上监听事件时,监听的是组件自动触发的自定义事件,但是在一些情况下可能想要在一个组件的根元素上直接监听一个原生事件。这时,可以用 v-on 指令的 .native 修饰符,如:

组件

Vue.component('my-input', {template:`<input type="text">`
})

组件引用

<div id="app"><my-input @focus.native="onFocus"></my-input>
</div>

Vue实例

const vm = new Vue({el:"#app",methods:{onFocus(){console.log('focus');}}
})

【结果】

4.$listeners

当<input>标签不是组件的根元素,即包裹在其他标签中时,父级的.native 监听器将静默失败。虽然不会产生报错,但是 onFocus 处理函数不会被调用。为了解决这个问题,Vue提供了一个 $listeners 属性,它是一个对象,里面包含了作用在这个组件上所有的监听器,有了这个 $linteners 属性,我们可以配合 v-on="$linteners" 将所有的事件监听器指向这个组件的某个特性的子元素,如:

组件

Vue.component('my-input', {template: `<label>姓名<input type="text" v-on="$listeners"></label>`
})

组件引用

<my-input @focus="onFocus"></my-input>

5.在组件上使用v-model

由于自定义事件的出现,在组件上也可以使用 v-model 指令。

在 input 元素上使用 v-model 指令时,相当于绑定了 value 特性以及监听了 input 事件

<input v-model="searchText" />

等价于

<input:value="searchText"@input="searchText = $event.target.value"
>

当把 v-model 指令引用在组件上时

<base-input v-model="searchText" /> 

等价于

<base-input:value="searchText"@input="searchText = $event"
/>

同 input 元素一样,在组件上使用 v-model 指令,也是绑定了 value 特性,监听了 input 事件。所以 为了让 v-model 指令正常工作,这个组件内的<input>元素必须满足

  1. 将其 value 特性绑定到一个叫 value 的 prop 上
  2. 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出

组件

Vue.component('my-input',{props:['value'],template:`<input :value="value" @input="$emit('input',$event.target.value)">`
})

组件引用

<my-input v-model="searchText"></my-input>

Vue实例

const vm = new Vue({el:"#app",data:{searchText:''}
})

【结果】

综上所述,一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不用的目的。遇到这种情况,我们可以利用 model 选项来避免冲突:

组件

Vue.component('my-checkbox', {//model选项model: {prop: 'checked',event: 'change'},props: {checked: Boolean},template: `<input type="checkbox":checked="checked"@change="$emit('change',$event.target.checked)">`
})

组件引用

<my-checkbox v-model="isChecked"></my-checkbox>

Vue实例

const vm = new Vue({el: "#app",data: {isChecked: ''}
})

【结果】

6. .sync修饰符(语法糖)

除了使用 v-model 指令实现组件与外部数据的双向绑定外,还可以用 v-bind 指令的修饰符. sync 来实现

组件

Vue.component('my-input1',{props:['value'],template:`<input :value="value"@input="$emit('update:value',$event.target.value)">`
})

组件引用

<my-input1 :value.sync="searchText"></my-input1>

Vue实例

const vm = new Vue({el:"#app",data:{searchText:''}
})

【注】当用一个对象同时设置多个 prop 时,也可以将 .sync 修饰符和 v-bind 配合使用

<base-input v-bind.sync="obj"></base-input>

注意:

  1. 带有 .sync 修饰符的 v-bind 指令,只能提供想要绑定的属性名,不能和表达式一起使用,如::title.sync="1+1",这样操作是无效的
  2. 将 v-bind.sync 用在一个字面量对象上,如 v-bind.sync="{titel: 'haha'}",是无法工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。

7.v-model VS .sync

  1. 两者都是用于实现双向数据传递的,实现方式都是语法糖,最终通过 prop + 事件 来达成目的
  2. vue 1.x 的.sync 和 v-model 是完全两个东西,vue 2,3 之后可以理解为一类特性,使用场景略有区别
  3. 当一个组件对外只暴露一个受控的状态,且都符合统一的标准时,使用 v-model 来处理; .sync 则更为灵活,凡是需要双向数据传递的,都可以使用

vue_组件_监听组件事件相关推荐

  1. SpringBoot--->>>原理解析-->>自定义事件监听组件

    自定义事件监听组件 在上面了解了在程序启动时准备工作和启动过程会扫描 spring.factories 中的配置,拿到要启动的各种配置.这也说明可以自己自定义一些程序启动时会自动扫描的文件,然后在 r ...

  2. element-ui 搜索框组件:监听input键盘事件 - 代码篇

    踩坑:vue + element-ui 框架监听input键盘事件 - 含demo演示 代码示下: html部分: <el-inputplaceholder="职位 | 地区 | 工作 ...

  3. Vue钩子函数之钩子事件hookEvent,监听组件

    在Vue当中,hooks可以作为一种event,在Vue的源码当中,称之为hookEvent. 在Vue组件中,可以用过$on,$once去监听所有的生命周期钩子函数,如监听组件的updated钩子函 ...

  4. vue 组件属性监听_详解vuex 中的 state 在组件中如何监听

    前言 不知道大家有没有遇到过这样一种情况? vuex中的state会在某一个组建中使用,而这个状态的初始化是通过异步加载完成的.组件在渲染过程中,获取的state状态为空.也就是说组件在异步完成之前就 ...

  5. 前端开发——Vue 监听组件生命周期

    监听组件生命周期 通常我们使用 $emit 监听组件生命周期,父组件接收事件进行通知. 子组件 export default {mounted() {this.$emit( listenMounted ...

  6. js 监听 安卓事件_百行代码实现js事件监听实现跨页面数据传输

    百行代码实现js事件监听实现跨页面数据传输 使用场景 类似消息队列的使用场景,支持同页面和跨页面通信,发送消息和接收消息 技术原理 跨页面通信: 基于事件监听,通过监听 storage事件监听回调机制 ...

  7. chromedp网络监听_动态爬虫三:监听网络事件 + 监听js事件

    一: 概述 上两篇文章介绍了cdp协议和chromedp库,从这篇文章开始动手实战一下,我们要拿到页面上更多的网络请求,最直接的想法就是类似于开发者工具里的network,只有一有网络请求就显示在列表 ...

  8. vue组件加载完成之后执行方法_vue-cli监听组件加载完成的方法

    在使用vue-cli开发项目时遇到过一个问题,要求是页面组件全部加载完成后再执行某个函数,给上代码参考,方法可能有点笨,好在实现了功能. 1.安装vuex npm install vuex --sav ...

  9. vue 学科年级学段多级联动需求 跨组件如何监听 如何解决vue-communicatio监听多个参数的问题 以及vue-communicatio的注意事项

    最近的项目中有这么一个需求 先解释一下需求 顶部是一个多级联动的组件,用来选择学段,年级和科目,同时左侧的教材和知识点的树形结构受到顶部三个字段的影响,随之变动而变动 顶部的联动解决方案是使用 wat ...

最新文章

  1. C/C++包管理工具Conan简介
  2. 【PP操作手册】创建公司间交易采购订单
  3. 系列笔记 | 深度学习连载(4):优化技巧(上)
  4. 【物联网】OpenWrt OpenWRT的源码下载及目录结构
  5. WordPress搬家全攻略
  6. 编写程序判断两个数组是否相等,然后编写一段类似的程序比较两个 vector。
  7. redis 怎么关闭写盘_Redis持久化策略
  8. array_column php什么版本可以用,array_column兼容php5.5以下版本
  9. java hs err pid_JAVA 奔溃 生成hs_err_pid****的文件,求大神看看
  10. python计算密集型任务_Python多进程和多线程测试比高低,只为证明谁是最快的“仔”
  11. 使用遗传算法解决N皇后问题
  12. 分离圆环图显示百分比_excel这个百分比图,你不一定会制作
  13. 使用CentOS光盘镜像作为YUM源安装rpm软件包
  14. java输出阶乘_Java阶乘输出
  15. Python shapefile转GeoJson的两种方式
  16. 软件测评师的一些重点①
  17. index.highlight.max_analyzed_offset 偏移量设置
  18. win10误删的注册表能还原吗_Win10自带注册表修复方法 Win10注册表误删修复步骤...
  19. 【Unity3D】在Unity中实现UI指向箭头
  20. 单片机用c语言编写测量波形频率和占空比,单片机测量方波的频率、占空比及相位差的方法...

热门文章

  1. 秒杀多线程第三篇 原子操作 Interlocked系列函数
  2. pycharm debug 断点调试
  3. Git之删除本地无用分支
  4. Redis内存使用优化与存储
  5. 查找两个字符串a,b中的最长公共子串
  6. WebRTC视频数据流程分析
  7. LiveVideoStackCon讲师热身分享 ( 四 ) —— 基于强化学习的自动码率调节
  8. MySQL索引知识点
  9. 程序员妈妈的“work-life balance”,直面想象中的困难
  10. CentOS6.5下RabbitMQ安装