ES6
简介
ECMAScript 6.0 是 JavaScript 语言的下一代标准
ECMAScript 是浏览器脚本语言的规范,而各种我们熟知的 js 语言,如 JavaScript 则是规范的具体实现。
ES6 新特性
let 声明变量
let 声明的变量有严格局部作用域
// var 声明的变量往往会越域
// let 声明的变量有严格局部作用域
{
var a = 1;
let b = 2;
}
console.log(a); // 1
console.log(b); // ReferenceError: b is not defined
var 可以声明多次,let 只能声明一次
var m = 1
var m = 2
let n = 3
//let n = 4 // Identifier 'n' has already been declared
console.log(m) // 2
console.log(n)
var 会变量提升, let 不存在变量提升
console.log(x); // undefined
var x = 10;
console.log(y);//Uncaught ReferenceError: Cannot access 'y' before initialization
let y = 20;
const 声明常量(只读变量)
声明之后不允许改变
一但声明必须初始化,否则会报错
const a = 1;
a = 3; //Uncaught TypeError: Assignment to constant variable.
解构表达式
数组解构
let arr = [1,2,3];
//以前我们想获取其中的值,只能通过角标。
// let a = arr[0];
// let b = arr[1];
// let c = arr[2];
let [a,b,c] = arr; // a,b,c 将与 arr 中的每个位置对应来取值
console.log(a,b,c) //1 2 3
对象解构
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
//对象解构
//扩展:如果想要将 name 的值赋值给其他变量,可以如下,abc 是新的变量名
const { name: abc, age, language } = person;
// 等价于:
// const name = person.name;
// const age = person.age;
// const language = person.language;
console.log(abc, age, language)//jack 21 ['java', 'js', 'css']
字符串扩展
几个新的 API
includes()
:返回布尔值,表示是否找到了参数字符串。startsWith()
:返回布尔值,表示参数字符串是否在原字符串的头部。endsWith()
:返回布尔值,表示参数字符串是否在原字符串的尾部。
let str = "hello.vue";
console.log(str.startsWith("hello"));//true
console.log(str.endsWith(".vue"));//true
console.log(str.includes("e"));//true
console.log(str.includes("hello"));//true
字符串模板
多行字符串
let ss = `<div> <span>hello world<span> </div>`; console.log(ss);
字符串插入变量和表达式。变量名写在
${}
中,${}
中可以放入JavaScript 表达式。字符串中调用函数
const person = { name: "jack", age: 21, language: ['java', 'js', 'css'] } const { name: abc, age, language } = person; function fun() { return "这是一个函数" } let info = `我是${abc},今年${age + 10}了, 我想说: ${fun()}`; console.log(info);
函数优化
函数参数默认值
//在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(20));
如何理解b = b || 1;
这行代码
在JavaScript中,所有的非零数字、非空字符串、非
null
、非undefined
、非false
、非NaN
、非空对象等都是“真值”(truthy value)。如
0
、null
、undefined
、false
、NaN
、空字符串""
或空对象{}
都为“假值”(falsy value)||
短路或,一个数为真值时,就返回第一个,否则就返回第二个console.log((0||null)); // null console.log(("12"||null)); // 12 console.log((""||0)); // 0
所以:
b || 1
的值,要么是b(b不为假值),要么是1
不定参数
function fun(...values) {
console.log(values.length)
}
fun(1, 2) //2
fun(1, 2, 3, 4) //4
不定参数用来表示不确定参数个数,形如,…变量名,由…加上一个具名参数标识符组成。
具名参数只能放在参数列表的最后,并且有且只有一个不定参数
箭头函数
// var print = function (obj) {
// console.log(obj);
// }
var print = obj => console.log(obj);
print("hello");
var sum = function (a, b) {
c = a + b;
return a + c;
}
var sum2 = (a, b) => a + b;
console.log(sum2(11, 12));
var sum3 = (a, b) => {
c = a + b;
return a + c;
}
console.log(sum3(10, 20))
箭头函数结合解构表达式
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
function hello(person) {
console.log("hello," + person.name)
}
//箭头函数+解构
var hello2 = ({name}) => console.log("hello," +name);
// hello2(person); ---> hello2({name}=person);
// 其中:{name}=person 就是取person的name值
hello2(person);
对象优化
新增的 API
keys(obj)
:获取对象的所有 key 形成的数组values(obj)
:获取对象的所有 value 形成的数组entries(obj)
:获取对象的所有 key 和 value 形成的二维数组。格式:[[k1,v1],[k2,v2],...]
assign(dest, ...src)
:将多个 src 对象的值 拷贝到 dest 中。(==第一层为深拷贝,第二层为浅拷贝==)
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
console.log(Object.keys(person));//["name", "age", "language"]
console.log(Object.values(person));//["jack", 21, Array(3)]
console.log(Object.entries(person));//[Array(2), Array(2), Array(2)]
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
//{a:1,b:2,c:3}
Object.assign(target, source1, source2);
console.log(target);//{a:1,b:2,c:3}
target.a=4;
target.b=5;
target.c=6;
console.log(target, source1, source2)
let personDest={};
Object.assign(personDest, person);
console.log(personDest)
person.age=88;
person.language[0]='python';
// 证明第二层是浅拷贝,person.language变了,personDest.language也会变
console.log(personDest) // {name: 'jack', age: 21, language: ['python', 'js', 'css']}
声明对象简写
const age = 23
const name = "张三"
//传统
const person1 = { age: age, name: name }
//ES6:属性名和属性值变量名一样,可以省略
const person2 = { age, name }
console.log(person2);
对象的函数属性简写
箭头函数this不能使用,对象.属性
let person3 = {
name: "jack",
// 以前:
eat: function (food) {
console.log(this.name + "在吃" + food);
},
//箭头函数this不能使用,对象.属性
eat2: food => console.log(person3.name + "在吃" + food),
eat3(food) {
console.log(this.name + "在吃" + food);
}
}
person3.eat("香蕉");
person3.eat2("苹果")
person3.eat3("橘子");
对象拓展运算符
拓展运算符(...
)用于取出参数对象所有可遍历属性然后拷贝到当前对象。
// 1、拷贝对象(深拷贝)
let p1 = { name: "Amy", age: 15 }
let someone = { ...p1 }
console.log(someone) //{name: "Amy", age: 15}
// 2、合并对象
let age1 = { age: 15 }
let name1 = { name: "Amy" }
let p2 = {name:"zhangsan"}
//如果两个对象的字段名重复,后面对象字段值会覆盖前面对象的字段值
p2 = { ...age1, ...name1 } // {age: 15, name: 'Amy'}
console.log(p2)
p3 = {age:88,height:180};
p2 = {...p3}
console.log(p2) // {age: 88, height: 180} 之前的值被覆盖了
p2 = {...name1,...age1,...p3}
console.log(p2) // {name: 'Amy', age: 88, height: 180} // 后面覆盖前面
数组的map 和 reduce方法
map
//map():就是遍历这个数组取执行相关函数
let arr = ['1', '20', '-5', '3'];
/** 之前的方式*/
let arr2 = arr.map((item)=>{
return item*2
});
console.log(arr2) //[2, 40, -10, 6]
console.log(arr) // ['1', '20', '-5', '3']
/** 现在的方式*/
let arr3 = arr.map(item=> item*2);
console.log(arr3);//[2, 40, -10, 6]
console.log(arr);//'1', '20', '-5', '3']
reduce
语法:arr.reduce(callback,[initialValue])
reduce 为数组中的每一个元素依次执行回调函数callback,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。
callback(previousValue, currentValue, index, array)
- 第一个参数:previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
- 第二个参数:currentValue (数组中当前被处理的元素)
- 第三个参数:index (当前元素在数组中的索引)
- 第四个参数:array (调用 reduce 的数组)
initialValue:初始值,也就是第一次调用时的previousValue
let arr4 = ['1', '20', '-5', '3'];
let result = arr4.reduce((a,b,c,d)=>{
let e = a+b;
console.log("previousValue"+a+", currentValue="+b+", index"+c+", array="+d
+", return="+e);
d[c]='a';// 数组会变,而且会带到下一次循环
return e;
},100);
console.log(result)
结果:

Promise
ajax
在 JavaScript 的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致 JavaScript 的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现。
一连串的 ajax 请求会造成层层嵌套,使得上下文代码混乱,不易维护和管理
案例:用户登录,并展示该用户的各科成绩。在页面发送三次请求:
查询用户,查询成功说明可以登录
查询用户成功,查询科目
根据科目的查询结果,获取去成绩
使用json文件模拟数据:
// es6/mock/user.json
{
"id": 1,
"name": "zhangsan",
"password": "123456"
}
//es6/mock/user_corse_1.json
{
"id": 10,
"name": "chinese"
}
//es6/mock/corse_score_10.json
{
"id": 100,
"score": 90
}
以下是使用ajax发请求的代码
$.ajax({
url: "mock/user.json",
success(data) {// 1、查出当前用户信息:成功
console.log("查询用户:", data);
$.ajax({
url: `mock/user_corse_${data.id}.json`,
success(data) {//2、按照当前用户的id查出他的课程:成功
console.log("查询到课程:", data);
$.ajax({
url: `mock/corse_score_${data.id}.json`,
success(data) {//3、按照当前课程id查出分数:成功
console.log("查询到分数:", data);
},
error(error) {//3、按照当前课程id查出分数:失败
console.log("出现异常了:" + error);
}
});
},
error(error) {//2、按照当前用户的id查出他的课程:失败
console.log("出现异常了:" + error);
}
});
},
error(error) { // 1、查出当前用户信息:失败
console.log("出现异常了:" + error);
}
});
promise的语法
const promise = new Promise(function (resolve, reject) {
// 执行异步操作:发送请求
if (/* 异步操作成功 */){
resolve(value);// 调用 resolve,代表 Promise 将返回成功的结果
} else {
reject(error);// 调用 reject,代表 Promise 会返回失败结果
}
});
使用箭头函数可以简写为:
const promise = new Promise((resolve, reject) =>{
// 执行异步操作:发送请求
if (/* 异步操作成功 */) {
resolve(value);// 调用 resolve,代表 Promise 将返回成功的结果
} else {
reject(error);// 调用 reject,代表 Promise 会返回失败结果
}
});
处理异步结果
上面发送完请求(异步操作),根据请求的结果调用then
或者catch
方法
promise.then(function (value) {
// 异步执行成功后的回调
}).catch(function (error) {
// 异步执行失败后的回调
})
Promise 改造以前嵌套方式
function get(url, data) {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
data: data,
success: function (data) {
resolve(data); // 处理成功信息
},
error: function (err) {
reject(err) // 处理失败信息
}
})
});
}
// 注意:.then()里面是一个函数,而不是参数
get("mock/user.json")
.then((data) => {
console.log("用户查询成功~~~:", data)
return get(`mock/user_corse_${data.id}.json`);
})
.then((data) => {
console.log("课程查询成功~~~:", data)
return get(`mock/corse_score_${data.id}.json`);
})
.then((data)=>{
console.log("课程成绩查询成功~~~:", data)
})
.catch((err)=>{
console.log("出现异常",err)
});
模块化
什么是模块化
模块化就是把代码进行拆分,方便重复利用。类似 java 中的导包:要使用一个包,必须先导包。而 JS 中没有包的概念,换来的是 模块
export
命令用于规定模块的对外接口。
import
命令用于导入其他模块提供的功能。
export
方式一:
const util = {// 对象 sum(a,b){ return a + b; } } export {util};
方式二:
export const util = { sum(a,b){ return a + b; } }
方式三:没有变量名
default
,由于没有变量名,引入的时候可以随便取名字// 无需声明对象的名字 export default { sum(a,b){ return a + b; } }
export
不仅可以导出对象,一切 JS 变量都可以导出。比如:基本类型变量、函数、数组、对象。var name = "jack" var age = 21 export {name,age}
import
方式一:
// from + 文件的相对路径 import util from 'hello.js' // 调用 util 中的属性 util.sum(1,2)
方式二:批量导入
import {name, age} from 'user.js' console.log(name + " ,
Vue
安装
直接 script 引入本地 vue 文件。需要通过官网下载 vue 文件。
通过 script 引入 CDN 代理。需要联网,生产环境可以使用这种方式
通过 npm 安装。这种方式也是官网推荐的方式,需要 nodejs 环境。
# 指定和课件同样的版本 @2.6.10 xieshaolin@xieshaolindeMacBook-Pro vue3 % cnpm install vue@2.6.10 ✔ Installed 1 packages ✔ Linked 1 latest versions ✔ Run 0 scripts deprecate vue@2.6.10 Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details. ✔ All packages installed (1 packages installed from npm registry, used 2s(network 2s), speed 604.25KB/s, json 1(136.27KB), tarball 824.49KB, manifests cache hit 0, etag hit 0 / miss 1)
安装好后会出现如下文件:
安装好后需要引入:
<script src="./node_modules/vue/dist/vue.js"></script>
入门案例
vue声明式渲染
<body> <div id="app"> <!-- 页面中的`h2`元素中,我们通过{{name}}的方式,来渲染刚刚定义的 name 属性。 --> <h2> {{name}} ,非常帅</h2> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> //1、vue声明式渲染:首先通过 new Vue()来创建 Vue实例,然后构造函数接收一个对象,对象中有一些属性: let vm = new Vue({ el: "#app",//el:是 element 的缩写,通过 id 选中要渲染的页面元素,本例中是一个 div data: { //data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中 name: "张三",//name:这里我们指定了一个 name 属性 }, }); </script> </body>
还可以再控制台修改name的属性
[!CAUTION]
在VScode格式化代码:单机右键 —> 格式化代码
双向绑定:v-model
<body>
<div id="app">
<input type="text" v-model="num" />
<h2>{{name}},非常帅!!!有{{num}}个人为他点赞。</h2>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 创建 vue 实例
let app = new Vue({
el: "#app", // el 即 element,该 vue 实例要渲染的页面元素
data: {
// 渲染页面需要的数据
name: "张三",
num: 5,
},
});
</script>
</body>
输入框变了,下面的也会变。

事件处理:v-on
<body>
<div id="app">
<input type="text" v-model="num" />
<button v-on:click="num++">关注</button>
<h4>{{name}},非常帅!!!有{{num}}个人为他点赞。</h4>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 创建 vue 实例
let app = new Vue({
el: "#app", // el 即 element,该 vue 实例要渲染的页面元素
data: {
// 渲染页面需要的数据
name: "张三",
num: 5,
},
});
</script>
每次点击关注按钮,就会执行num++
的命令

这里用v-on
指令绑定点击事件,而不是普通的onclick
,然后直接操作 num。普通 click 是无法直接操作 num 的
概念
vue实例
//每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:
let app = new Vue({
//在构造函数中传入一个对象,并且在对象中声明各种 Vue 需要的数据和方法,包括:
//- el - data - methods
});
模版或元素
<!-- 每个 Vue 实例都需要关联一段 Html 模板,Vue 会基于此模板进行视图渲染。 -->
<div id="app">
</div>
let vm = new Vue({
el: "#app" // 创建 Vue 实例,关联这个 div
})
数据
<div id="app">
<input type="text" v-model="name" />
</div>
let vm = new Vue({
el: "#app",
/**
当 Vue 实例被创建时,它会尝试获取在 data 中定义的所有属性,用于视图的渲染,并且监
视 data 中的属性变化,当 data 发生改变,所有相关的视图都将重新渲染,这就是"响应式"
系统。
*/
data: {
name: "刘德华"
}
// 在这个例子中:name 的变化会影响到`input`的值,
// 而 input 中输入的值,也会导致 vm 中的 name 发生改变
})
方法
<div id="app">
{{num}}
<button v-on:click="add">加</button>
</div>
let vm = new Vue({
el: "#app",
data: {
num: 0
},
methods: {
add: function () {
// this 代表的当前 vue 实例
this.num++;
}
}
})
指令
插值表达式
花括号
格式:{{表达式}}
- 该表达式支持 JS 语法,可以调用 js 内置函数(必须有返回值)
- 表达式必须有返回结果,例如 1 + 1。没有结果的表达式不允许使用,如:let a = 1 + 1;
使用{{}}
方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的{{}}
,加载完毕后才显示正确数据,我们称为插值闪烁。
v-text和v-html
v-text
:将数据输出到元素内部,如果输出的数据有 HTML 代码,会作为普通文本输出
v-html
:将数据输出到元素内部,如果输出的数据有 HTML 代码,会被渲染
这两种方法不会出现插值闪烁,当没有数据时,会显示空白或者默认数据。
<body>
<div id="app">
v-text:<span v-text="hello"></span> <br />
v-html:<span v-html="hello"></span>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
hello: "<h1>大家好</h1>",
},
});
</script>
</body>
v-bind:单向绑定
<!-- 给html标签的属性绑定 -->
<div id="app">
<a v-bind:href="link">gogogo</a>
<!-- class,style {class名:加上?}-->
<span
v-bind:class="{active:isActive,'text-danger':hasError}"
:`v-bind:class="{}"`="{color: color1,fontSize: size}"
>你好</span
>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
link: "http://www.baidu.com",
isActive: true,
hasError: true,
color1: "red",
size: "36px",
},
});
</script>
绑定class属性:v-bind:class="{}"
绑定style属性:v-bind:style="{}"
绑定其他属性如href:v-bind:href=""
v-bind的缩写:v-bind:class=:class
;v-bind:style=:style
;v-bind:href=:href
v-bind只是单向绑定:
- 以下是运行的结果

当我们把color1变成blue的时候,视图也变了
可数当我们修改视图的参数时
数据并没有变化
关于class,当hasError=false的时候,text-danger这个class就会失效


v-text和v-html也是单向绑定
v-model:双向绑定
v-model 的可使用元素有:input
;select
;textarea
;checkbox
;radio
;components
(Vue 中的自定义组件)
<body>
<div id="app">
<!-- 多个`CheckBox`对应一个 model 时,model 的类型是一个数组 -->
<input type="checkbox" v-model="language" value="Java" />Java<br />
<input type="checkbox" v-model="language" value="PHP" />PHP<br />
<input type="checkbox" v-model="language" value="Swift" />Swift<br />
<h1>你选择了:{{language.join(',')}}</h1>
<br />
<!-- 单个 checkbox 值默认是 boolean 类型 -->
<input type="checkbox" v-model="boolV" value="boolV" />boolV<br />
<a>boolV : {{boolV}}</a><br />
<br />
<!-- input 对应的值是 input 的 value 值 -->
<input type="input" v-model="inputValue" /><br />
<a>inputValue:{{inputValue}}</a><br />
<br />
<!-- radio 对应的值是 input 的 value 值 -->
<input
type="radio"
v-model="radioValue"
value="radioxxxx"
/>radioxxxx11<br />
<input
type="radio"
v-model="radioValue"
value="radioyyyy"
/>radioyyyy11<br />
<input
type="radio"
v-model="radioValue"
value="radiozzzz"
/>radiozzzz11<br />
<a>radioValue:{{radioValue}}</a><br />
<!-- `text` 和`textarea` 默认对应的 model 是字符串 -->
<input type="text" v-model="textV" />textV<br />
<a>textV :{{textV}}</a><br />
<input type="textarea" v-model="textareaV" />radioyyyy11<br />
<a>textareaV :{{textareaV}}</a><br />
<br />
<!-- `select`单选对应字符串,多选对应也是数组 -->
单选:<br />
<select v-model="selectV1">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option></select
><br />
<a>selectV1 :{{selectV1}}</a><br />
<br />
多选: <br />
<br />
<select v-model="selectV2" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option></select
><br />
<a>selectV2 :{{selectV2.join(',')}}</a><br />
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
language: [],
inputValue: "",
radioValue: "",
boolV: "",
textV: "",
textareaV: "",
selectV1: "",
selectV2: [],
},
});
</script>
</body>

[!NOTE]
multiple
属性是一个布尔属性。当存在时,它规定可以一次选择多个选项。选择多个选项在不同的操作系统和浏览器中有所不同:
- 对于 Windows:按住 ctrl 键选择多个选项
- 对于 Mac:按住 command 键选择多个选项
v-on
基本用法
v-on 指令用于给页面元素绑定事件。
语法:v-on:事件名="js 片段或函数名"
<body>
<div id="app">
<!--事件中直接写 js 片段-->
<button v-on:click="num++">点赞</button>
<!--事件指定一个回调函数,必须是 Vue 实例中定义的函数-->
<!--事件绑定可以简写:-on:click="decrement" = @click="decrement" -->
<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>
</body>

事件修饰符
修饰符是由点开头的指令后缀来表示的:
.stop
:阻止事件冒泡到父元素什么是事件冒泡:
<body> <div id="app"> <div style="border: 1px solid red; padding: 20px" v-on:click="hello"> 大div <div style="border: 1px solid blue; padding: 20px" @click="hello"> 小div <br /> <a href="http://www.baidu.com">去百度</a> </div> </div> </div> <script> new Vue({ el: "#app", data: {}, methods: { hello() { alert("点击了"); }, }, }); </script> </body>
如果点击小div,就等于是点击了大div,这样hello方法就会执行两次。
加上
.stop
就可以解决:@click.stop="hello"
<div style="border: 1px solid blue; padding: 20px" @click.stop="hello"> 小div <br /> <a href="http://www.baidu.com">去百度</a> </div>
.prevent
:阻止默认事件发生
在上面代码中,点击连接会跳转到百度页面,如果我们不想跳转,就可以用它:
<a href="http://www.baidu.com" @click.prevent>去百度</a>
如果还想在阻止默认行为之后,在作一些其他事情,这个时候可以绑定一个方法:@click.prevent="hello2"
<body>
<div id="app">
<div style="border: 1px solid red; padding: 20px" v-on:click="hello">
大div
<div style="border: 1px solid blue; padding: 20px" @click.stop="hello">
小div <br />
<a href="http://www.baidu.com" @click.prevent="hello2">去百度</a>
</div>
</div>
</div>
<script>
new Vue({
el: "#app",
data: {},
methods: {
hello() {
alert("点击了");
},
hello2() {
alert("~~~~~~");
},
},
});
</script>
</body>
可以如果我们点击连接,其实会执行hello和hello2方法,出现了事件冒泡。可以再次用.stop
解决:@click.prevent.stop="hello2"
<a href="http://www.baidu.com" @click.prevent.stop="hello2">去百度</a>
.capture
:使用事件捕获模式.self
:只有元素自身触发事件才执行。(冒泡或捕获的都不执行).once
:只执行一次
<div style="border: 1px solid red; padding: 20px" v-on:click.once="hello">
大div
<div style="border: 1px solid blue; padding: 20px" @click.stop="hello">
小div <br />
<a href="http://www.baidu.com" @click.prevent.stop="hello2">去百度</a>
</div>
</div>
v-on:click.once="hello"
这样第二次点击大div的时候,就不会再执行hello方法
按键修饰符
<body>
<div id="app">
<!-- 按键修饰符: -->
<input
type="text"
v-model="num"
v-on:keyup.up="num+=2"
@keyup.down="num-=2"
@click.meta="num=10"
/><br />
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
num: 0,
},
});
</script>
</body>
v-on:keyup.up="num+=2"
:表示一次上键,num加2
@keyup.down="num-=2"
:是v-on:keyup.down="num-=2"
的缩写,表示按一次下键,num减2
@click.meta="num=10"
:这是一个组合按钮。需要按住meta(windows中为window键,mac中为command键),然后点击,就会使num等于10
实际上的语法是:<input v-on:keyup.13="submit">
,这里的13是keyCode
。但是记住所有的 keyCode
比较困难,所以 Vue 为最常用的按键提供了别名:
别名 | 按键 |
---|---|
.delete | delete(删除)/BackSpace(退格) |
.tab | Tab |
.enter | Enter(回车) |
.esc | Esc(退出) |
.space | Space(空格键) |
.left | Left(左箭头) |
.up | Up(上箭头) |
.right | Right(右箭头) |
.down | Down(下箭头) |
.ctrl | Ctrl(和mac没有找到对应) |
.alt | Alt (对应mac的option) |
.shift | Shift |
.meta | windows中为window键,mac中为command键 |
v-for
遍历数组
<div id="app">
<ul>
<li v-for="user in users">
{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
users: [
{ name: "柳岩", gender: "女", age: 21 },
{ name: "张三", gender: "男", age: 18 },
{ name: "范冰冰", gender: "女", age: 24 },
{ name: "刘亦菲", gender: "女", age: 18 },
{ name: "古力娜扎", gender: "女", age: 25 },
],
},
});
</script>

语法:v-for=”item in items”
- items:要遍历的数组,需要在 vue 的 data 中定义好。
- item:迭代得到的当前正在遍历的元素
数组角标
<div id="app">
<ul>
<li v-for="(user, index) in users">
{{index + 1}}. {{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>

语法:v-for=”(item,index) in items”
- items:要迭代的数组
- item:迭代得到的数组元素别名
- index:迭代到的当前元素索引,从 0 开始。
遍历对象
<div id="app">
<ul>
<li v-for="(value, key, index) in user">
{{index + 1}}. {{key}} - {{value}}
</li>
</ul>
</div>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
user: { name: "张三", gender: "男", age: 18 },
},
});
</script>

语法:v-for=”value in object” && v-for=”(value,key) in object” &&v-for=”(value,key,index) in object”
- 1 个参数时,得到的是对象的属性值
- 2 个参数时,第一个是属性值,第二个是属性名
- 3 个参数时,第三个是索引,从 0 开始
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>
这里的:key
就是唯一标识,加上这个配置可以提高渲染效率。无论是数组还是对象,都采用唯一标识index
,作为key的值。
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">看到我啦?!if</h1>
<h1 v-show="show">看到我啦!show</h1>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
show: true,
},
});
</script>

与v-for
结合,筛选出女生来
<body>
<div id="app">
<ul>
<li v-for="(user, index) in users" v-if="user.gender == '女'">
{{index + 1}}. {{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>
<script type="text/javascript">
let app = new Vue({
el: "#app",
data: {
users: [
{ name: "柳岩", gender: "女", age: 21 },
{ name: "张三", gender: "男", age: 18 },
{ name: "范冰冰", gender: "女", age: 24 },
{ name: "刘亦菲", gender: "女", age: 18 },
{ name: "古力娜扎", gender: "女", age: 25 },
],
},
});
</script>
</body>

与v-else
和v-else-if
结合,作条件判断
<body>
<div id="app">
<button v-on:click="random=Math.random()">点我呀</button><br /><br /><br />
<span>random={{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 type="text/javascript">
let app = new Vue({
el: "#app",
data: {
random: 1,
},
});
</script>
</body>

计算属性和侦听器
<body>
<div id="app">
<!-- 某些结果是基于之前数据实时计算出来的,我们可以利用 计算属性 来完成 -->
<ul>
<li>
西游记; 价格:{{xyjPrice}},数量:<input
type="number"
v-model="xyjNum"
/>
</li>
<li>
水浒传; 价格:{{shzPrice}},数量:<input
type="number"
v-model="shzNum"
/>
</li>
<li>总价:{{totalPrice}}</li>
{{msg}}
</ul>
</div>
<script>
//watch可以让我们监控一个值的变化。从而做出相应的反应。
new Vue({
el: "#app",
data: {
xyjPrice: 99.98,
shzPrice: 98.0,
xyjNum: 1,
shzNum: 1,
msg: "",
},
// 计算属性
computed: {
totalPrice() { // totalPrice的值是基于 其他操作之后 得出的值 来计算的;而且是实时计算
return this.xyjPrice * this.xyjNum + this.shzPrice * this.shzNum;
},
},
watch: { // 监听器
xyjNum(newVal, oldVal) { // 监听xyjNum这个变量,这个变量发生变化之后,会执行后面的函数
if (newVal >= 3) {
this.msg = "库存超出限制";
this.xyjNum = 3;
} else {
this.msg = "";
}
},
},
});
</script>
</body>

过滤器
<body>
<!-- 过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 -->
<div id="app">
<ul>
<li v-for="user in userList">
{{user.id}} ==> {{user.name}} ==> {{user.gender == 1?"男":"女"}} ==>
{{user.gender | genderFilter}} ==> {{user.gender | gFilter}}
</li>
</ul>
</div>
<!--
每个过滤器要使用三元运算符来赋值男女:user.gender == 1?"男":"女"
有过滤器后,使用 通道符 `|` {{user.gender | genderFilter}}
每一个元素都会执行genderFilter方法和gFilter方法
传入的值:user.gender
-->
<script>
// 全局过滤器:
Vue.filter("gFilter", function (val) {
if (val == 1) {
return "男~~~";
} else {
return "女~~~";
}
})
let vm = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: 'jacky', gender: 1 },
{ id: 2, name: 'peter', gender: 0 }
]
},
filters: {
//// filters 定义局部过滤器,只可以在当前vue实例中使用
genderFilter(val) {
if (val == 1) {
return "男";
} else {
return "女";
}
}
}
})
</script>
</body>

user.gender == 1?"男":"女"
这段代码改变了user.gender的值,有代码侵入。
但是过滤器不改变真正的data
,而只是改变渲染的结果,并返回过滤后的版本。
过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind表达式
组件化
<body>
<div id="app">
<button v-on:click="count++">我被点击了 {{count}} 次</button> <br />
<br />
全局组件:<counter></counter><br />
<br />
局部组件:<jb></jb><br />
</div>
<script>
//1、全局声明注册一个组件: counter组件的名字
Vue.component("counter", {
template: `<button v-on:click="count++">我被点击了 {{count}} 次</button>`,
data() {
return {
count: 1,
};
},
});
//2、局部声明一个组件
const buttonCounter = {
template: `<button v-on:click="count++">我被点击了 {{count}} 次~~~</button>`,
data() {
return {
count: 1,
};
},
};
new Vue({
el: "#app",
data: {
count: 1,
},
// 然后在 Vue 中使用局部组件
components: {
"jb": buttonCounter,
},
/**
components 就是当前 vue 对象子组件集合。
- 其 key 就是子组件名称
- 其值就是组件对象名
*/
});
</script>
</body>

组件其实也是一个 Vue 实例,因此它在定义时也会接收:data、methods、生命周期函数等
不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有 el 属性。
但是组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板
全局组件定义完毕,任何 vue 实例都可以直接在 HTML 中通过组件名称来使用组件了
data 必须是一个函数,不再是一个对象。
定义好的组件,可以任意复用多次
一旦组件全局注册,就意味着即便以后你不再使用这个组件,它依然会随着 Vue 的加载而加载。因此,对于一些并不频繁使用的组件,我们会采用局部注册。
局部组件效果与全局注册是类似的,不同的是,局部组件只能在当前的 Vue 实例中使用
生命周期钩子函数

<body>
<div id="app">
<span id="num">{{num}}</span>
<button @click="num++">赞!</button>
<h2>{{name}},有{{num}}个人点赞</h2>
</div>
<script>
let app = new Vue({
el: "#app",
data: {
name: "张三",
num: 100,
},
methods: {
show() {
return this.name;
},
add() {
this.num++;
},
},
beforeCreate() {
console.log("=========beforeCreate=============");
console.log("数据模型未加载:" + this.name, this.num);
console.log("方法未加载:" + this.show());
console.log("html模板未加载:" + document.getElementById("num"));
},
created: function () {
console.log("=========created=============");
console.log("数据模型已加载:" + this.name, this.num);
console.log("方法已加载:" + this.show());
console.log("html模板已加载:" + document.getElementById("num"));
console.log(
"html模板未渲染:" + document.getElementById("num").innerText
);
},
beforeMount() {
console.log("=========beforeMount=============");
console.log(
"html模板未渲染:" + document.getElementById("num").innerText
);
},
mounted() {
console.log("=========mounted=============");
console.log(
"html模板已渲染:" + document.getElementById("num").innerText
);
},
beforeUpdate() {
console.log("=========beforeUpdate=============");
console.log("数据模型已更新:" + this.num);
console.log(
"html模板未更新:" + document.getElementById("num").innerText
);
},
updated() {
console.log("=========updated=============");
console.log("数据模型已更新:" + this.num);
console.log(
"html模板已更新:" + document.getElementById("num").innerText
);
},
});
</script>
</body>

点击按钮之后,会先后执行beforeUpdate
和updated

vue 模块化开发
安装vue项目
全局安装webpack
npm install webpack -g
全局安装 vue 脚手架
npm install -g @vue/cli-init
vue init webpack appname
:vue 脚手架使用 webpack 模板初始化一个 appname 项目
vue init webpack vue-test
问题:How to fix “zsh: command not found: vue”? – Zsh
- Uninstall the existing vue CLI globally using these commands:
sudo npm uninstall --global vue-cli
sudo npm uninstall --global @vue/cli
- Install the latest version of vue CLI globally:
sudo npm install --global @vue/cli@latest
- Ensure that the vue command is now recognized by running:
vue --version
启动项目:npm start
= npm run dev
了解vue项目结构
项目结构如下:

项目运行的大致流程:
主入口页面:index.html,里面的内容非常简单:
<body> <div id="app"></div> <!-- built files will be auto injected --> </body>
主程序文件:src/main.js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' // 这里导入 import App from './App' import router from './router'// 路由文件 Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', // 挂载 index里面的div页面 router, // 路由,这里是简写,完整写法是 router:router // 使用App这个组件,组件用于页面,这里是简写,全写是 App:App。在Vue实例中,是一个局部组件。组件来源:src/App.vue components: { App }, template: '<App/>' // 表示使用App组件 })
App组件:src/App.vue
<!-- template: 决定页面如何展示,怎么展示 --> <template> <div id="app"> <!-- 引入一张图片:src/assets/logo.png --> <img src="./assets/logo.png"> <!-- 路由视图:意思是页面上方是一张图片,而页面下方显示什么,是有路径决定的 --> <router-view/> </div> </template> <!-- script代码:数据的运算等。如data和method --> <script> export default { name: 'App' // 定义这个组件的名字加 App。在main.js中:template: '<App/>' } </script> <!-- 当前模版的样式 --> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
目前页面是这样:
我们目前的访问路径是这样:
http://localhost:8080/#/
在main.js中的
router,
配置,决定了访问路径和展示内容的关系路由内容:src/router/index.js
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld'//引入HelloWorld组件。这里的@表示src目录 Vue.use(Router) export default new Router({ routes: [ {//意思是:http://localhost:8080/ 这个路径访问,就展示HelloWorld这个组件 path: '/', name: 'HelloWorld', component: HelloWorld } ] })
HelloWorld组件:src/components/HelloWorld.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <h2>Essential Links</h2> <ul> <li> <a href="https://vuejs.org" target="_blank" > Core Docs </a> </li> <li> <a href="https://forum.vuejs.org" target="_blank" > Forum </a> </li> <li> <a href="https://chat.vuejs.org" target="_blank" > Community Chat </a> </li> <li> <a href="https://twitter.com/vuejs" target="_blank" > Twitter </a> </li> <br> <li> <a href="http://vuejs-templates.github.io/webpack/" target="_blank" > Docs for This Template </a> </li> </ul> <h2>Ecosystem</h2> <ul> <li> <a href="http://router.vuejs.org/" target="_blank" > vue-router </a> </li> <li> <a href="http://vuex.vuejs.org/" target="_blank" > vuex </a> </li> <li> <a href="http://vue-loader.vuejs.org/" target="_blank" > vue-loader </a> </li> <li> <a href="https://github.com/vuejs/awesome-vue" target="_blank" > awesome-vue </a> </li> </ul> </div> </template> <script> export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> h1, h2 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } </style>
导入 element-ui 快速开发
安装element-ui
npm i element-ui -S
引入 Element
// 引入 import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' // 使用 Vue.use(ElementUI) // 没有这段代码:‘ElementUI‘ is defined but never used no-unused-vars
根据文档操作编写即可
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1909773034@qq.com