前言
最近公司在做关于物联网的管理后台,因为v1版本是用php后端渲染的,目前v2版本用前后端分离的方法相当于完全重构了,于是采用了Element-admin + vue的方式作为前端技术栈进行开发,过程中遇到不少坑,有些是因为以前的基础薄弱,有些则是新的知识,所以借此记录一下。
一、Vue中的事件代理
在原生ES5或ES6开发中,由于经常和dom元素打交道,我们可以很轻易地通过浏览器的冒泡和捕获机制完成一些便捷操作如事件代理。
但是在Vue当中,并不鼓励操作Dom,但是$ref
本身又不适合进行这种委托机制的事件绑定,那我们该如何像原生js那样对元素进行事件委托呢?其实Vue也提供了办法,就是在事件中传入$events
参数,如下实例:
假设有如下结构的元素:
<div @click="change($events)">
<span id="a">one</span>
<span id='b'>two</span>
</div>
那么我们的调用逻辑就和原生js一样:
methods:{
change(e){
if(e.target.id === 'a'){e.target.innerHTML = 'c'}
if(e.target.id === 'b'){e.target.innerHTML = 'd'}
}
}
可以看到,Vue给我们提供的特殊变量$event
,其实就是js中addEventListenr()
方法回调函数中的event参数,功能是一样的。
二、自定义组件触发原生事件
什么是原生事件?就是Dom元素中自身支持的如click
、keyup
等事件,一般我们直接绑定在元素上就能生效,但是在vue中,如果你往自己写的组件中绑定如@click
等原生事件,是不会触发的。
那么解决的办法就是,利用native修饰符来触发事件:
<self-item :width="width" :height="height" @click.native="changeSize" />
这其实相当于在组件内部的根元素div上绑定了click
事件,然后通过$emit('click',...args)
这样的钩子方式触发事件。
三、主动触发视图更新
最近在使用Element的table时,遇到一个问题,动态改变table内的数据,但table并不会马上更新。后来经查阅,发现其实是ES5的Object.defineproperty
方法缺陷,Vue在初始化实例时会将属性转为getter
/setter
,所以属性必须在 data 对象上才能让 Vue 转换它,才能让它是响应的。
有以下解决办法:
- 数据改变后,重新定义data中的数据:(比如我的
tableData
经过一连串的逻辑后,它里面的数据是有改变的,但是视图没触发变化)
method:{
reloadData(){
this.tableData = [...this.tableData]
}
}
写一个方法,暴力重新赋值data中的tableData来触发更新,其他数据也是同理,但是不太推荐,毕竟一个数组里面如果只更新了部分数据,那并没有必要整个数组重新赋值,开销太大了。
- 使用
$set
方法:this.$set(this.data,”key”,value’)
这是比较推荐的一种方法,也是官方文档首推的,用上面的实例也就是改为:
method:{
reloadData(){
this.$set(this.tableData,'name',username)
}
}
也就是说,我的tableData里的name属性发生了改变,把username赋值给它,并通知Vue更新视图。