vue基础知识整理

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

vue中的点击事件

 

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:`

12341
` })

 

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

var chlid={ template: `
组件b
` }; components:{"data-b":chlid};

 

3.全局组件

var c = { template: `
全局组件c
` }; Vue.component("data-c", c); Vue.component("data-d", { template: `
全局组件
` };);

 

4.外部组件

1.使用script标签引入 2.使用import引入js文件或者vue文件

 

5.父子组件,父子组件通信

ex:

1.子组件接受父组件的值:prop

2.同样的prop中 不能出现大写字符等,否则解析时会报错找不到组件.

3.子组件写在父组件同一个文件中时,整个vue实例即父组件.

4.可以新建一个.vue文件写子组件,需要使用export default导出.同样的,父组件需要使用import接收子组件.

 

静态prop(基本没什么用个人感觉):

Vue.component('date-e',{ props:['static'], template:`

{ {static}}
` });

 

动态prop:子组件接受vue实例中data的值并渲染模板

Vue.component('data-f', { props: ['message'], template: '

{ {message}}
' }); data: function () { return { msg: "Hello World!" } }

 

 

父组件往子组件中添加html(详见slot篇)

 

 

 

 

六:slot(插槽)

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的特性。

 

ex:

1.子组件内插糟slot控制摆放位置

2.子组件里负责挖坑,父组件填坑,放什么内容由父组件决定

 

slot(插槽)顾名思义,即父组件向子组件插入html时候的占位符.子组件内插糟slot控制摆放位置.需要注意的是,如果没使用slot,父组件直接往子组件中写html时,内容不会被渲染.

如下:多云没有使用slot,不会被渲染到页面.

多云 components: { 'data-g': { template: '

今天天气状况

' } }

 

插槽一共就三大类

1.匿名插槽(也叫默认插槽): 没有命名,有且只有一个.匿名插槽有个默认名字default

2.具名插槽: 相对匿名插槽组件slot标签带name命名的

3.作用域插槽: 子组件内数据可以被父页面拿到(解决了数据只能从父页面传递给子组件)

 

 

vue2.6之前

1.匿名插槽(只能有一个)

多云 components: { 'data-g': { template: `

今天天气状况

` } }

 

2.具名插槽

components: { 'data-g': { template: `

今天天气状况

` } }

 

3.作用域插槽( slot-scope)

 

 

vue2.6之后:新增v-slot

 

 

 

 

七:Vue 路由

1.路由:

定义的组件会在 中显示

name属性:通过name属性,为一个页面中不同的router-view渲染不同的组件.name也可以传递参数.name属性可以省略.

{ {$route.name}}可以获取name的值

Go to Foo

{ {$route.name}}

 

var router = new VueRouter({ routes:[ { path: '/foo',component: Foo }, { path: '/bar', component: Bar }] });

 

参数传递:

// 字符串 to apple // 对象 to apple // 命名路由 to apple //直接路由带查询参数query,地址栏变成 /apple?color=red to apple // 命名路由带查询参数query,地址栏变成/apple?color=red to apple

 

 

2.动态路由匹配:

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。对于所有 ID 各不相同的用户,都要使用这个组件来渲染。我们可以在路由中传入参数.动态参数路径参数以冒号开头.同样也可以直接使用/a/b来直接拼接.

const User = { template: '

User
' } const router = new VueRouter({ routes: [ // 动态路径参数 以冒号开头 { path: '/user/:id', component: User } ] })

 

 

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绑定的是