实例vue(3步):
1.创建根实例:
let app =new Vue({})
2.挂载根实例:
let app = new Vue({
el:’#app’
})
3.绑定数据:
let app =new Vue({
el:’#app’,
data: {age:24}
})
vue核心
数据的双向绑定、组件化
$el
表示在vue实例上挂载的DOM对象属性
app.$el ===document.getElementById(“app”)
$data
表示在vue实例上挂载的数据属性
app.$data.apge === app.age //true
基本指令
v-html: 原始html
v-once:单项绑定
v-pre:跳跃编译,显示原始标签
v-bind:属性绑定 ( :)
绑定 class
1 2 3 4 5
| <div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }" ></div>
|
和如下 data:
1 2 3 4
| data: { isActive: true, hasError: false }
|
结果渲染为:
<div class="static active"></div>
绑定 style
<div v-bind:style="styleObject"></div>
1 2 3 4 5 6
| data: { styleObject: { color: 'red', fontSize: '13px' } }
|
v-show 和 v-if
v-show 本质是标签display:none ,元素隐藏, 控制CSS, 只编译一次,后面一直控制css,故性能更好
v-if 是动态的向DOM 树内 添加或删除DOM元素,不停的销毁和创建
v-cloak : 遮罩指令 (防止屏幕闪动,需要配合[v-cloak]{display:none})
v-else / v-else-if / v-if : 加key
v-for : 列表渲染 (加key)
1 2 3 4 5 6 7
| <ul id="example-1"> <li v-for="item in items" :key="item.message"> {{ item.message }} </li> </ul>
|
遍历数组 可以接收三个参数 : element ,index ,self
遍历对象 可以接收三个参数 : value , key, index
1 2 3 4 5
| <div v-for="(value, name, index) in object"> {{ index }}. {{ name }}: {{ value }} </div>
|
控制循环次数的两次方法:
- item of items.slice(0,2)
- 通过 v-if 控制
v-on:事件绑定 ( @ )
v-on 绑定修饰符
- .stop: 阻止事件的传递,即阻止事件向上冒泡 (写在子元素里)
- .prevent: 阻止对象的默认行为
- .capture: 使用事件捕获机制 (写给父元素)
- .self: 自身事件修饰符
- .once: 绑定的事件只能触发一次
- .keyup .keyCode 键值修饰符
v-model
修饰符
- .lazy 取代 input 监听 change 事件
- .number 输入字符串转为有效的数字
- .trim 输入首尾空格过滤
1 2 3 4
| <input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p>
|
在文本区域插值 () 并不会生效,应用 v-model 来代替。
1 2 3 4
| <span>Multiline message is:</span> <p style="white-space: pre-line;">{{ message }}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea>
|
使用v-modle时,如果是中文输入法下,在拼音阶段,不会随时更新,可以用@input
来代替
- 单选框/按钮:组合使用可使v-model相同,即可实现互斥,配合value使用
- 复选框/多选按钮:b-model会绑定到同数组类型的数据,配合value使用
- 下拉列表:想多选就加一个multiple
updated,watch,nextTick
updated
对数据的某一次更新
watch
对某个数据的统一变化
nextTick
对所有数据变化统一的处理
console
- console.log() 日志信息
- console.info() 一般信息
- console.debug() 除错信息 ( 谷歌 ,Opera 不支持)
- console..warn() 警告提示
- console.error() 错误提示
- console.group()和 console.groupEnd() 分组显示
- console.dir() 输出属性和方法
- console.dirxml() 输出节点代码
- console.clear() 清空控制台内容
- console.time() , console.timeEnd() 计时器
- console.count() 计数器
- console.table() 表格化
生命周期钩子
创建阶段
beforeCreate : el 和 data 并未初始化
created : data 已经初始化 ,但 el 并未初始化
挂载阶段
beforeMount : el 和 data 均已初始化 ,用了 虚拟DOM 技术
mounted : 数据被渲染出来
更新阶段
beforeUpdate : 无法访问DOM
updated : 可以访问DOM
销毁阶段
beforeDestroy: 实例销毁前调用,在这一步,实例仍然完全可用
destoryed: 实例销毁后被调用 。 该钩子被调用后, 对应Vue 实例的所有指令都被解绑,所有的事件监听器都被移除,所有的子实例 也都被销毁 。
数据挂载方式
- 实例化时用el 挂载
- $mount
computed
包含 getter 和 setter ,采用 getter 读取 ,用 setter 设置 ,默认 用 getter 读取就可
getter 和 setter 的 this 上下文 自动绑定为 vue 实例 。
数组更新检测
变更方法
- push() 末尾添加
- pop() 末尾删除
- shift() 开头删除
- unshift() 开头添加
- splice() 添加、删除、替换
- sort() 排序
- reverse() 颠倒数组中元素的顺序
替换数组
变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如 filter()、concat() 和 slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:
1 2 3 4
| example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) })
|
显示过滤/排序后的结果
1 2 3 4 5
| <ul v-for="set in sets"> <li v-for="n in even(set)">{{ n }}</li> </ul>
|
1 2 3 4 5 6 7 8 9 10 11
| data: { sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]] }, methods: { even: function (numbers) { return numbers.filter(function (number) { return number % 2 === 0 }) } }
|
遍历对象
for … in
遍历对象键 object.keys()
遍历对象键 object.values()
for … of
数组非变异方法
- 筛选-filter
- 拼接-concat
- 截取-slice
js 限制 - 数组操作
- 直接设置/修改一项内容
vue.set(app.items,0,’p’)
app.items.splice(0,1,’p’)
- 修改长度
app.items.splice(0,0)
app.items.length = 8;
JS限制-对象操作:
vue.set(app.obj,'height','180')
全局组件和局部组件
全局组件
- 注册组件 component 并命名
- 添加 template 内容
- 通过自定义组件名调用组件
全局都可以直接用
在创建实例前注册
局部组件
在当前实例作用域下有效
在component选项内注册
组件当中除了可以用template,还可以用 computed ,methods,data 必须是函数, 且必须将数据return 出去
路由跳转
- this.$router.push()
$once(钩子,函数)
混入 mixin
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
var myMixin = { created: function () { this.hello() }, methods: { hello: function () { console.log('hello from mixin!') } } }
var Component = Vue.extend({ mixins: [myMixin] })
var component = new Component()
|
选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。
比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| var mixin = { data: function () { return { message: 'hello', foo: 'abc' } } }
new Vue({ mixins: [mixin], data: function () { return { message: 'goodbye', bar: 'def' } }, created: function () { console.log(this.$data) } })
|
值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
全局混入
混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用恰当时,这可以用来为自定义选项注入处理逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Vue.mixin({ created: function () { var myOption = this.$options.myOption if (myOption) { console.log(myOption) } } })
new Vue({ myOption: 'hello!' })
|
对象的赋值
(1)在 store 中定义一个对象:
1 2 3 4 5 6 7
| userInfo: { pin: '', nickName: '', avatarUrl: DEFAULT_AVATAR, definePin: '', isbind: true },
|
(2)从接口拿到数据后,给这个对象赋值:
1 2 3 4 5 6 7
| this.userInfo = { ...this.userInfo, pin: res.base.curPin, nickName: res.base.nickname, avatarUrl: res.base.headImageUrl ? res.base.headImageUrl : DEFAULT_AVATAR, definePin: res.definePin }
|
自定义过滤器
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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="vue2.5.16.js"></script> </head> <body> <div id="app"> <!-- 通过 过滤器 msgFormat 对 msg 进行过滤--> <p>{{ msg | msgFormat }}</p> </div> <script> Vue.filter('msgFormat', function (myMsg) { return myMsg.replace(/美/g, '丑') }) var vm = new Vue({ el: '#app', data: { msg: '没有美的女人' }, methods: {} }); </script> </body> </html>
|
时间格式化
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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="vue2.5.16.js"></script> </head> <body> <div id="app"> 2018-05-25T14:06:51.618Z <br /> {{ '2018-05-25T14:06:51.618Z' | dateFormat }} </div> </body> <script> Vue.filter('dateFormat', function (dateStr, pattern = '') { var dt = new Date(dateStr) 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} ~~~~~~~` } }) new Vue({ el: '#app', data: { time: new Date() } }); </script> </html>
|
自定义私有过滤器
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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="vue2.5.16.js"></script> </head> <body> <div id="app"> {{ time }} <br /> {{ time | datefmt }} </div> </body> <script> new Vue({ el: '#app', data: { time: new Date() }, filters: { datefmt: function (input) { var res = ''; var year = input.getFullYear(); var month = input.getMonth() + 1; var day = input.getDate(); res = year + '-' + month + '-' + day; return res; } } }); </script> </html>
|
• padStart:返回新的字符串,表示用参数字符串从头部(左侧)补全原字符串。
• padEnd:返回新的字符串,表示用参数字符串从尾部(右侧)补全原字符串。
以上两个方法接受两个参数,第一个参数是指定生成的字符串的最小长度,第二个参数是用来补全的字符串。如果没有指定第二个参数,默认用空格填充。
1 2 3
| console.log("h".padStart(5,"o")); console.log("h".padEnd(5,"o")); console.log("h".padStart(5));
|
Vue 动画
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 82 83 84 85 86 87 88 89 90 91 92
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <style> li { border: 1px dashed #999; margin: 5px; line-height: 35px; padding-left: 5px; font-size: 12px; width: 100%; } li:hover { background-color: hotpink; transition: all 0.8s ease; } .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); } .v-enter-active, .v-leave-active { transition: all 0.6s ease; } .v-move { transition: all 0.6s ease; } .v-leave-active { position: absolute; } </style> </head> <body> <div id="app"> <div> <label> Id: <input type="text" v-model="id"> </label> <label> Name: <input type="text" v-model="name"> </label> <input type="button" value="添加" @click="add"> </div> <!-- <ul> --> <transition-group appear tag="ul"> <li v-for="(item, i) in list" :key="item.id" @click="del(i)"> {{item.id}} --- {{item.name}} </li> </transition-group> --> </div> <script> var vm = new Vue({ el: '#app', data: { id: '', name: '', list: [ { id: 1, name: '赵高' }, { id: 2, name: '秦桧' }, { id: 3, name: '严嵩' }, { id: 4, name: '魏忠贤' } ] }, methods: { add() { this.list.push({ id: this.id, name: this.name }) this.id = this.name = '' }, del(i) { this.list.splice(i, 1) } } }); </script> </body> </html>
|