Vue2 API
两种API
Option API Vue2 vs Compition API Vue3(也可以用Option API 推荐前者) 两种文件
Option API
data:{} computed:{} methods:{} watch(){}
beforeCreate\Mounted\Update\Destory\ 、created\mounted\updated\desotryed
指令
-
组件
概念 是什么:Web界面的前端框架、响应式编程、组件化、关注视图层、构建用户界面的渐进式框架、自底向上逐层应用 优点:小、高效(虚拟DOM)、双向数据绑定、生态丰富、学习成本低 安装 cdn && npm/yarn vue-cli
1 2 3 4 5 6 // vue-cli vue -V @vue/cli版本 npm install @vue/cli // 安装 vue-cli yarn global add @vue/cli vue create my-project // 创建项目 // webpack vue init webpack my-project
定义 data computed methods watch
data 数据 computed:{ }解决模板过重的问题 把模板中的复杂逻辑进行抽取出来
computed 是计算属性,数据的逻辑运算 可以理解为经过计算的 data的属性 计算属性是基于它们的响应式依赖进行缓存的get(){ return } 和 set(val){ } methods 事件 watch 侦听属性 观察和响应Vue实例上的数据变动 每时每刻监听数据或者动作的变化 一个数据依赖于其他数据,那么把这个数据设计为 computed 的 如果你需要在某个数据变化时做一些事情,使用 watch 来观察这个数据变化 前缀 $
: Vue 实例还暴露了一些有用的实例 property 与方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 {{ msg }} {{ reversed }}var obj = { }Object .freeze (obj) var vm = new Vue ({ el :"#app" , data :{ firstName : "ZSH" , msg :"Message" , newTodoText : '' , visitCount : 0 , hideCompletedTodos : false , todos : ['zs' ,'sz' ,'wo' ], error : null , items :[ { name :'zs' ,age :20 }, { name :'sh' ,age :30 } ] }, watch :{ firstName : function (newval, oldval ) {} }, computed :{ num ( ){ return 1000 }, num :{ get ( ){ return 100 } set (newVale ){ } }, reversed ( ){ return this .msg .reserve () } }, methods :{ alert ( ){}, show ( ){} }, watch :{ }, filters :{}, directives :{}, components :{ login :{ template :'#tpl2' } }, beforeCreate ( ){}, created ( ){}, beforeMount ( ){}, mounted ( ){}, beforeUpdate ( ){}, update ( ){}, beforeDestroy ( ){}, destroyed ( ){}, }) vm.message == data.message vm.message = 100 data.message = 200 vm.$data === data vm.$el === el === document .getElementById ("app" ) vm.$watch("a" , function (newValue, oldValue ) {}
1 2 3 4 5 6 7 8 9 10 11 12 import vue from 'vue' import app from './App' new Vue ({ el :"app" })export default { }
指令 内置指令 v-html/text/module/bind/once/for/if/else-if/else/show/on/pre/clock 双大括号
{{}}
Mustache”语法 (双大括号) 的文本插值{数据绑定} v-html 插入 HTML 需要绑定在某个元素上且能避免编译前闪现问题 不建议在网站上直接动态渲染任意 HTML 片段,很容易导致 XSS 攻击 v-text 插入文本 没有闪烁问题 解决{{ text }} 中闪现的问题 会覆盖元素中原本的内容
插值表达式 {{}}
只会替换自已的这个占位符,不会把整个元素的内容清空 v-model 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <textarea/input v-model="message" placeholder="输入内容" ></textarea> <input type="checkbox" id="jack" value="Jack" v-model="toggle"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="toggle"> <label for="john">John</label> // 当选中时 vm.toggle === 'yes' // 当没有选中时 vm.toggle === 'no' // 单选 picked <input type="radio" id="one" value="One" v-model="picked" v-bind:value="a"> //绑定值 // vm.picked === vm.a <label for="one">One</label> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> // 选项卡 <select v-model="selected" multiple> <option disabled>请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> // v-bind:value绑定 {{ option.text }} </option> </select> options: [ { text: 'One', value: 'A' }, { text: 'Two', value: 'B' }, { text: 'Three', value: 'C' } ]
v-once 标明元素或组件只能渲染一次 文本插值不可改变,执行一次插值 数据改变时 插值的内容不会更新 v-bind 属性绑定 :id="id" :src="xxx" :class=""
绑定 DOM 元素属性 缩写::href="url"
绑定属性值
动态参数的缩写(2.6.0+) :[key]=url
class(类) 和 style(内联样式)绑定 两种方法动态绑定css
class 类:class="[' ',' ']"
:class="{ active: isActive }" + data控制ture或false +style样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 data :{ classObject :{ active :true , 'text-danger' :false } } :class ="['red', 'thin']" :class ="['red', 'thin', isactive?'active':'']" > :class ="['red', 'thin', {'active': isactive}]" :class ="{ red:true, italic:false, active:true, thin:true }" :class ="{ active:isActive,Error:hasError }" .active { color : red; font-size : 20px; }Vue .component ('my-component' ,{ template :'<p class="foo bar"></p>' }) <my-component class ="bar boo" :class ="{ active:isActive }" ></my-component> data{ isActive :true } <p class ="foo bar boo active" ></p>
style 内联样式 对象 { } data中的对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 :style="{color: 'red', 'font-size': '40px'}" data :{ h1StyleObj : { color : 'red' , 'font-size' : '40px' , 'font-weight' : '200' } } :style="h1StyleObj" :style="[h1StyleObj,h1StyleObj2]"
v-on 事件绑定 @
动态参数的缩写 (2.6.0+) @[event]="doSomething"
v-for 列表循环 和v-bind:key key属性
不推荐 同时在同一元素中使用 v-if
和 v-for
。当 v-if
与 v-for
一起使用时,v-for
具有比 v-if
更高的优先级 v-for > v-if v-if
将分别重复运行于每个 v-for
循环中。当你只想为部分 项渲染节点时,这种优先级的机制会十分有用如果你的目的是有条件地跳过循环的执行,那么可以将 v-if
置于外层元素 (或 [`) 上 在组件上使用 v-for 1 2 3 4 5 6 7 8 9 10 11 12 13 <ul v-if ="todos.length" > <li v-for ="todo in todos" > {{ todo }}</li > </ul><p v-else > No todos left!</p > <my-component v-for ="item in items" :key ="item.id" > </my-component > <my-component v-for ="(item, index) in items" v-bind:item ="item" v-bind:index ="index" v-bind:key ="item.id" > </my-component >
key:vue用v-for正在更新已渲染过的元素列表时,默认用就地复用的策略
。如果数据项的顺序被改变,Vue 将不是移动 DOM 元素来匹配数据项的顺序 , 而是简单复用此处每个元素 ,并且确保它在特定索引下显示已被渲染过的每个元素。(DOM 改变顺序,不是修改 DOM,而是重新渲染每一个元素) 这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出 。 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素 ,你需要为每项提供一个唯一 key 属性。
尽可能在使用 v-for
时提供 key
attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。 因为它(key)是 Vue 识别节点的一个通用机制,key
并不仅与 v-for
特别关联
不要使用对象或数组之类的非基本类型值作为 v-for
的 key
。请用字符串或数值类型的值
in 后面我们放过普通数组 对象数组 对象 数字 of 替代 in 作为分隔符,接近 JavaScript 迭代器的语法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 data :{ items :[ {},{},{} ], object : { title : 'How to do lists in Vue' , author : 'Jane Doe' , publishedAt : '2016-04-10' } } <div v-for ="item in items" > {{ item.name }} </div><div v-for ="item of items" > </div > <li v-for ="(item,key,index) in items" :key ="item.id" > {{item}}+{{index}}</li > <p v-for ="i in 10" > {{i}}</p > <li v-for ="(value,name,index) in object" > {{index}} {{value}} {{ name }}</li >
数组更新
push pop shift unshift splice sort reverse filter concat slice 替换数组 v-if and v-show 切换元素的显示和隐藏
v-if / v-else /v-else-if
控制元素的显隐、运行条件不大时、更高的切换消耗、操作 DOM(true/false)的增删来显隐
惰性的、初始渲染时条件为假,则什么都不用做,为真开始局部编译(编译会被缓存起来)
真实的条件渲染
通过操作 DOM(true/false)的增删来显隐、
更高的切换消耗(元素的创建与销毁)
运行条件不大时
切换、更高的切换消耗、运行时条件不大可能改变时用 v-if 每次都会重新删除或创建元素,是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建 惰性的 :如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块
1 2 3 4 5 6 7 8 <h1 v-if ="hidden" >Vue is awesome!</h1><h1 v-else > 这是第二段文字</h1 > data :{ hidden :true } <div v-if ="type === 'A'" >A</div><div v-else-if ="type === 'B'" > B</div > <div v-else-if ="type === 'C'" > C</div > <div v-else > NOT A/B/C</div > <template v-if ="loginType === 'username'" >
v-show 元素始终被编译并保留,只是简单地基于 CSS 切换 通过切换 Css 的 display 的属性(style=”display:none”)来显隐、 更高的初始渲染消耗(display 属性控制元素的显示与消失) 不支持 template 语法 控制元素的显隐、更高的初始渲染消耗 频繁切换、切换 Css 的 display 的属性(style=”display:none”)来显隐 显隐、更高的初始渲染消耗、元素始终会被渲染并保留在 DOM 中、不会重新进行 DOM 的删除和创建操作,简单地切换元素的 CSS property display
、不支持 <template>
元素,也不支持 v-else
、更高的初始渲染消耗、频繁切换 v-show 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换 v-el 、v-ref 废弃 v-ref 通过v-ref
获取到整个组件(component
)的对象
可以通过实例的$refs
属性调用 父组件注册子组件索引方便访问v-ref:some-ref
this.$refs.some-ref
v-cloak 1 解决双大括号闪烁 在元素上添加了一个[v-cloak]的属性,直到关联的实例结束编译 解决 插值表达式闪烁的问题(网速慢,页面会出现插入表达式{{ }} 的问题
v-pre 编译时跳过当前元素和它的子元素。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译,作用显示出{{双大括号}}
1 2 3 4 5 6 7 8 9 10 11 // v-el 、v-ref `vue1.0中的属性 v-el和v-ref在2.0中被废弃了。`<h1 v-cloak > Yout input is{{ message }}</h1 > <div v-el:demo > 这是一段话</div > vm.$els.demo.innerText // 这是一段话<template id ="demo" > <h2 > 组件对象</h2 > </template > <demo v-ref:mycom > </demo > <button @click ="getCom" > 获取组件对象</button > vm.$refs.mycom<h1 v-text ="HH" > </h1 >
自定义指令 全局: Vue.directive('name',{ })
bind/unbind(el, binding, vnode){} inserted/componentUpdated(el, binding, vnode) {} update(el, binding, vnode, oldVnode) 局部 注册v-*
自定义指令,以便封装对 DOM 元素的重复处理行为,提高代码的复用效率 复用 JS 代码,指令方便 将 JS 代码挂载具体的 DOM 元素上 创建、注册自定义指令,以及讲述指令相关属性钩子函数
1 2 3 4 5 6 7 Vue .directive ("Vuedemo" , { bind (el, binding, vnode ) {}, inserted (el, binding, vnode ) {}, update (el, binding, vnode, oldVnode ) {}, componentUpdated (el, binding, vnode ) {}, unbind (el, binding, vnode ) {}, });
自定义全局指令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <input type="text" v-model="searchName" v-focus v-color="'red'" v-font-weight="900" >Vue .directive ('focus' , { inserted : function (el ) { el.focus (); console .log (el); } });Vue .directive (id,definition) <div v-global -directive></div>Vue .directive ("focus" , { inserted : function (el ) { el.fouce ; }, });
自定义局部指令 局部注册 组件的directions选项
注册一个局部的自定义指令,该指令只能在当前组件中通过v-local-direactive
的方式调用
1 2 3 4 5 6 7 8 9 10 11 directives : { color : { bind (el, binding ) { el.style .color = binding.value ; } }, 'font-weight' : function (el, binding2 ) { el.style .fontWeight = binding2.value ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var comp = Vue .extend ({ directives : { localDirective : {}, }, });var vm = new Vue ({ el : "#app" , data : {}, directives : { color : { bind (el ) { el.style .backgroundColor = "red" ; }, }, }, });
钩子函数
事件(function)
钩子函数(hook 函数)[监听函数]
钩子函数和回调函数都是事件处理函数
钩子函数其实和回调是一个概念,当系统执行到某处时,检查是否有 hook,有则回调
钩子函数:js 派函数监听事件 => 监听函数
就是所谓的钩子函数 => 函数钩取事件 (函数自动找事件 => 钩子函数)自动
回调函数:js 预留函数给 dom 事件,dom 事件调用 js 预留的函数 => 事件派发给函数:(事件调用函数=>回调函数) 手动
dom 通过事件通知 js 的过程即是回调,对应的函数就是回调函数
js 通过监听函数得知事件的过程即是钩取,对应的函数就是钩子函数 一个指令定义对象可以提供了五个钩子函数(可选)可以理解成指令的(生命周期的) bind (绑定)==> inserted(插入) ==> update(更新) ==> componentUpdated(组件和子组件 全部更新调用) ==> unbind(解绑)
绑定、插入、更新、VNode更新、解绑
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中) update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前 。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。 componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。 unbind:只调用一次,指令与元素解绑 1 2 3 4 5 6 7 Vue .directive ("demo" , { bind ( ) {}, inserted ( ) {}, update ( ) {}, componentUpdated ( ) {}, unbind ( ) {}, });
钩子函数参数
三个参数:el(DOM 元素)、binding、vnode(vue 虚拟节点) el:指令所绑定的元素,可以用来直接操作 DOM。 binding:一个对象 与动态钩子参数 {name、value、oldValue、expression、arg、modifiers } name 指令名 value 指令的绑定值 binding.value 数字 oldValue 指令绑定的前一个值 expression 字符串形式的指令表达式 binding.expression 字符串 arg 传给指令的参数 binding.arg modifiers 一个包含修饰符的对象 vnode:Vue 编译生成的虚拟节点。 oldVnode:上一个虚拟节点,仅在 update
和 componentUpdated
钩子中可用。 除了 el
之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset
来进行。
value 和 expression 的区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <div id="hook-arguments-example" v-demo :foo.a .b ="message" ></div>Vue .directive ("demo" ,{ bind (el,binding,vnode ){ console .log (el) console .log (binding) console .lg (vnode) var s = JSON .stringify el.innerHTML = 'name: ' + s (binding.name ) + '<br>' + 'value: ' + s (binding.value ) + '<br>' + 'expression: ' + s (binding.expression ) + '<br>' + 'argument: ' + s (binding.arg ) + '<br>' + 'modifiers: ' + s (binding.modifiers ) + '<br>' + 'vnode keys: ' + Object .keys (vnode).join (', ' ) }, inserted ( ){}, update ( ){}, componentUpdated ( ){}, unbind ( ){} }new Vue ({ el : '#hook-arguments-example' , data : { message : 'hello!' } })
1 2 3 4 5 6 7 name: "demo" // message: 'hello!' value: "hello!" expression: "message" argument: "foo" // 参数 modifiers: {"a" :true ,"b" :true } vnode keys: tag, data, children, text, elm, ns, context, fnContext, fnOptions, fnScopeId, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce, asyncFactory, asyncMeta, isAsyncPlaceholde
动态参数
指令的参数可以是动态的。例如,在 v-mydirective:[argument]="value"
中,argument
参数可以根据组件实例数据进行更新!这使得自定义指令可以在应用中被灵活使用。 格式
1 2 3 4 5 6 <h1 v-pin: [arg ]="value" > </h1 > `v-mydirective:[argument]="value"` binding.value = 100 binding.expression = 参数 :[arg] binding.arg = message // 重点 arg 要注册到data中 data:{ arg:'message' } <p v-pin: [direction ]="200" > </p > // v-pin:[参数]
修饰符 v-on:click.xxx="" Or @click.xxx="" @click.事件修饰符="btnHandler"
v-on:事件修饰符是由点开头的指令后缀来表示的、修饰符可以串联
事件修饰符: .stop 阻止冒泡 .prevent 默认事件 .capture 捕获 .self 事件不是从内部元素触发 .once 触发一次 .passive 修饰符尤其能够提升移动端的性能
按钮修饰符:@keyup +.enter .tab .delete .esc .space .up .down .left .right
自定义按键修饰符别名:全局 config.keyCodes
对象 系统修饰符: .ctrl .alt .shift .meta
鼠标按键修饰符:.left .right .middle
v-model:修饰符 .lazy 在鼠标离开输入框时进行同步 .number .trim debounce 延时
v-model.lazy/.number/.trim=”msg” .number 自动将用户的输入值转为数值类型、没有办法输入字符,只能输入数字 .trim 自动过滤用户输入的首尾空白字符 自动在鼠标离开input框时 修饰符 作用 .sync
双向绑定 .once
单次绑定 .camel
将绑定的特性名字转换回驼峰命名
v-model
修饰符 作用 number 用户输入自动转换为 Number 类型 lazy 添加一个 lazy 特性,从而将数据改到 change 事件中发生 debounce 设置一个最小的延时,每次敲击之后延时同步输入框的值域数据
1 <input v-model="msg" number lazy debounce="5000" />
事件修饰符
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
事件修饰符 作用 .stop
阻止单击事件继续传播 阻止冒泡 事件 默认从里到外 阻止外层事件 .prevent
阻止默认事件 a 链接的跳转行为 提交事件不再重载页面 .capture
添加事件监听器时使用事件捕获模式、即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 .self
只当在 event.target 是当前元素自身时触发处理函数 即事件不是从内部元素触发的 只当事件在该元素本身(比如不是子元素)触发时触发回调 阻止了当前元素的冒泡事件 .once
2.1.4 新增、点击事件将只会触发一次 .passive
2.3.0 新增、Vue 还对应 addEventListener
中的 passive
选项 提供了 .passive
修饰符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <a v-on:click.stop ="doThis" > </a > <form v-on:submit.prevent ="onSubmit" > </form > <a v-on:click.stop.prevent ="doThat" > </a > <form v-on:submit.prevent > </form > <div v-on:click.capture ="doThis" > ...</div > <div v-on:click.self ="doThat" > ...</div > <a v-on:click.once ="doThis" > </a > // 不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。<div v-on:scroll.passive ="onScroll" > ...</div > // 这个 .passive 修饰符尤其能够提升移动端的性能。 // 不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。
按钮修饰符
修饰键与常规按键不同,在和 keyup
事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl
的情况下释放其它按键,才能触发 keyup.ctrl
。而单单释放 ctrl
也不会触发事件。如果你想要这样的行为,请为 ctrl
换用 keyCode
:keyup.17
。 常规按键 按键码 @keyup.
.enter
回车键.tab
制表键.delete
(捕获“删除”和“退格”键).esc
逃逸键.space
空格键方向键.up
上.down
下.left
左.right
右 1 2 3 4 5 6 7 <input type ="text" v-on:keyup.enter ="greet" @keyup.up ="up" > greet(){ console.log('msg'); } up(){ console.log('upup') }
自定义按键修饰符别名:全局 config.keyCodes
对象自
1 2 // 可以使用 `v-on:keyup.f1` Vue.config.keyCodes.f1 = 112
系统修饰键
1 2 3 4 <!-- Alt + C --> <input v-on:keyup.alt.67="clear"> <!-- Ctrl + Click --> <div v-on:click.ctrl="doSomething">Do something</div>
鼠标按键修饰符
事件 监听事件
v-on:click=“func” @click="func"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @click="greet('Hi')" v-on :click="warn('Message',$event)" methods :{ greet (event ){ console .log (event.target .tagName ) console .log (message); }, warn (message,event ){ if (event){ event.preventDefault () } } }
过滤器 filters:{} Vue.filter(“name”, function (value) {}) Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化 。 过滤器可以用在两个地方:
mustache 插值 v-bind 表达式 过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示|
1 2 {{ message | capitalize; }} <div v-bind :id="rawId | formatId" ></div>;
当全局过滤器和局部过滤器重名时,会采用局部过滤器
局部过滤器 私有 filters
定义方式:
1 2 3 4 5 6 7 filters :{ capitalize :function (value ){ if (!value) return '' value = value.toString () return value.charAt (0 ).toUpperCase () + value.slice (1 ) } }
1 <td > {{item.ctime | dataFormat('yyyy-mm-dd')}}</td >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 filters : { dataFormat (input, pattern = "" ) { var dt = new Date (input); var y = dt.getFullYear (); var m = (dt.getMonth () + 1 ).toString ().padStart (2 , '0' ); var d = dt.getDate ().toString ().padStart (2 , '0' ); if (pattern.toLowerCase () === 'yyyy-mm-dd' ) { return `${y} -${m} -${d} ` ; } else { var hh = dt.getHours ().toString ().padStart (2 , '0' ); var mm = dt.getMinutes ().toString ().padStart (2 , '0' ); var ss = dt.getSeconds ().toString ().padStart (2 , '0' ); return `${y} -${m} -${d} ${hh} :${mm} :${ss} ` ; } } }
使用 ES6 中的字符串新方法 String.prototype.padStart(maxLength, fillString=’’) 或 String.prototype.padEnd(maxLength, fillString=’’)来填充字符串;
全局过滤器 1 2 3 4 5 Vue .filter ("capitalize" , function (value ) { if (!value) return "" ; value = value.toString (); return value.charAt (0 ).toUpperCase () + value.slice (1 ); });
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Vue .filter ("dataFormat" , function (input, pattern = "" ) { var dt = new Date (input); var y = dt.getFullYear (); var m = (dt.getMonth () + 1 ).toString ().padStart (2 , "0" ); var d = dt.getDate ().toString ().padStart (2 , "0" ); if (pattern.toLowerCase () === "yyyy-mm-dd" ) { return `${y} -${m} -${d} ` ; } else { var hh = dt.getHours ().toString ().padStart (2 , "0" ); var mm = dt.getMinutes ().toString ().padStart (2 , "0" ); var ss = dt.getSeconds ().toString ().padStart (2 , "0" ); return `${y} -${m} -${d} ${hh} :${mm} :${ss} ` ; } });
注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
过滤器传递参数 多个过滤器串联 过滤器可以串联 过滤
1 {{ message | filterA | filterB; }}
message
==> filterA
==> filterB
filterA
被定义为接收单个参数的过滤器函数,表达式 message
的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB
,将 filterA
的结果传递到 filterB
中。
过滤器多个参数 过滤器是 JavaScript 函数
1 2 3 4 {{ message | filterA ("args1" , "args2" ); }}
生命周期 什么是生命周期:从 Vue 实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期
生命周期钩子 :就是生命周期事件的别名 生命周期钩子 = 生命周期函数 = 生命周期事件
创建(create) ==> 挂载(mounted) ==> 更新(updated) ==> 销毁(destroy)
beforeCreate created beforeMount mounted beforeUpdate updated beforeDestory destroyed ==创建期间的生命周期函数==:
beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性(调用报错 )组件刚刚被创建
created:实例已经在内存中创建 OK,此时 data 和 methods 已经创建 OK,此时还没有开始 编译模板 beforeMount:此时已经完成了模板的编译,但是还没有
挂载到页面·中 挂载之前
mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示 挂载之后
==运行期间的生命周期函数==:
beforeUpdate:状态更新之前 执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染 DOM 节点 updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了! ==销毁期间的生命周期函数==:
beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。组件销毁前调用
destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。组件销毁后调用
不要在选项 property 或回调上使用箭头函数 并没有 this
1 2 3 4 5 6 7 8 9 10 11 var vm = new Vue ({ el : "#app" , beforeCreate ( ){}, created ( ){}, beforemount ( ){}, mounted ( ){}, beforeupdate ( ){}, update ( ){}, beforeDestroy ( ){}, destroyed ( ){}, });
动画 && 过渡 使用过渡类名实现动画
.v-enter-active 和 .v-leave-active 设置动画过渡的时间
.v-enter 和 .v-leave-to 设置动画进入和离开
transition 设置过渡的动画元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /* 定义进入和离开时候的过渡状态 */ .v-enter-active, .v-leave-active { transition: all 0.2s ease; position: absolute; } /* 定义进入过渡的开始状态 和 离开过渡的结束状态 */ .v-enter, .v-leave-to { opacity: 0; transform: translateX(100px); }<transition > <div v-show ="isshow" > 动画哦</div > </transition >
通过可以给`transtion标签添加name属性设置自定义v-前缀
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /* 定义进入和离开时候的过渡状态 */ .fade-enter-active, .fade-leave-active { transition: all 0.2s ease; position: absolute; } /* 定义进入过渡的开始状态 和 离开过渡的结束状态 */ .fade-enter, .fade-leave-to { opacity: 0; transform: translateX(100px); } <transition name="fade"> <div v-show="isshow">动画哦</div> </transition>
钩子函数 定义 transition 组件以及三个钩子函数 动画钩子函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" > <div class ="ball" v-show ="flag" > </div > </transition> methods :{ beforeEnter (el ){ el.style .transform ="translate(0,0)" ; }; enter (el,done ){ el.offsetWidth el.style .transform ="translate(150px,450px)" el.style .transition ="all 1s ease" done () }, afterEnter (el ){ this .flag = !this .flag } } }
transition-group
1 2 3 4 5 6 7 8 9 10 11 12 13 14 .v -enter, .v -leave-to { transform : translateY (150px); opacity : 0 ; } .v -enter-active, .v -leave-active { transition : all 1s ease; } <transition-group> <li v-for ="item in list" :key ="item.id" > id:{{item.id}} name:{{item.name}} </li > </transition-group>
trasition-group 中 appear
1 2 3 4 5 6 7 8 9 10 11 // 给trasition-group 添加appear属性,实现页面展示出来时候,入场时候的效果 同岗位transition-group元素,设置tag属性,指定transition-group渲染为指定的元素,如果不指定tag属性,默认,渲染为span 标签 //<ul > <transition-group appear tag ="ul" > <li v-for ="(item,index) in list" :key ="item.id" @click ="del(index)" > id:{{item.id}} name:{{item.name}} </li > </transition-group > //</ul >
列表的排序过渡<transition-group>
组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位 。要使用这个新功能只需了解新增的 v-move
特性,它会在元素的改变定位的过程中应用 。
v-move
和 v-leave-active
结合使用,能够让列表的过渡更加平缓柔和:1 2 3 4 5 6 .v-move{ transition: all 0.8s ease; } .v-leave-active{ position: absolute; }
组件 拆分vue实例代码量 不同组件划分不同的功能模块 模块化: 是从代码逻辑
的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一; 组件化: 是从 UI 界面
的角度进行划分的;前端的组件化,方便 UI 组件的重用; 组件命令方式kebab-case kebab-case (短横线分隔命名) PascalCase PascalCase (首字母大写命名) 注册方式全局注册:· 局部注册:components:{ }
进行局部注册 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <component-name></component-name>Vue .component ('component-name' ,{ data ( ){ return { } } props : ['Message' ], template :'<h1>Hello {{ Message }} Vue2!!!<h1>' })var Message = Vue .extend ({ props : ["content" ], template : "<h1>{{ content }}</h1>" , });Vue .component ("message" , Message );Vue .component ('register' , Vue .extend ({ template : '<h1>注册</h1>' }));<script id ="tmpl" type ="x-template" > <div > <a href ="#" > 登录</a > | <a href ="#" > 注册</a > </div > </script > <template id ="tpl" > <div > <h1 > 这是通过template元素,在定义</h1 > <h4 > 这是一个或</h4 > </div > </template > Vue .component ("account" , { template : "#tpl" , });new Vue ({ data :{}, xxx :{} components :{ son :{ data ( ){ return { } } } } })
1 2 3 4 5 6 7 8 9 10 #appexport default { data ( ){ return {} }, computed ( ){}, watch ( ){}, methods ( ){} }
组件系统
1 2 3 4 5 6 7 8 9 ComponentB.js/.vue import ComponentA from './ComponentA' import ComponentB from './ComponentC' export default{ components:{ ComponentA, ComponentC } }
插槽
动态组件
在不同组件之间进行动态切换:特殊的 is
attribute 来实现
1 2 <component v-bind:is ="currentTabComponent" > </component > // currentTabComponent // 已注册组件的名字,或 一个组件的选项对象
组件通信 父 => 子子 props: [‘finfo’] 父 <son :finfo="msg">
prop 与 data 的区别
data 组件或实例的数据 prop 传递的数据 newVue ==> 子组件 1 2 3 4 5 6 Vue.component('blog-post',{ props:['title'], template:' <h3>{{ title }}</h3> ' }) <blog-post title="My journey with Vue"></blog-post> <blog-post title="Blogging with Vue"></blog-post> <blog-post title="Why Vue is so fun"></blog-post>
子父子sendMsg() { this.$emit('func', 'OK'); }
父<son @func="getMsg"></son>
<input type="button" value="向父组件传值" @click="sendMsg" />
getMsg(val){}
this.$refs
来获取元素和组件1 2 3 4 <h1 ref="myh1"> <my-com ref="mycom"> console.log(this.$refs.myh1.innerText); //元素 console.log(this.$refs.mycom.name); // 组件
复用 && 组合 var myMixin = { } // 选项api Vue.extend({ minxins:[myMixin] }) var component = new Component() 什么是混入(Mixin):提供了一种非常灵活的方式,来分发Vue组件中的可复用功能
。 一个混入对象可以包含任意组件选项。 当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var myMixin = { created :function ( ){ this .hello () } methods :{ hello :function ( ){ console .log ('hello from mixin!' ) } } }var Component = Vue .extend ({ minxins :[myMixin] })var component = new Component ()
防抖和节流
1 2 3 4 5 methods :{ click :_.debounce (function ( ){ xxx },500 ) }
vue-preview
一个 Vue 集成 PhotoSwipe 图片预览插件