1 ES6基础
1.1 ECMAScript
ECMAScript是一种由ECMA国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript或JScript,所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。
1.2 ECMAScript2015与ES6
通常讲ES6就是ECMAScript2015 ,但也有泛指ES2015及之后版本。
1.3 let const var
变量声明方式 | 是否变量提升 | 作用域 | 是否可以重复声明 | 是否可变 |
---|---|---|---|---|
let | 无 | 块级作用域 | 不可以 | 可变 |
const | 无 | 块级作用域 | 不可以 | 不可变 |
var | 有 | 函数作用域/全局作用域 | 可以 | 可变 |
let与var在for循环中表现不同
//for循环用var
var a = [];
for (var i = 0; i < 5; i++) {
a[i] = function () {
console.log(i);
};
}
a[1]();//5
a[2]();//5
a[3]();//5
//for循环用let
var b = [];
for (let i = 0; i < 5; i++) {
b[i] = function () {
console.log(i);
};
}
b[1]();//1
b[2]();//2
b[3]();//3
1.4 变量/对象的解构赋值
//变量解构赋值
let a = 1;
let b = 2;
//==>>等价于
let [a,b] = [1,2];
//复制对象
let pserson = {
name:'张三',
age:18
}
let person2 = person
let person3 = {...person}
person2.name = '李四'
console.log(person)
//对象的解构赋值
let {name ,age} = person
console.log(name)
console.log(age)
常用用途
1)变量交换
let x = 1;
let y = 2;
[x, y] = [y, x];
2)提取后台返回的json数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
1.5 模板字符串
let place = 'World';
let msg = `Hello, ${place}`;
1.6 箭头函数
ES6 允许使用“箭头”(=>
)定义函数。
var func = x => x;
// 等同于
var func = function (x) {
return x;
};
如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
箭头函数的this
对于普通函数来说,内部的this
指向函数运行/使用时所在的对象,箭头函数没有自己的this,它的this是继承而来,默认指向在定义它时所处的对象(宿主对象)。
let person = {
name: '张三',
age: 39,
fav: function () {
console.log(this)
console.log(`${this.name}在干啥`);
},
fav2:()=>{
console.log(this)
console.log(`${this.name}在干啥`);
}
}
person.fav();
person.fav2();
1.7 数组操作
for in 和for of 遍历普通数据无差别,遍历对象数组时才会不同
let arr = [1,2,3,4,5,6]
let arr2 = [
{
name:'张三',
age:15
},
{
name:'李四',
age:12
},{
name:'王五',
age:19
},{
name:'赵六',
age:11
}
]
for (let i = 0; i < arr.length; i++) {
console.log(`我是${i}`)
}
for(let i of arr2){
console.log(`我1是${stringify(i)}`)
}
2 Vue.js 基础篇
Vue(读音 /vjuː/,类似于 view),是一套用于构建用户界面的渐进式框架,与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,方便与第三方库或既有项目整合。另一方面,当与**现代化的工具链以及各种支持类库**结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
2.1 作者
尤雨溪
尤雨溪是一位美籍华人,在上海复旦大学附中读完高中后,在美国完成大学学业,本科毕业于 Colgate University,后在 Parsons 设计学院获得 Design & Technology 艺术硕士学位。他是 Vue Technology LLC 创始人,曾经在 Google Creative Lab 就职,参与过多个项目的界面原型研发,后加入 Meteor,参与 Meteor 框架本身的维护和 Meteor Galaxy 平台的交互设计与前端开发。
2014 年 2 月,尤雨溪开源了一个前端开发库 Vue.js。Vue.js 是构建 Web 界面的 JavaScript 库,也是一个通过简洁的 API 提供高效数据绑定和灵活组件的系统。
2016 年 9 月 3 日,在南京的 JSConf 上,尤雨溪正式宣布以技术顾问的身份加盟阿里巴巴 Weex 团队,来做 Vue 和 Weex 的 JavaScript runtime 整合,目标是让大家能用 Vue 的语法跨三端。
2.2 优点
轻量级的框架:
只关注视图层,是一个构建数据的视图集合,大小只有几十kb
双向数据绑定(MVVM模式)
组件化:
实现了html的封装和重用,在构建单页面应用方面有着独特的优势
视图,数据,结构分离
数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作
dom
Document Object Model(文档对象模型),是为HTML和XML提供的API;
按照DOM的标准,HTML和XML都是以标签为结点构造的树结构,DOM将HTML和XML的相同的结构本质抽象出来,然后通过脚本语言,如javascript,按照DOM里的模型标准访问和操作文档内容。
javascript可以通过DOM直接访问和操作网页文档的内容,连接js和html结构的接口就是DOM。
虚拟dom
不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式
虚拟DOM的最终目标是将虚拟节点渲染到视图上。但是如果直接使用虚拟节点覆盖旧节点的话,会有很多不必要的DOM操作。例如,一个ul标签下很多个li标签,其中只有一个li有变化,这种情况下如果使用新的ul去替代旧的ul,因为这些不必要的DOM操作而造成了性能上的浪费。
为了避免不必要的DOM操作,虚拟DOM在虚拟节点映射到视图的过程中,将虚拟节点与上一次渲染视图所使用的旧虚拟节点(oldVnode)做对比,找出真正需要更新的节点来进行DOM操作,从而避免操作其他无需改动的DOM。
其实虚拟DOM在Vue.js主要做了两件事:
- 提供与真实DOM节点所对应的虚拟节点vnode
- 将虚拟节点vnode和旧虚拟节点oldVnode进行对比,然后更新视图
各种指令、过滤器
2.3 MVVM框架
- MVVM(Model-View-ViewModel)是对 MVC(Model-View-Control)和 MVP(Model-View-Presenter)的进一步改进。
『View』:视图层(UI 用户界面)
『ViewModel』:业务逻辑层(一切 js 可视为业务逻辑)
『Model』:数据层(存储数据及对数据的处理如增删改查)
-
MVVM 将数据双向绑定(data-binding)作为核心思想,View 和 Model 之间没有联系,它们通过 ViewModel 这个桥梁进行交互。
-
Model 和 ViewModel 之间的交互是双向的,因此 View 的变化会自动同步到 Model,而 Model 的变化也会立即反映到 View 上显示。
-
当用户操作 View,ViewModel 感知到变化,然后通知 Model 发生相应改变;反之当 Model 发生改变,ViewModel 也能感知到变化,使 View 作出相应更新。
2.4 Vue用法
2.4.1 下载Vuejs
//开发版本:
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
//生产版本:
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
2.4.2 第一个Hello World
<div id="app">
{{ message }}
</div>
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
app.message | app. e l ∣ a p p . el | app. el∣app.data | app. r e f s ∣ a p p . refs |app. refs∣app.options
mustache语法:
{{ number + 1 }}
{{ ok ? ‘YES’ : ‘NO’ }}
{{ message.split(‘’).reverse().join(‘’) }}
# 总结:
1.vue实例(对象)中el属性: 代表Vue的作用范围 日后在Vue的作用范围内都可以使用Vue的语法
2.vue实例(对象)中data属性: 用来给Vue实例绑定一些相关数据, 绑定的数据可以通过{{变量名}}在Vue作用范围内取出
3.在使用{{}}进行获取data中数据时,可以在{{}}中书写表达式,运算符,调用相关方法,以及逻辑运算等
4.el属性中可以书写任意的CSS选择器[jquery选择器],但是在使用Vue开发是推荐使用 id选择器 注意: el属性值不能指定body或html标签
2.4.3 v-text
<div id="app">
<span v-text="text"></span>
</div>
const app = new Vue({
el: '#app',
data: {
text: 'v-text!'
}
})
用来设置当前元素的文本内容,相当于DOM对象的 innerText或textContent
# 总结
1.{{}}(插值表达式)和v-text获取数据的区别在于
a.使用v-text取值会将标签中原有的数据覆盖 使用插值表达式的形式不会覆盖标签原有的数据
b.使用v-text可以避免在网络环境较差的情况下出现插值闪烁
2.4.4 v-html
<div id="app">
<div v-html="htmData"></div>
</div>
const app = new Vue({
el: '#app',
data: {
htmData: "<span style='color:blue'>James</span>"
}
})
用来设置DOM对象的innerHTML
2.4.5 v-bind(语法糖:)
有时候属性也不是写死的,也是需要根据某些变量某些数据动态来决定的。
比如动态绑定a元素的href属性
比如动态绑定img元素的src属性
比如动态绑定一些类、样式
<div id="app">
<span v-bind:class='class1'></span>
</div>
const app = new Vue({
el: '#app',
data: {
class1: 'class-bind'
}
})
Class和Style绑定
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind
处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
对象:
<div v-bind:class="{ active: isActive }"></div>
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
data: {
isActive: true,
hasError: false
}
数组:
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
2.4.6 v-on(语法糖@)
<div id="app">
<button v-on:click="click">{{btnName}}</button>
</div>
const app = new Vue({
el:'#app',
data: {
btnName: '按钮1'
},
methods:{
click:function (){
console.log('按钮1被点击');
}
}
})
# 总结:
事件 事件源:发生事件dom元素 事件: 发生特定的动作 click.... 监听器 发生特定动作之后的事件处理程序 通常是js中函数
1.在vue中绑定事件是通过v-on指令来完成的 v-on:事件名 如 v-on:click
2.在v-on:事件名的赋值语句中是当前事件触发调用的函数名
3.在vue中事件的函数统一定义在Vue实例的methods属性中
4.在vue定义的事件中this指的就是当前的Vue实例,日后可以在事件中通过使用this获取Vue实例中相关数据 调用methods中相关方法
2.4.7 Vue事件函数两种写法
<div id="app">
<span>{{count}}</span>
<input type="button" value="改变count的值" @click="changecount">
</div>
<!--引入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
count:1,
},
methods:{
/*changecount:function(){
this.count++;
}*/
changecount(){
this.count++;
}
}
});
</script>
# 总结:
1.在Vue中事件定义存在两种写法
一种是 函数名:function(){}
一种是 函数名(){} 推荐
2.4.8 Vue事件参数传递
<div id="app">
<span>{{count}}</span>
<input type="button" value="改变count为指定的值" @click="changecount(23,'xiaohei')">
</div>
<!--引入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
count:1,
},
methods:{
//定义changecount
changecount(count,name){
this.count = count;
alert(name);
}
}
});
</script>
// 在使用事件时,可以直接在事件调用处给事件进行参数传递,在事件定义处通过定义对应变量接收传递的参数
2.4.9 v-model
<div id="app">
<div><input type="text" v-model="name"></div>
<!-- <input :value="name" @input="name= $event.target.value"> --><!--语法糖-->
<div>name:{{name}}</div>
</div>
const app = new Vue({
el:'#app',
data: {
name: 'info'
}
})
v-model本质上是一个语法糖。如下代码<input v-model="test">
本质上是<其中@input是对输入事件的一个监听:value="test"是将监听事件中的数据放入到input,下面代码是v-model的一个简单的例子。在这边需要强调一点,v-model不仅可以给input赋值还可以获取input中的数据,而且数据的获取是实时的,因为语法糖中是用@input对输入框进行监听的。
2.4.10 v-if
<div id="app">
<div v-if="exist">Kobe</div>
<div v-else>James</div>
</div>
const app = new Vue({
el:'#app',
data: {
exist: true
}
})
key
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。
2.4.11 v-show
<div id="app">
<div v-show="exist">kobe</div>
<div v-show="!exist">James</div>
</div>
const app = new Vue({
el:'#app',
data: {
exist: true
}
})
# 总结
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
2.4.12 v-for
<div id="app">
<span>{{ user.name }} {{ user.age }}</span>
<br>
<!--
通过v-for遍历对象
-->
<span v-for="(value,key,index) in user">
{{index}} : {{key}} : {{value}}
</span>
<!--
通过v-for遍历数组
-->
<ul>
<li v-for="a,index in arr" >
{{index}} {{a}}
</li>
</ul>
<!--
通过v-for遍历数组中对象
:key 便于vue内部做重用和排序
-->
<ul>
<li v-for="user,index in users" :key="user.id">
{{index+1}} {{ user.name }} === {{ user.age }} ==== {{ user.content }}
</li>
</ul>
</div>
const app = new Vue({
el: "#app",
data: {
user:{name:"小陈",age:23},
arr:["北京校区", "天津校区", "河南校区"],
users:[
{id:"1",name:"xiaochen",age:23,content:"我曾经也是一个单纯的少年!"},
{id:"2",name:"小白",age:23,content:"我曾经是一个邪恶的少年!"},
]
},
methods: {}
});
注意::key
不常用: v-once/v-pre/v-cloak
-
v-pre指令
在模板中跳过vue的编译,直接输出原始值。就是在标签中加入v-pre就不会输出vue中的data值了。
<div v-pre>{{message}}</div>
这时并不会输出我们的message值,而是直接在网页中显示{{message}}
-
v-cloak指令
在vue渲染完指定的整个DOM后才进行显示。它必须和CSS样式一起使用,[v-cloak] { display: none; }
<div v-cloak> {{ message }} </div>
-
v-once指令
在第一次DOM时进行渲染,渲染完成后视为静态内容,跳出以后的渲染过程。<div v-once>第一次绑定的值:{{message}}</div> <div><input type="text" v-model="message"></div>
2.5 生命周期
钩子函数 | 含义 |
---|---|
beforeCreate | Vue实例进行初始化,此时实例的各个组件还没有完全初始化,因此不能访问data、computed、watch、methods的方法和数据,同时,Vue实例的挂载点也没有进行初始化 |
created | Vue实例初始化完成,此时可以访问data、computed、watch、methods的方法和数据,但是依旧没有进行Vue实例的挂载点初始化 |
beforeMount | 将实例绑定到模板并进行渲染,但并不会讲实例挂载到页面上 |
mounted | 讲渲染好的模板绑定到页面上,此时,Vue实例已完全创建好 |
beforeUpdate | 数据变更时执行,在实例数据更改之前执行自定义逻辑或操作 |
updated | 将Vue实例更新完成的数据重新渲染到内存中的虚拟DOM中,再讲虚拟DOM应用到页面上 |
beforeDestroy | Vue实例进入销毁阶段,此时实例上的data、methods、过滤器、指令等仍处于可用的状态,还没有真正执行销毁的过程(解除与页面DOM元素的绑定) |
detroyed | 实例被销毁(解除Vue实例与页面DOM元素的绑定,但该Vue实例的对象、数据仍然可以使用) |
# Vue生命周期总结
- 1.初始化阶段
beforeCreate(){ //1.生命周期中第一个函数,该函数在执行时Vue实例仅仅完成了自身事件的绑定和生命周期函数的初始化工作,Vue实例中还没有 Data el methods相关属性
console.log("beforeCreate: "+this.msg);
},
created(){ //2.生命周期中第二个函数,该函数在执行时Vue实例已经初始化了data属性和methods中相关方法
console.log("created: "+this.msg);
},
beforeMount(){//3.生命周期中第三个函数,该函数在执行时Vue将El中指定作用范围作为模板编译
console.log("beforeMount: "+document.getElementById("sp").innerText);
},
mounted(){//4.生命周期中第四个函数,该函数在执行过程中,已经将数据渲染到界面中并且已经更新页面
console.log("Mounted: "+document.getElementById("sp").innerText);
}
- 2.运行阶段
beforeUpdate(){//5.生命周期中第五个函数,该函数是data中数据发生变化时执行 这个事件执行时仅仅是Vue实例中data数据变化页面显示的依然是原始数据
console.log("beforeUpdate:"+this.msg);
console.log("beforeUpdate:"+document.getElementById("sp").innerText);
},
updated(){ //6.生命周期中第六个函数,该函数执行时data中数据发生变化,页面中数据也发生了变化 页面中数据已经和data中数据一致
console.log("updated:"+this.msg);
console.log("updated:"+document.getElementById("sp").innerText);
},
- 3.销毁阶段
beforeDestory(){//7.生命周期第七个函数,该函数执行时,Vue中所有数据 methods componet 都没销毁
},
destoryed(){ //8.生命周期的第八个函数,该函数执行时,Vue实例彻底销毁
}
2.6 组件化
全局组件
在所有的vue实例中都可以使用,注意:先注册组件,再初始化根实例。
//1.开发全局组件
Vue.component('login',{
template:'<div><h1>用户登录</h1></div>'
});
//2.使用全局组件 在Vue实例范围内
<login></login>
# 注意:
- 1.Vue.component用来开发全局组件 参数1: 组件的名称 参数2: 组件配置{} template:''用来书写组件的html代码 template中必须有且只有一个root元素
- 2.使用时需要在Vue的作用范围内根据组件名使用全局组件
- 3.如果在注册组件过程中使用 驼峰命名组件的方式 在使用组件时 必须将驼峰的所有单词小写加入-线进行使用
局部组件
是在某一个具体的vue实例中定义的,只能在这个vue实例中使用;在Vue实例中使用components对象创建组件,可以创建多个组件;
- 第一种方式
//局部组件登录模板声明
let login ={ //具体局部组件名称
template:`<div><h2>用户登录</h2></div>`
};
const app = new Vue({
el: "#app",
data: {},
methods: {},
components:{ //用来注册局部组件
login //注册局部组件
}
});
//局部组件使用 在Vue实例范围内
<login></login>
- 第二种方式
//1.声明局部组件模板 template 标签 注意:在Vue实例作用范围外声明
<template id="loginTemplate">
<h1>用户登录</h1>
</template>
//2.定义变量用来保存模板配置对象
let login ={ //具体局部组件名称
template:'#loginTemplate' //使用自定义template标签选择器即可
};
//3.注册组件
const app = new Vue({
el: "#app",
data: {},
methods: {},
components:{ //用来注册局部组件
login:login //注册局部组件
}
});
//4.局部组件使用 在Vue实例范围内
<login></login>
2.7 Props的使用
- 作用:props用来给组件传递相应静态数据或者是动态数据的
通过在组件上声明静态数据传递给组件内部
//1.声明组件模板配置对象
let login = {
template:"<div><h1>欢迎:{{ userName }} 年龄:{{ age }}</h1></div>",
props:['userName','age'] //props作用 用来接收使用组件时通过组件标签传递的数据
}
//2.注册组件
const app = new Vue({
el: "#app",
data: {},
methods: {},
components:{
login //组件注册
}
});
//3.通过组件完成数据传递
<login user-name="小陈" age="23"></login>
# 总结:
1.使用组件时可以在组件上定义多个属性以及对应数据
2.在组件内部可以使用props数组生命多个定义在组件上的属性名 日后可以在组件中通过{{ 属性名 }} 方式获取组件中属性值
通过在组件上声明动态数据传递给组件内部
//1.声明组件模板对象
const login = {
template:'<div><h2>欢迎: {{ name }} 年龄:{{ age }}</h2></div>',
props:['name','age']
}
//2.注册局部组件
const app = new Vue({
el: "#app",
data: {
username:"小华",
age:23
},
methods: {},
components:{
login //注册组件
}
});
//3.使用组件
<login :name="username" :age="age"></login> //使用v-bind形式将数据绑定Vue实例中data属性,日后data属性发生变化,组件内部数据跟着变化
prop单向数据流
单向数据流:所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
-
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
-
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。—摘自官网
2.8 组件中定义数据和事件使用
1. 组件中定义属于组件的数据
//组件声明的配置对象
const login = {
template:'<div><h1>{{ msg }} 教育</h1><ul><li v-for="item,index in lists">{{ index }}{{ item }}</li></ul></div>',
data(){ //使用data函数方式定义组件的数据 在templatehtml代码中通过插值表达式直接获取
return {
msg:"hello",
lists:['java','spring','springboot']
}//组件自己内部数据
}
}
2.组件中事件定义
const login={
template:'<div><input type="button" value="点我触发组件中事件" @click="change"></div>',
data(){
return {
name:'小陈'
};
},
methods:{
change(){
alert(this.name)
alert('触发事件');
}
}
}
# 总结
1.组件中定义事件和直接在Vue中定义事件基本一致 直接在组件内部对应的html代码上加入@事件名=函数名方式即可
2.在组件内部使用methods属性用来定义对应的事件函数即可,事件函数中this 指向的是当前组件的实例
2.9 向子组件中传递事件并在子组件中调用该事件
在子组件中调用传递过来的相关事件必须使用 this.$emit('函数名') 方式调用
//1.声明组件
const login = {
template:"<div><h1>百思教育 {{ uname }}</h1> <input type='button' value='点我' @click='change'></div>",
data(){
return {
uname:this.name
}
},
props:['name'],
methods:{
change(){
//调用vue实例中函数
this.$emit('aaa'); //调用组件传递过来的其他函数时需要使用 this.$emit('函数名调用')
}
}
}
//2.注册组件
const app = new Vue({
el: "#app",
data: {
username:"小陈"
},
methods: {
findAll(){ //一个事件函数 将这个函数传递给子组件
alert('Vue 实例中定义函数');
}
},
components:{
login,//组件的注册
}
});
//3.使用组件
<login @find="findAll"></login> //=====> 在组件内部使用 this.$emit('find')
2.10 计算属性
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
const app = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
2.11 监听器
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Goast message: "{{ info }}"</p>
</div>
const app = new Vue({
el: '#example',
data: {
message: 'Hello',
info:'info'
},
watch: {
// 监听
message: function (newValue,oldValue) {
console.log('newValue',newValue)
console.log('oldValue',oldValue)
}
}
})
#深度监听
msg:{
handler (newMsg,oldMsg){
console.log(newMsg)
},
immediate:true,
deep:true
}
2.12 过滤器
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind
表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
你可以在一个组件的选项中定义本地的过滤器:
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
或者在创建 Vue 实例之前全局定义过滤器:
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
new Vue({
// ...
})
当全局过滤器和局部过滤器重名时,会采用局部过滤器。
下面这个例子用到了 capitalize
过滤器:
John
过滤器函数总接收表达式的值 (之前的操作链的结果) 作为第一个参数。在上述例子中,capitalize
过滤器函数将会收到 message
的值作为第一个参数。
过滤器可以串联:
{{ message | filterA | filterB }}
在这个例子中,filterA
被定义为接收单个参数的过滤器函数,表达式 message
的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB
,将 filterA
的结果传递到 filterB
中。
过滤器是 JavaScript 函数,因此可以接收参数:
{{ message | filterA('arg1', arg2) }}
这里,filterA
被定义为接收三个参数的过滤器函数。其中 message
的值作为第一个参数,普通字符串 'arg1'
作为第二个参数,表达式 arg2
的值作为第三个参数。
2.13 事件修饰符
// 表单修饰符
.lazy - 我们输入完所有东西,光标离开才更新视图
.trim - 过滤首尾空格
.number - 自动将用户的输入值转为数值类型,如果你先输入数字,那它就会限制你输入的只能是数字。如果你先输入字符串,那它就相当于没有加.number
// 事件修饰符 (尽管我们可以在方法中轻松实现相关处理,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。)
.stop - 调用 event.stopPropagation(), 阻止事件冒泡(不触发父级事件)。
.prevent - 调用 event.preventDefault(), 阻止默认行为,比如点击链接会进行跳转;填写表单时按回车会自动提交到服务器;点击鼠标右键会呼出浏览器右键菜单。
.capture - 添加事件侦听器时使用 capture 模式。事件触发从包含这个元素的顶层开始往下触发,即内部元素触发的事件先在此处理,然后才交由内部元素进行处理。完整的事件机制是:捕获阶段--目标阶段--冒泡阶段
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.native - 监听组件根元素的原生事件。把一个vue组件转化为一个普通的HTML标签。
.once - 只触发一次回调。
// 鼠标按键修饰符
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
// 键值修饰符
.keyCode - 只当事件是从特定键触发时才触发回调。
.exact - 只需要或者只能按一个系统修饰键来触发。
// 其他修饰符
.sync - 父子组件进行双向数据绑定,会扩展成一个更新父组件绑定值的 v-on 侦听器。
.camel - HTML 特性是不区分大小写的,该修饰符使属性被渲染为驼峰名
2.14 拓展
var let const
# 变量提升
// 不会报错
console.log(a);
var a = 10;
# 作用域
for (var i = 0; i < 6; i++) {
setTimeout(function () {
console.log(i);
}, 1000)
}
//setTimeout是个异步函数,它会在循环结束后再执行,i用var声明,全局作用域,用let声明,在每次循环中,setTimeout里的i都是独立的(局部作用域)
var btns = document.getElementsByTagName("button")
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click',function (){
console.log("第" + i + "个按钮被点击")
})
}
es6
ES6是JavaScript的下一代标准,解决了es5中存在的问题
数组操作
forEach map some every filter find
import export
ES6 入门教程 - ECMAScript 6入门 (ruanyifeng.com)