1. ES6
1.1 简介
ECMAScript 6.0(以下简称 ES6,ECMAScript 是一种由 Ecma 国际(前身为欧洲计算机制造商协会,英文名称是 European Computer Manufacturers Association)通过 ECMA-262标准化的脚本程序设计语言)是JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了,并且从 ECMAScript 6 开始,开始采用年号来做版本。即 ECMAScript 2015,就是 ECMAScript6。 它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 每年一个新版本。
1.2 let声明变量
var:声明的变量可以越域,可以多次声明,有变量的提升功能
let:声明的变量有严格的局部作用域,只能声明一次,不会存在变量提升
<!DOCTYPE html>
<html lang="en">
<body>
<script>
// var 声明变量往往回越域
// let 声明的变量有严格的局部作用域
{
var a=1;
let b=2;
}
console.log(a) //2
// console.log(b) //ReferenceError: b is not defined
//var 可以声明多次
//let 只能声明一次
var m=1;
var m=2;
let n=1;
// let n=2;
console.log("m",m)
console.log("n",n)// Identifier 'n' has already been declared
// var 会变量提升
// let 不存在变量提升
console.log("x",x); // undefined
var x = 10;
console.log("y",y); //ReferenceError: y is not defined
let y = 20;
</script>
</body>
</html>
1.3 const 声明常量(只读变量)
- 声明之后不允许改变
- 一但声明必须初始化,否则会报错
1.4 解构表达式
- 数值解构
let arr = [1,2,3]; //以前我们想获取其中的值,只能通过角标。ES6 可以这样:
const [x,y,z] = arr;// x,y,z 将与 arr 中的每个位置对应来取值
- 对象解构
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css'] }// 解构表达式获取值,将 person 里面每一个属性和左边对应赋值
const { name, age, language } = person;
// 等价于下面
// const name = person.name;
// const age = person.age;
// const language = person.language;
// 可以分别打印
// console.log(name);
// console.log(age);
// console.log(language);
//扩展:如果想要将 name 的值赋值给其他变量,可以如下,nn 是新的变量名
const { name: nn, age, language } = person;
console.log(nn);
console.log(age);
console.log(language);
1.4 字符串的扩展
- 几个新的API
ES6为字符串扩展了几个新的API
- includes():返回布尔值,表示是否找到参数字符串
- startswith():返回布尔值,表示参数字符串是否在原字符串的开头
- endswith():返回布尔值,表示参数字符串是否在原字符串的结尾
- 字符串模板
模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行 字符串,还可以在字符串中加入变量和表达式。
- 多行字符串
let s=`<div>
<span>hello word</span>
</div>`
console.log(s)
- 字符串中插入变量和表达式,变量名写在$ { }中,$ { }中可以放入JavaScript表达式
let name="张三"
let age=18
let mes=`我是${name},今年${age}岁`
console.log(mes)
- 字符串中调用函数
function a(){
return '这是一个函数'
}
let message=`你好,${a()}`
console.log(message)
1.5 函数优化
- 函数参数默认值
//在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
function add(a, b) {
// 判断 b 是否为空,为空就给默认值 1
b = b || 1;
return a + b;
}
// 传一个参数
console.log(add(10));
//现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
function add2(a , b = 1) {
return a + b;
}// 传一个参数
console.log(add2(10));
- 不定参数
不定参数用来表示不确定参数个数,形如,…变量名,由…加上一个具名参数标识符组成。 具名参数只能放在参数列表的最后,并且有且只有一个不定参数
function fun(...values) {
console.log(values.length)
}
fun(1, 2) //2
fun(1, 2, 3, 4) //4
- 箭头函数 ES6 中定义函数的简写方式
- 一个参数时
// var print = function(obj){
// console.log(obj)
// }
//可以简写为
var print = obj=>{
console.log(obj)
}
print(111)
- 多个参数时
// 两个参数的情况:
var sum1=function(a,b){
return a+b;
}
console.log(sum1(1,1,))
// 简写为: //当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
var sum2=(a,b)=> a+b;
//测试调用
console.log(sum2(10, 10));//20
// 代码不止一行,可以用`{}`括起来
var sum3=(a,b)=>{
var c=a+b;
return c+b;
}
//测试调用
console.log(sum3(10, 20));//30
- 实战:箭头函数结合解构表达式
const person={
name:"张三",
age:18,
language:['math','chinese','Jap']
}
var say=(person)=>{
console.log(person.name)
}
say(person)
var sya1=({name})=>{
console.log(name)
}
sya1(person)
1.6 对象优化
- 新增的API
新增的 API ES6 给 Object 拓展了许多新的方法,如:
- keys(obj):获取对象的所有 key 形成的数组
- values(obj):获取对象的所有 value 形成的数组
- entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式:
[[k1,v1],[k2,v2],...]
- assign(dest, …src) :将多个 src 对象的值 拷贝到 dest 中。(第一层为深拷贝,第二层为浅 拷贝) con
const person={
name:"张三",
age:18,
language:['math','chinese','Jap']
}
console.log(Object.keys(person))
console.log(Object.values(person))
console.log(Object.entries(person))
const target={a:1}
const source={b:2}
const source1={c:3}
// Object.assign方法第一个是目标参数,后面参数都是源对象
Object.assign(target,source,source1)
console.log(target)
- 声明对象的简写
const age=18
const name="张三"
const person={
name:name,
age:age
}
console.log(person)
const p={name,age}
console.log(p)
- 对象函数属性简写
let person = { name: "jack",
// 以前:
eat: function (food) {
console.log(this.name + "在吃" + food);
},
// 箭头函数版:这里拿不到 this
eat2: food => console.log(person.name + "在吃" + food),
// 简写版:
eat3(food) { console.log(this.name + "在吃" + food);
}
}
person.eat("苹果");
person.eat2("香蕉");
person.eat3("梨子")
- 对象扩展运算符
展运算符(…) 用于取出参数对象所有可遍历属性然后拷贝到当前对象。
// 1、 拷贝对象(深拷贝)
let person1 = { name: "Amy", age: 15 }
let someone = { ...person1 }
console.log(someone) //{name: "Amy", age: 15}
// 2、 合并对象
let age = { age: 15 }
let name = { name: "Amy" }
let person2 = { ...age, ...name } //如果两个对象的字段名重复, 后面对象字
段值会覆盖前面对象的字段值
console.log(person2) //{age: 15, name: "Amy"}
1.7 map 和 reduce
数组中新增了 map 和 reduce 方法
1.7.1 map
map(): 接收一个函数, 将原数组中的所有元素用这个函数处理后放入新数组返回。
let arr = ['1', '20', '-5', '3'];
console.log(arr)
arr=arr.map((item)=>{
return item*2
})
console.log(arr)
arr = arr.map(s => parseInt(s));
console.log(arr)
1.7.2 reduce
语法:
arr.reduce(callback,[initialValue])
reduce 为数组中的每一个元素依次执行回调函数, 不包括数组中被删除或从未被赋值的元素, 接受四个参数: 初始值(或者上一次回调函数的返回值) , 当前元素值, 当前索引, 调用 reduce 的数组。
callback (执行数组中每个值的函数, 包含四个参数)
- previousValue (上一次调用回调返回的值, 或者是提供的初始值(initialValue) )
- currentValue (数组中当前被处理的元素)
- index (当前元素在数组中的索引)
- array (调用 reduce 的数组)
initialValue (作为第一次调用 callback 的第一个参数。 )
//没有初始值:
let arr=[1,20,-5,3]
console.log(arr.reduce((a,b)=>a+b));//19
console.log(arr.reduce((a,b)=>a*b));//-300//指定初始值:
console.log(arr.reduce((a,b)=>a+b,1));//20
console.log(arr.reduce((a,b)=>a*b,0));//-0
1.9模块化
1.9.1 什么是模块化
模块化就是把代码进行拆分, 方便重复利用。 类似 java 中的导包: 要使用一个包, 必须先导包。 而 JS 中没有包的概念, 换来的是模块。
模块功能主要由两个命令构成: export
和import
。
export
命令用于规定模块的对外接口。import
命令用于导入其他模块提供的功能。
1.9.2 export
比如我定义一个 js 文件:hello.js, 里面有一个对象
const util = {
sum(a,b){
return a + b;
}
}
可以使用 export 将这个对象导出:
const util = {
sum(a,b){return a + b;
}
}
export {util};
当然, 也可以简写为:
export const util = {
sum(a,b){
return a + b;
}
}
export 不仅可以导出对象, 一切 JS 变量都可以导出。 比如: 基本类型变量、 函数、数组对象。
当要导出多个值时, 还可以简写。 比如我有一个文件: user.js:
var name = "jack"
var age = 21
export {name,age}
省略名称
上面的导出代码中, 都明确指定了导出的变量名, 这样其它人在导入使用时就必须准确写出变量名, 否则就会出错。
因此 js 提供了default
关键字, 可以对导出的变量名进行省略
例如:
// 无需声明对象的名字
export default {
sum(a,b){
return a + b;
}
}
这样, 当使用者导入时, 可以任意起名字
1.9.3 import
使用export
命令定义了模块的对外接口以后, 其他 JS 文件就可以通过import
命令加载这个模块。
例如我要使用上面导出的 util:
// 导入 utilimport util from 'hello.js'
// 调用 util 中的属性
util.sum(1,2)
要批量导入前面导出的 name 和 age:
import {name, age} from 'user.js'
console.log(name + " , 今年"+ age +"岁了")
但是上面的代码暂时无法测试, 因为浏览器目前还不支持 ES6 的导入和导出功能。 除非借助于工具, 把 ES6 的语法进行编译降级到 ES5, 比如Babel-cli
工具我们暂时不做测试, 大家了解即可
2.Vue
2.1 MVVM 思想
- M: 即 Model, 模型, 包括数据和一些基本操作
- V: 即 View, 视图, 页面渲染结果
- VM: 即 View-Model, 模型与视图间的双向操作(无需开发人员干涉)
在 MVVM 之前, 开发人员从后端获取需要的数据模型, 然后要通过 DOM 操作 Model 渲染到 View 中。 而后当用户操作视图, 我们还需要通过 DOM 获取 View 中的数据, 然后同步到Model 中。而 MVVM 中的 VM 要做的事情就是把 DOM 操作完全封装起来, 开发人员不用再关心 Model和 View 之间是如何互相影响的: - 只要我们 Model 发生了改变, View 上自然就会表现出来。
- 当用户修改了 View, Model 中的数据也会跟着改变。
把开发人员从繁琐的 DOM 操作中解放出来, 把关注点放在如何操作 Model 上。
2.2 Vue 简介
Vue (读音 /vjuː/, 类似于 view) 是一套用于构建用户界面的渐进式框架。 与其它大型框架不同的是, Vue 被设计为可以自底向上逐层应用。 Vue 的核心库只关注视图层, 不仅易于上手, 还便于与第三方库或既有项目整合。另一方面, 当与现代化的工具链以及各种支持类库
结合使用时, Vue 也完全能够为复杂的单页应用提供驱动。
官网: https://cn.vuejs.org/
参考: https://cn.vuejs.org/v2/guide/
Git 地址: https://github.com/vuejs
尤雨溪, Vue.js 创作者, Vue Technology 创始人, 致力于 Vue 的研究开发。
2.3、 入门案例
2.3.1 安装
官网文档提供了 3 中安装方式:
- 直接 script 引入本地 vue 文件。 需要通过官网下载 vue 文件。
- 通过 script 引入 CDN 代理。 需要联网, 生产环境可以使用这种方式
-
- 通过 npm 安装。 这种方式也是官网推荐的方式, 需要 nodejs 环境。
本课程就采用第三种方式
- 通过 npm 安装。 这种方式也是官网推荐的方式, 需要 nodejs 环境。
2.3.2 、 创建示例项目
1、 新建文件夹 hello-vue, 并使用 vscode 打开
2、 使用 vscode 控制台, npm install -y;
项目会生成 package-lock.json 文件, 类似于 maven 项目的 pom.xml 文件。
3、 使用 npm install vue, 给项目安装 vue; 项目下会多 node_modules 目录, 并且在下面有一个 vue 目录
2.3.3 HelloWorld
在 hello.html 中, 我们编写一段简单的代码。
h2 中要输出一句话: xx 非常帅
。 前面的xx
是要渲染的数据。
<body>
<div id="app"><h2>{{name}}, 非常帅! ! ! </h2>
</div>
2.3.4 、 vue 声明式渲染
<body>
<div id="app">
<h1>{{name}}, 非常帅! ! !{{num}}人为他点赞 </h1>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
name: "张三"
}
});
</script>
</body>
- 首先通过 new Vue()来创建 Vue 实例
- 然后构造函数接收一个对象, 对象中有一些属性:
- el: 是 element 的缩写, 通过 id 选中要渲染的页面元素, 本例中是一个 div
- data: 数据, 数据是一个对象, 里面有很多属性, 都可以渲染到视图中
- name: 这里我们指定了一个 name 属性
页面中的h2
元素中, 我们通过{{name}}的方式, 来渲染刚刚定义的 name 属性。
打开页面查看效果:
2.3.5 双向绑定
对上面的案例进行简单的修改
<body>
<div id="app">
<input type="text" v-model="num">
<h1>{{name}}, 非常帅! ! !{{num}}人为他点赞 </h1>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
name: "张三",
num:0
}
});
</script>
</body>
双向绑定:模型变化视图变化,反正亦然
2.3.6 事件处理
给页面添加一个按钮:
<body>
<div id="app">
<input type="text" v-model="num">
<h1>{{name}}, 非常帅! ! !{{num}}人为他点赞 </h1>
<button v-on:click="num++">点赞</button>
<button @click="f()">取消</button>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
name: "张三",
num:0
},
methods:{
f:function(){
this.num--;
}
}
});
</script>
</body>
简单使用总结:
- 使用 Vue 实例管理 DOM
- DOM 与数据/事件等进行相关绑定
- 我们只需要关注数据, 事件等处理, 无需关心视图如何进行修改
2.4 指令
什么是指令?
- 指令 (Directives) 是带有
v-
前缀的特殊特性。 - 指令特性的预期值是: 单个 JavaScript 表达式。
- 指令的职责是, 当表达式的值改变时, 将其产生的连带影响, 响应式地作用于 DOM。
2.4.1 插值表达式
- 花括号
格式:{{表达式}}
说明:
- 该表达式支持 JS 语法, 可以调用 js 内置函数(必须有返回值)
- 表达式必须有返回结果。 例如 1 + 1, 没有结果的表达式不允许使用, 如: let a = 1 + 1;
- 可以直接获取 Vue 实例中定义的数据或函数
- v-text 和 v-html
可以使用 v-text 和 v-html 指令来替代{{}}
说明:
- v-text: 将数据输出到元素内部, 如果输出的数据有 HTML 代码, 会作为普通文本输出
- v-html: 将数据输出到元素内部, 如果输出的数据有 HTML 代码, 会被渲染
实例
<html>
<div id="app">
<span v-html="hello"></span>
<span v-text="hello"></span>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
hello:"<h1>大家好</h1>"
}
});
</script>
</html>
效果展示
2.4.2 v-bind
html 属性不能使用双大括号形式绑定, 我们使用 v-bind 指令给 HTML 标签属性绑定值;而且在将 v-bind
用于 class
和 style
时, Vue.js 做了专门的增强。
- 绑定 class
<div class="static" v-bind:class="{ active: isActive, 'text-danger':hasError }">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
isActive: true,
hasError: false
}
})
</script>
- 绑定 style
v-bind:style
的对象语法十分直观, 看着非常像 CSS, 但其实是一个 JavaScript 对象。 style属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case, 这种方式记得用单引号括起来) 来命名。
例如: font-size–>fontSize
<div id="app" v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
<script>
let vm = new Vue({
el: "#app",
data: {
activeColor: 'red',
fontSize: 30
}
})
</script>
结果:
<div style="color: red; font-size: 30px;"></div>
3. 绑定其他任意属性
<div id="app" v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }" v-bind:user="userName">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
activeColor: 'red',
fontSize: 30,
userName: 'zhangsan'
}
})
</script>
效果:
<div id="app" user="zhangsan" style="color: red; font-size: 30px;"></div>
4. v-bind 缩写
<div id="app" :style="{ color: activeColor, fontSize: fontSize +'px' }" :user="userName">
<div>
2.4.3 v-model
v-text、 v-html、 v-bind 可以看做是单向绑定, 数据影响了视图渲染, 但是反过来就不行。 接下来学习的 v-model 是双向绑定, 视图(View) 和模型(Model) 之间会互相影响。既然是双向绑定, 一定是在视图中可以修改数据, 这样就限定了视图的元素类型。 目前v-model 的可使用元素有:
- input
- select
- textarea
- checkbox
- radio
- components(Vue 中的自定义组件)
基本上除了最后一项, 其它都是表单的输入项。
示例:
<html>
<div id="app">
请选择语言
<input type="checkbox" v-model="lang" value="java">java<br>
<input type="checkbox" v-model="lang" value="python">python<br>
<input type="checkbox" v-model="lang" value="php">hph<br>
选择的语言<input type="text" v-model="lang" >
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let vm=new Vue({
el:"#app",
data:{
lang:[]
}
})
</script>
</div>
</html>
- 多个
CheckBox
对应一个 model 时, model 的类型是一个数组, 单个 checkbox 值默认是boolean 类型 - radio 对应的值是 input 的 value 值
text
和textarea
默认对应的 model 是字符串select
单选对应字符串, 多选对应也是数组
效果展示
2.4.4 v-on
- 基本用法
v-on 指令用于给页面元素绑定事件。
语法: v-on:事件名=“js 片段或函数名”
示例:
<div id="app">
<!--事件中直接写 js 片段-->
<button v-on:click="num++">点赞</button>
<!--事件指定一个回调函数, 必须是 Vue 实例中定义的函数-->
<button v-on:click="decrement">取消</button>
<h1>有{{num}}个赞</h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
num: 100
},
methods: {decrement() {
this.num--; //要使用 data 中的属性, 必须 this.属性名
}
}
})
</script>
另外, 事件绑定可以简写, 例如v-on:click='add'
可以简写为@click='add'
- 事件修饰符
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。 尽管我们可以在方法中轻松实现这点, 但更好的方式是: 方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。为了解决这个问题, Vue.js 为 v-on
提供了事件修饰符。 修饰符是由点开头的指令后缀表示的。
.stop
: 阻止事件冒泡到父元素.prevent
: 阻止默认事件发生.capture
: 使用事件捕获模式.self
: 只有元素自身触发事件才执行。 (冒泡或捕获的都不执行).once
: 只执行一次
<div id="app">
<!--右击事件, 并阻止默认事件发生-->
<button v-on:contextmenu.prevent="num++">点赞</button> <br />
<!--右击事件, 不阻止默认事件发生-->
<button v-on:contextmenu="decrement($event)">取消</button> <br />
<h1>有{{num}}个赞</h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
num: 100
},
methods: {
decrement(ev) {
// ev.preventDefault();
this.num--;}
}
})
</script>
效果: 右键“点赞” , 不会触发默认的浏览器右击事件; 右键“取消” , 会触发默认的浏览器右击事件)
- 按键修饰符
在监听键盘事件时, 我们经常需要检查常见的键值。 Vue 允许为 v-on
在监听键盘事件时添
加按键修饰符:
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">
记住所有的 keyCode
比较困难, 所以 Vue 为最常用的按键提供了别名:
<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
全部的按键别名:
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
- 组合按钮
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
2.4.5 v-for
遍历数据渲染页面是非常常用的需求, Vue 中通过 v-for 指令来实现。
1、 遍历数组
语法: v-for=“item in items”
- items: 要遍历的数组, 需要在 vue 的 data 中定义好。
- item: 迭代得到的当前正在遍历的元素
案例
<html>
<div id="app">
<ul>
<li v-for="user in users">
{{user.name}}--{{user.age}}
</li>
</ul>
{{meg}}
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let mn=new Vue({
el:"#app",
data:{
users:[
{name:"张三",age:18},
{name:"李四",age:20},
{name:"王五",age:24},
{name:"邓六",age:29}
],
meg:"111"
}
})
</script>
</html>
效果
2. 数组角标
在遍历的过程中, 如果我们需要知道数组角标, 可以指定第二个参数:
语法: v-for=“(item,index) in items”
- items: 要迭代的数组
- item: 迭代得到的数组元素别名
- index: 迭代到的当前元素索引, 从 0 开始
示例
<html>
<div id="app">
<ul>
<li v-for="(user,index) in users">
{{index+1}}--{{user.name}}--{{user.age}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let mn=new Vue({
el:"#app",
data:{
users:[
{name:"张三",age:18},
{name:"李四",age:20},
{name:"王五",age:24},
{name:"邓六",age:29}
],
meg:"111"
}
})
</script>
</html>
效果
- 遍历对象
v-for 除了可以迭代数组, 也可以迭代对象。 语法基本类似
语法:
v-for=“value in object”
v-for=“(value,key) in object”
v-for=“(value,key,index) in object”
- 1 个参数时, 得到的是对象的属性值
- 2 个参数时, 第一个是属性值, 第二个是属性名
- 3 个参数时, 第三个是索引, 从 0 开始
示例:
<div id="app">
<ul>
<li v-for="(value, key, index) in user">
{{index + 1}}. {{key}} - {{value}}
</li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
user: { name: '张三', gender: '男', age: 18 }
}
})
</script>
效果
4. Key
用来标识每一个元素的唯一特征, 这样 Vue 可以使用“就地复用” 策略有效的提高渲染的效率。
<ul>
<li v-for="(item,index) in items" :key=”index”></li>
</ul>
<ul>
<li v-for="item in items" :key=”item.id”></li>
</ul>
最佳实践:如果 items 是数组, 可以使用 index 作为每个元素的唯一标识
如果 items 是对象数组, 可以使用 item.id 作为每个元素的唯一标识
2.4.6 v-if 和 v-show
- 基本用法
- v-if, 顾名思义, 条件判断。 当得到结果为 true 时, 所在的元素才会被渲染。
- v-show, 当得到结果为 true 时, 所在的元素才会被显示。
语法: v-if=“布尔表达式”, v-show=“布尔表达式”,
示例:
<div id="app">
<button v-on:click="show = !show">点我呀</button>
<br>
<h1 v-if="show">
看到我啦? !
</h1>
<h1 v-show="show">
看到我啦? ! show
</h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
show: true
}
})
</script>
2、 与 v-for 结合
当 v-if 和 v-for 出现在一起时, v-for 优先级更高。 也就是说, 会先遍历, 再判断条件。
修改 v-for 中的案例, 添加 v-if
<html>
<div id="app">
<ul>
<li v-for="(user,index) in users" v-if="user.age > 18" :key="user.name">
{{index+1}}--{{user.name}}--{{user.age}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let mn=new Vue({
el:"#app",
data:{
users:[
{name:"张三",age:18},
{name:"李四",age:20},
{name:"王五",age:24},
{name:"邓六",age:29}
],
meg:"111",
peo:{name:"smile",age:24}
}
})
</script>
</html>
效果: 只显示年龄大于18
2.4.7 7、 v-else 和 v-else-if
v-else 元素必须紧跟在带 v-if
或者 v-else-if
的元素的后面, 否则它将不会被识别。
示例:
<div id="app">
<button v-on:click="random=Math.random()">点我呀
</button><span>{{random}}</span>
<h1 v-if="random >= 0.75">
看到我啦? ! v-if >= 0.75
</h1>
<h1 v-else-if="random > 0.5">
看到我啦? ! v-else-if > 0.5
</h1>
<h1 v-else-if="random > 0.25">
看到我啦? ! v-else-if > 0.25
</h1>
<h1 v-else>
看到我啦? ! v-else
</h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
random: 1
}
})
</script>
2.5 计算属性和侦听器
- 计算属性(computed)
某些结果是基于之前数据实时计算出来的, 我们可以利用计算属性。 来完成
示例
<html>
<body>
<div id="app">
<ul>
<li> 苹果的价格{{apple}},数量<input type="number" v-model="myApple"></li>
<li> 香蕉的价格{{banana}},数量<input type="number" v-model="myBanana"></li>
<li>总价{{total}}</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let mn =new Vue({
el:"#app",
data:{
apple:2.5,
banana:3,
myApple:1,
myBanana:1,
},
computed:{
total(){
return this.apple*this.myApple+this.banana*this.myBanana
}
}
})
</script>
</body>
</html>
效果: 只要依赖的属性发生变化, 就会重新计算这个属性
- 侦听(watch)
watch 可以让我们监控一个值的变化。 从而做出相应的反应。
示例:
<html>
<body>
<div id="app">
<ul>
<li> 苹果的价格{{apple}},数量<input type="number" v-model="myApple"></li>
<li> 香蕉的价格{{banana}},数量<input type="number" v-model="myBanana"></li>
<li>总价{{total}}</li>
</ul>
{{message}}
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
let mn =new Vue({
el:"#app",
data:{
apple:2.5,
banana:3,
myApple:1,
myBanana:1,
message:''
},
computed:{
total(){
return this.apple*this.myApple+this.banana*this.myBanana
}
},
watch:{
myApple(oldVal,newVal){
if(newVal>3){
this.message="没有更多库存了"
this.myApple=3
}else{
this.message=""
}
}
}
})
</script>
</body>
</html>
效果
当苹果的数据大于3后提示没有更多库存
- 过滤器(filters)
过滤器不改变真正的data
, 而只是改变渲染的结果, 并返回过滤后的版本。 在很多不同的情况下, 过滤器都是有用的, 比如尽可能保持 API 响应的干净, 并在前端处理数据的格式。
示例: 展示用户列表性别显示男女
<body>
<div id="app">
<table>
<tr v-for="user in userList">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<!-- 使用代码块实现, 有代码侵入 -->
<td>{{user.gender===1? "男":"女"}}</td>
</tr>
</table>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: 'jacky', gender: 1 },
{ id: 2, name: 'peter', gender: 0 }
]
}
});
</script>
- 局部过滤器
注册在当前 vue 实例中, 只有当前实例能用
let app = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: 'jacky', gender: 1 },
{ id: 2, name: 'peter', gender: 0 }
]
},
// filters 定义局部过滤器, 只可以在当前 vue 实例中使用
filters: {
genderFilter(gender) {
return gender === 1 ? '男~' : '女~'
}
}
});
管道符号: 表示使用后面的过滤器处理前面的数据
<td>{{user.gender | genderFilter}}</td>
- 全局过滤器
// 在创建 Vue 实例之前全局定义过滤器:
Vue.filter('capitalize', function (value) {
return value.charAt(0).toUpperCase() + value.slice(1)
})
任何 vue 实例都可以使用:
<td>{{user.name | capitalize}}</td>
过滤器常用来处理文本格式化的操作。 过滤器可以用在两个地方: 双花括号插值和 v-bind表达式
2.6 组件化
在大型应用开发的时候, 页面可以划分成很多部分。 往往不同的页面, 也会有相同的部分。例如可能会有相同的头部导航。
但是如果每个页面都独自开发, 这无疑增加了我们开发的成本。 所以我们会把页面的不同部分拆分成独立的组件, 然后在不同页面就可以共享这些组件, 避免重复开发。
在 vue 里, 所有的 vue 实例都是组件
- 全局组件
我们通过 Vue 的 component 方法来定义一个全局组件
<html>
<body>
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
// 定义全局组件, 两个参数: 1, 组件名称。 2, 组件参数
Vue.component("counter", {
template: '<button v-on:click="count++">你点了我 {{ count }} 次, 我记住了.</button>',
data() {
return {
count: 0
}
}
})
let app = new Vue({
el: "#app"
})
</script>
</body>
</html>
注意:
- 组件其实也是一个 Vue 实例, 因此它在定义时也会接收: data、 methods、 生命周期函数等
- 不同的是组件不会与页面的元素绑定, 否则就无法复用了, 因此没有 el 属性。
- 但是组件渲染需要 html 模板, 所以增加了 template 属性, 值就是 HTML 模板
- 全局组件定义完毕, 任何 vue 实例都可以直接在 HTML 中通过组件名称来使用组件了
- data 必须是一个函数, 不再是一个对象。
效果
2. 组件的复用
定义好的组件, 可以任意复用多次:
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
<counter></counter>
</div>
组件的 data 属性必须是函数
- 局部组件
一旦全局注册, 就意味着即便以后你不再使用这个组件, 它依然会随着 Vue 的加载而加载。因此, 对于一些并不频繁使用的组件, 我们会采用局部注册。我们先在外部定义一个对象, 结构与创建组件时传递的第二个参数一致:
const counter = {
template: '<button v-on:click="count++">你点了我 {{ count }} 次, 我记住了</button>',
data() {
return {
count: 0
}
}
};
然后在 Vue 中使用它:
let app = new Vue({
el: "#app",
components: {
counter: counter // 将定义的对象注册为组件
}
})
- components 就是当前 vue 对象子组件集合。
- 其 key 就是子组件名称
- 其值就是组件对象名
- 效果与刚才的全局注册是类似的, 不同的是, 这个 counter 组件只能在当前的 Vue 实例中使用
简写:
let app = new Vue({
el: "#app",
components: {
counter // 将定义的对象注册为组件
}
})
2.8生命周期钩子函数
2.8.1 生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程 : 创建实例, 装载模板, 渲染模板等等。 Vue 为生命周期中的每个状态都设置了钩子函数(监听函数) 。 每当 Vue 实例处于不同的生命周期时, 对应的函数就会被触发调用。
生命周期: 你不需要立马弄明白所有的东西。
2.8.2 2、 钩子函数
- beforeCreated: 我们在用 Vue 时都要进行实例化, 因此, 该函数就是在 Vue 实例化时调用, 也可以将他理解为初始化函数比较方便一点, 在 Vue1.0 时, 这个函数的名字就是init。
- created: 在创建实例之后进行调用。
- beforeMount: 页面加载完成, 没有渲染。 如: 此时页面还是{{name}}
- mounted: 我们可以将他理解为原生 js 中的 window.οnlοad=function({.,.}),或许大家也在用 jquery, 所以也可以理解为 jquery 中的$(document).ready(function(){….}), 他的功能就是: 在 dom 文档渲染完毕之后将要执行的函数, 该函数在 Vue1.0 版本中名字为
- compiled。 此时页面中的{{name}}已被渲染成张三
- beforeDestroy: 该函数将在销毁实例前进行调用 。
- destroyed: 改函数将在销毁实例时进行调用。
- beforeUpdate: 组件更新之前。
- updated: 组件更新之后。