vue心得
不是专业的前端开发,但因为E2E开发和架构设计的需要,必须对前端框架有一些了解。这两年项目前端在用vue,就记录一下vue的使用心得。
vue心得
component
component: vue组件,可在其中完成界面呈现(V)+逻辑处理(M+C)。也可以接收父组件传过来的props,作为公共页面使用。
一般在里引用component即可呈现该组件,像这样:
<template><divid='app'><layout><repair-plan></repair-plan><button>编辑</button><button>保存</button><button>评审</button><button>发布</button></layout></div></template>rest调用
使用axios,我们的项目对axios做了一层封装。
@的含义
有几种含义:
import里的@别名,指向src目录 ;
放在事件名前,表示事件响应方法,比如input组件的@input方法能够获取input输入的值。
绑定
冒号的含义:单向绑定
相当于v-bind,例如:
<buttonclass="table-button":loading='exportLoading'@click="exportExcel">{{t('button.export')}}</button>表示button组件的loading属性动态绑定exportLoading变量,exportLoading变量发生变化,按钮的呈现就会不同,即,数据流向是从model层流向view层 。
v-model:双向绑定
冒号或v-bind是model->view的单向绑定,要双向绑定,用v-model。
双向绑定的原理:其实就是“v-bind+view层绑定事件监听”。
数据绑定原理
核心是Object.defineProperty(),这个函数提供了元编程的能力,类似于python里的setattr和java里的反射。
一个例子如下:
letobj={name:'bibi',sex:'male',age_:18//age_作为age的隐藏字段};console.log(obj.age);Object.defineProperty(obj,'age',{//访问obj.age就会触发get方法get(){console.log('age getter called')returnobj.age_;},//设置obj.age就会触发set方法set(newVal){console.log('age setter called');// 直接设置obj.age会造成死循环,所以我们存在age_隐藏字段里obj.age_=newVal;},enumerable:true,})obj.age=20;console.log(obj.age);打印结果为:
undefined age setter called age getter called 20可见,Object.defineProperty能捕获一个对象的setter和getter事件。当我们修改一个对象的属性时,setter事件触发,就可以在其中做一些事情,比如更新视图。vue的v-bind机制就是这个原理(术语叫数据劫持)。angularJS的数据绑定原理与vue不同,用的是脏数据检测,感兴趣的参考这里。
数据绑定意义重大,它真正体现了数据驱动开发,控制器完全与视图分离,而不必关心视图的展现。
响应式数据
ref和reactive,都用于创建界面关联的响应式数据,功能上两者是等价的,只是访问方式不一样。
ref 得到的是一个引用对象,必须用.value才能访问其值。当对.value赋值时,相当于替换了整个对象。
reactive 常用于对象,比如代表一个对话框的所有字段。不支持替换整个对象。
我们常常看到基本类型用ref包装成一个对象,这是为什么呢?因为非如此,vue无法感知基本类型的变化(基本类型是值类型),也就无法去更新界面了。
你可能有疑问,实际当中,数组类型也常用ref包装。这是因为,如果数组用reactive包装,当你从后台获得一个新数组,想直接覆盖旧数组,reactive就会失效(前面讲的,reactive不支持替换整个对象),用ref就不会有这个问题了。
vue组件的内置方法
data()方法
返回待绑定的数据供v-model或v-bind使用。
created()和mounted()方法
简言之,created在模板渲染成DOM前调用,mounted则在模板渲染成DOM后调用。因此,mounted函数里是可以访问DOM树节点的,而created里则不行。
vue组件的methods属性
使用methods属性来给Vue组件设置自定义方法。
Vue对象
ref
为DOM节点加上ref属性,就可以在vue里直接访问DOM节点了,这样写:
this.$refs.xxxRef.attrxxxRef是DOM的ref属性名。
js语法
delete操作符
从对象中移除一个属性,注意:是从对象里删除掉这个属性,而非把属性值设为null或undefined。
对象展开运算符
{… obj}表示展开对象obj的所有可遍历属性。等价于lua的unpack。
常见问题
$t在某些控件属性里不生效
比如,el-table-column 的 label 属性是一个普通 HTML 属性,需要使用 v-bind 指令(或简写为 :)来绑定表达式,这样 $t 函数才能正确执行:
<el-table :data="recentAlarms" style="width: 100%"> <el-table-column :label="$t('alarm.time')" prop="alarmTime" width="180">不能写成普通属性的字符串插值形式:
<el-table-column label="{{$t('alarm.time')}}" prop="alarmTime" width="180">el-form验证required异常
el-form里的el-form-item有个prop属性,它指向el-form的model对象的某个属性,即,model对象必须包含这个属性,不然,框架会认为el-form-item的值没填,从而不停的报required错误。该异常情形在动态表单里很容易出现。
