vue是中国比较流行的前端框架,对后端开发人员非常友善.下面整理了新项目中用到的部分vue知识.
一.生命周期
beforeCreate //在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。 created //实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见 beforeMount //在挂载开始之前被调用:相关的 render 函数首次被调用。 mounted //el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。 beforeUpdate //数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。 updated //由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作 activated //keep-alive 组件激活时调用。 deactivated //keep-alive 组件停用时调用。 beforeDestroy //实例销毁之前调用。在这一步,实例仍然完全可用。 destroyed //Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
二.指令
{ { }} 文本插值
Message: { { msg }} 支持js表达式: { { number + 1 }} { { ok ? 'YES' : 'NO' }} { { message.split('').reverse().join('') }}
{ { if (ok) { return message } }}
v-bind
1.v-bind 可缩写为冒号:
2.元素带引号是类名,不带引号是data中的值
3.:class 可以和普通的class共存,但是不能有两个:class
1.直接绑定data中的值 形如data
:class="sourceBtn.outPatientBtn" data:{ sourceBtn: { outPatientBtn: 'activeBlue', inPatientBtn: '' } }
2.直接绑定class类名 形如class:true/false 'class':true/false 此情况下可以省略单引号
:class="{classA:true}" :class="{classA:false}" :class="{classA:1==1}" :class="{classA:1==2}" :class="{activeBlue:timeSlice.recordId!=null}" 这里的activeBlue就是class style里有定义对应样式 :class="[{activeYellow:item.timeSliceId==timeSliceId}]"
3.直接绑定class类名 形如 'class'
直接获取: :class="'activeBlue'" 用三元表达式获取: :class="item.appointmentFlag?'activeAllAppointed':''"> 绑定多个::class=" 'classA classB' "
v-model
1.双向数据绑定,适用于text、radio、checkbox、selected等表单中
2.v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值。因为它会选择 Vue 实例数据来作为具体的值。你应该通过 JavaScript 在组件的 data 选项中声明初始值。所以比如单选框组默认选中状态应该用如下形式:
data(){ return{ param:'1' //设置默认值为1,即设置第一个单选框为选中状态 } }
v-html
使用 v-html 指令用于输出 html 代码
v-on
v-for
v-for="(item,index) in list" index即索引,从0开始
v-if v-show
条件判断 v-if 如果为false,不会渲染html v-show 如果为false,页面不会显示,但html仍然存在
三:过滤器Filter
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
{ { message | capitalize }}
格式:
vue同样支持全局过滤器和局部过滤器. 当全局过滤器与局部过滤器同名时,默认使用局部过滤器.
局部过滤器:
{ {count|refresh}} filters:{ refresh:function(obj){ return obj+2; } }
全局过滤器:
Vue.filter('refresh',function (obj) { return obj+3; });
过滤器可以串联:先执行A,再执行B
{ { message | filterA | filterB }}
注:过滤器可以接受参数,过滤器默认的第一个参数是message.如下文,filterA实际接受了三个参数(message,arg1,arg2)
{ { message | filterA('arg1', arg2) }}
四:computed(计算属性) watch(监听事件)
computed:
定义:当其依赖的属性的值发生变化时,计算属性会重新计算,反之,则使用缓存中的属性值。
computed和methods区别:
1.computed带有缓存功能,而methods不是.
2.computed作为属性调用,methods是函数调用,此处methods不可省略括号(). 比如showDetail是属性调用 而showDetail()是函数调用
{ {showA}}
{ {showB()}}
computed:{ showA:function () { return '计算属性'; } }, methods:{ showB:function () { return '函数值'; } } 结果: 计算属性 函数值
ex:当计算属性和函数名名字相同时,调用computed不会正确获取计算属性值.而是输出.
function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}
调用methods正常.
watch:
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
watch主要用于监听vue数据变化.watch可以监控一个值的变换,并调用因为变化需要执行的方法。可以通过watch动态改变关联的状态。
基础用法:
这两种监听只能监听普通值,不能监听数组变化
a. a(newValue, oldValue){} 入参为newValue,oldValue
b. 直接写一个method 当监听值变化时,调用method
data: function () { return { a: 0, b: 0, } }, watch: { a(newValue, oldValue) { console.log(newValue); console.log(oldValue); }, b:'updateB' }, methods:{ updateB:function () { console.log(vm.b); } }
进阶:深度监听
c. 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
1.此时a对象的属性a1发生变化,但没有使用深度监听,不会被监听
2.直接对对象使用深度监听,回调函数返回新对象
3.对对象的具体属性使用深度监听,回调函数返回旧属性和新属性.
data: function () { return { a: { a_1:2, a_2:2 }, c: { c_1:2, c_2:2 } } }, watch: { a(newValue, oldValue) { console.log("newVlue:" + newValue); console.log("oldValue:" + oldValue); }, c: { deep: true, handler: function (newValue) { console.log("newVlue:" + newValue.c_1); } }, 'c.c_1': { deep: true, handler: function (newValue, oldValue) { console.log("newVlue:" + newValue); console.log("oldValue:" + oldValue); } } }
immediate:正常情况下,watch监听事件只会在监听对象发生变化时才会触发.加上immediate属性后,对象初始化绑定值时就会触发一次监听事件.第一次触发,oldValue为undefined.
data: function () { return { d: 5, d2: 6 } }, watch: { d: { immediate: true, handler(newValue, oldValue) { console.log(newValue); console.log(oldValue); } }, d2: { immediate: true, handler: 'method_b2' } }, methods: { method_b2: function (newValue, oldValue) { console.log(newValue); console.log(oldValue); } }
五:component(组件)
template(模板)其实就是占位符.不会渲染成html.主要服务于component.
template存在裸写的情况
ex:这种情况下,不能再添加component,所以原则上不会这么写
var vm=new Vue({ el: '#app', template:`
component(组件)
组件是vue的重要组成部分.最大的作用就是复用代码.很多相同的功能可以写成组件,实现多个html复用.
组件分为全局组件(component),局部组件(components)等
ex:
1.组件命名不可以是html默认标签名,比如div,a等
2.组件命名不能用大写,诸如驼峰之类的,都会引起报错
2.vue组件,只能有一个根节点.
3.全局组件中,可以有自己的data,data必须用function返回对象.而不是data:{a:1}这种形式.
4.全局组件必须写在Vue实例创建之前.
基础写法:
(全局)Vue.component(tagName, options) options可以用var提出.
1.局部组件1
2.局部组件2
3.全局组件
4.外部组件
1.使用script标签引入 2.使用import引入js文件或者vue文件
5.父子组件,父子组件通信
ex:
1.子组件接受父组件的值:prop
2.同样的prop中 不能出现大写字符等,否则解析时会报错找不到组件.
3.子组件写在父组件同一个文件中时,整个vue实例即父组件.
4.可以新建一个.vue文件写子组件,需要使用export default导出.同样的,父组件需要使用import接收子组件.
静态prop(基本没什么用个人感觉):
动态prop:子组件接受vue实例中data的值并渲染模板
父组件往子组件中添加html(详见slot篇)
六:slot(插槽)
在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的特性。
ex:
1.子组件内插糟slot控制摆放位置
2.子组件里负责挖坑,父组件填坑,放什么内容由父组件决定
slot(插槽)顾名思义,即父组件向子组件插入html时候的占位符.子组件内插糟slot控制摆放位置.需要注意的是,如果没使用slot,父组件直接往子组件中写html时,内容不会被渲染.
如下:多云没有使用slot,不会被渲染到页面.
插槽一共就三大类
1.匿名插槽(也叫默认插槽): 没有命名,有且只有一个.匿名插槽有个默认名字default
2.具名插槽: 相对匿名插槽组件slot标签带name命名的
3.作用域插槽: 子组件内数据可以被父页面拿到(解决了数据只能从父页面传递给子组件)
vue2.6之前
1.匿名插槽(只能有一个)
2.具名插槽
3.作用域插槽( slot-scope)
vue2.6之后:新增v-slot
七:Vue 路由
1.路由:
定义的组件会在
name属性:通过name属性,为一个页面中不同的router-view渲染不同的组件.name也可以传递参数.name属性可以省略.
{ {$route.name}}可以获取name的值
{ {$route.name}}
var router = new VueRouter({ routes:[ { path: '/foo',component: Foo }, { path: '/bar', component: Bar }] });
参数传递:
// 字符串
2.动态路由匹配:
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。对于所有 ID 各不相同的用户,都要使用这个组件来渲染。我们可以在路由中传入参数.动态参数路径参数以冒号开头.同样也可以直接使用/a/b来直接拼接.
const User = { template: '
3.嵌套路由
嵌套路由,顾名思义,就是在router中在使用router,注册的方法和上面相差不多,但是,注册子路由是需要在children中进行注册。
var routes = [ { path: '/foo', component: Foo, children:[{path:'foo2',component:Foo2}]}, ];
八:Vue this指向问题
1.vue自带的生命周期函数(created,mounted等)中,this指向vue实例.
2.自定义函数(包括匿名函数)中,this指向最近的单位,在非严格模式下,如果没有直接调用者,this指的是window.
如下图 mounted为自带的生命周期方法,故此地[1]this指向vue实例
[2]处this指向最近的单位,即windows,所以很显然赋值失败.正确的做法应该是在外部先绑定vue实例.即var vm=this;
mounted() { /* 问题:在内部直接操作this失效? */ /* 解析:因为在函数内部使用this时,this会指向window,而非vue实例。所以除了vue组件自身方法外,在别的地方调用this时, 首先需要在最外部,设置一个变量,将其绑定上vue实例。*/ var vm=this;[1] window.οnscrοll=function(){ if(document.documentElement.scrollTop>100) { this.isActive=true;[2] vm.isActive=true; }else{ vm.isActive=false; } } }
3.箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象。
八:Vue操作数组,集合列表
Vue.set
Vue.set( target, key, value ) target:要更改的数据源(可以是对象或者数组) key:要更改的具体数据 value :重新赋的值
两种写法 1.target为数组 则key为位置(position) value就是具体map {"adsa":"ads"} demo:Vue.set(this.items,0,{message:"Change Test",id:'10'}) 2.target为对象 则 key value 组成map demo:Vue.set(vm.outPatientDetectionApplications[0], "flag", true);
vue操作data
1.增加数组元素 push() 2.删除数组元素 arr.splice(arr.indexOf(ele),length):表示先获取这个数组中这个元素的下标,然后从这个下标开始计算,删除长度为length的元素
操作数组(javascript)
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。 pop() 方法用于删除并返回数组的最后一个元素。 shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。 unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。 splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
reference https://www.jianshu.com/p/71b1807b1815 https://www.jianshu.com/p/e6e8c45e7fd6
十:小坑
第一次进入模态框 v-model无法双向数据绑定 错误原因:vue2.3bug,更新为vue2.6后修正
layDate日期控件并不支持v-model双向数据绑定,请使用自带的.done()事件
vue和select2组件的坑 select2 api:https://www.520mwx.com/view/67866 vue绑定原生select组件较为简单 这种情况下,v-model自动绑定选中的值 1.select2 使用v-model绑定数据会出现问题,出现原因的问题很简单.v-model绑定的是