Vue 3 —— A / 前置基础知识
一、变量和常量
(一)变量
定义方式:使用let
关键字声明
let name = 'Jack'
let age = 18name = 'Bit'
age = 20
(二)常量
定义方式:使用const
关键字声明,特性:声明时必须赋值,且不能重新赋值,但引用类型(数组、对象)内部元素可修改
const PI = 3.14const articleList = []const user = {
name: 'vue3',
age: 9}
(三)思考与实例
1. 问题:const
声明的数组能否添加或删除元素?const
声明的对象能否添加或修改属性?
2. 答案:可以,因数组和对象是引用类型,操作内部元素不改变内存地址
3. 实例:数组添加(arr.push(4)
)、删除(arr.shift()
);对象添加属性(obj.birth = 2015
)、修改属性(obj.age = 10
)
const arr = [1,2,3]// 添加
arr.push(4)
console.log(arr)// 删除
arr.shift()
console.log(arr)const obj = {
name: 'vue3',
age: 9
}// 添加属性
obj.birth = 2015
console.log(obj)// 修改属性
obj.age = 10
console.log(obj)
二、模版字符串
(一)普通字符串
定义方式:用单引号或双引号声明,常用单引号
// 普通字符串
let name = 'Jack'
let msg = "Hello World"
(二)模版字符串
定义方式:用反引号声明
let name = `Jack`
let msg = `Hello World`
(三)优势
1. 可任意换行:如声明 HTML 字符串时,能按 HTML 结构换行书写,增强可读性
const htmlStr = '<div class="hot-goods-box"><h1>热门商品</h1><p>卖爆了卖爆了卖爆了</p></div>'const htmlStr = `<div class="hot-goods-box"><h1>热门商品</h1><p>卖爆了卖爆了卖爆了</p></div>`
2. 可嵌入表达式:使用${表达式}
语法,避免繁琐字符串拼接,
let name = 'Bit'
let age = 9// 把 name,age 变量的值放到 xxx 的位置, 并且展示是否成年
// let str = 'My name is xxx, I am xxx years old, 未成年 or 已成年'// 传统的加号拼接
// let str = 'My name is ' + name + ', I am ' + age + ' years old' + (age >= age+'years old'+(age>=18 ? '已成年' : '未成年')// 模版字符串嵌入表达式
let str = `My name is ${name}, I am ${age} years old, ${age >= 18 ? '已成年' : '未成年'}`
三、对象
(一)取值方式
1. 点取值:如obj.name
、obj.age
,等同于obj['name']
、obj['age']
const obj = {
name: 'vue3',
age: 9
}console.log(obj.name)
console.log(obj.age)// 等同于
console.log(obj['name'])
console.log(obj['age'])
2. 中括号取值:当属性名是变量时必须用此方式,如let x = 'name'
,console.log(obj[x])
;属性名非变量时,点取值和中括号取值均可
const obj = {
name: 'vue3',
age: 9
}let x = 'name'
let y = 'age'// 正确的
console.log(obj[x])
console.log(obj[y])// 错误的
console.log(obj.x)
console.log(obj.y)
注意:当属性名是变量的时候, 只能用中括号取值; 否则既可以用点, 也可以用中括号
(二)简写形式
属性简写:当属性名和属性值变量名相同时,可省略属性值变量
let min = 1
let max = 99// 以前的写法(不简写)
const obj = {
min: min,
max: max
}// 现在的写法
const obj = {
min,
max
}
四、解构赋值
(一)适用目标
数组和对象
(二)作用
简化数组和对象的取值操作,提高代码效率
(三)代码示例
1. 数组结构
const arr = [11, 22, 33]
// eg1: 把 arr 中的3个值分别赋值给变量 a, b, c// 以前的写法
let a = arr[0]
let b = arr[1]
let c = arr[2]// 现在的写法
let [a, b, c] = arr// eg2: 把 arr 中的后两个值赋值给变量 b,c
let [,b,c] = arr// eg3: 把 arr 中的第1个值赋值给变量 a, 剩余的全部给到变量 rest
let [a, ...rest] = arr
2. 对象解构
const obj = {
name: '比特教育科技',
age: 9,
address: '陕西省西安市高新区沣惠南路34号'
}// eg1: 把 obj 中的3个属性值分别赋值给变量 name, age, address// 以前的写法
const name = obj.name
const age = obj.age
const address = obj.address// 现在的写法
const { name, age, address } = obj// eg2: 把 obj 的 age, address 属性值赋值给 age, address
const { age, address } = obj// eg3: 把 obj 的 name 属性值赋值给变量 name, 剩余的全部给到变量 rest
const { name, ...rest } = obj// eg4: 把 obj 的 name 属性值赋值给变量 uname
const { name: uname } = obj
(四)练习
const arr = [2,[3, 4],5]// 1、把 arr 中的3, 4赋值给变量 a,bconst obj = {
data: {
code: 10000,
message: '频道列表获取成功',
result: ['HTML', 'CSS', 'JavaScript', 'Vue', 'SprintBoot']
},status: 200,
statusText: 'Ok'
}
// 2、把 obj 中的 code, message, result 的值取出来赋值给变量 code, message, list
五、箭头函数
(一)非箭头函数形式
- 有名函数:
function fn() { // some code... }
- 函数表达式:
const fn = function() { // some code... }
(二)语法
- 基本语法:
const fn = () => { // some code... }
- 带参数语法:
const add = (x, y) => { return x + y }
(三)特点
- 参数简化:单个参数可省略小括号,如
const log = arg => { console.log(arg) }
- 函数体简化:函数体只有一句话可省略大括号,且自带 return,如
const add = (x, y) => x + y
- 返回对象简化:函数体直接返回对象时,需给对象加小括号,如
const state = () => ({token: 'xxxx', userInfo: {name: 'admin', id: 1}})
(四)应用场景
- 普通函数声明
- 回调函数传参,如
setTimeout(() => {}, 2000)
六、数组的重要方法
(一)概述
数组是 JavaScript 重要数据结构,掌握数组操作对开发至关重要
(二)添加元素方法
push()
:尾部添加元素,返回新数组长度,如const len = arr.push(44)
unshift()
:头部添加元素,返回新数组长度,如const len = arr.unshift(44)
(三)删除元素方法
pop()
:尾部删除元素,返回删除的元素,如const last = arr.pop()
shift()
:头部删除元素,返回删除的元素,如const first = arr.shift()
(四)任意位置操作方法
splice()
:语法arr.splice(startIndex: number, delCount: number, ...addItem)
- 示例:删除元素
arr.splice(1, 1)
;添加元素arr.splice(2, 0, 55)
(五)包含判断方法
includes()
:判断数组是否包含指定元素,返回布尔值,如arr.includes(33)
返回 true,arr.includes(55)
返回 false
(六)遍历方法
forEach()
:遍历数组,语法arr.forEach((item, index, array) => {})
,其中 item 为当前元素,index 为元素下标,array 为数组本身
(七)过滤方法
filter()
:保留满足条件的元素,返回新数组,语法const filteredArr = arr.filter((item, index, array) => { return 布尔值 })
- 示例:保留偶数
const eventArr = arr.filter((item) => item % 2 === 0)
(八)映射方法
map()
:由原数组得到新数组,二者长度相同且元素有对应关系,语法const mappedArr = arr.map((item, index, array) => { return 新值 })
- 示例:元素翻倍
const doubleArr = arr.map((item) => item * 2)
;转换为指定对象数组const newArr = arr.map((value, index) => ({index, value}))
(九)全量检测方法
every()
:检测数组所有元素是否满足条件,语法arr.every((item, index, array) => { return 布尔值 })
- 特性:返回 true 则继续检测,返回 false 则立即停止检测并最终返回 false
- 示例:判断是否都是奇数
const bool = arr.every((item) => item % 2 === 1)
;判断是否都大于 10const bool = arr.every((item) => item > 10)
(十)汇总方法
reduce()
:对数组元素进行汇总计算,语法const result = arr.reduce((prev, item, index, array) => { return 结果 }, 初始值)
- 示例:求和
const sum = arr.reduce((prev, item) => prev + item, 0)
;求商品总数量const totalNum = goodsList.reduce((prev, item) => prev + item.num, 0)
七、对象的重要方法
(一)Object.keys()
- 作用:获取对象所有键组成的数组
- 示例:
const obj = {id: 10001, name: 'Bit', age: 9, address: '陕西省西安市高新区沣惠南路34号'}
,const keys = Object.keys(obj)
,返回['id', 'name', 'age', 'address']
- 应用:遍历对象
Object.keys(obj).forEach(key => { console.log(obj[key]) })
;筛选属性Object.keys(obj).filter(key => key.startsWith('a')).forEach(key => { console.log(key, obj[key]) })
八、扩展运算符
(一)复制数组或对象
- 复制数组:
const arr1 = [11, 22, 33]
,const arr2 = [...arr1]
,避免直接赋值导致原数组受影响 - 复制对象:
const obj1 = {id: 10001, name: 'Bit', age: 9}
,const obj2 = {...obj1}
,避免直接赋值导致原对象受影响
(二)合并数组或对象
- 合并数组:
const arr1 = [1, 2, 3]
,const arr2 = [4, 5, 6]
,const arr = [...arr1, ...arr2]
- 合并对象:
const obj1 = {name: 'Jack', height: 176}
,const obj2 = {height: 180, age: 18}
,const obj = {...obj1, ...obj2}
,同名属性后者覆盖前者
九、序列化和反序列化
(一)序列化
- 定义:将对象转换为 JSON 格式字符串
- 方法:
JSON.stringify()
,示例const json = {id: 10001, name: 'Bit', age: 9}
,const jsonStr = JSON.stringify(json)
(二)反序列化
- 定义:将 JSON 字符串转换为 JSON 数据
- 方法:
JSON.parse()
,示例const jsonStr = '{"id": 10001, "name": "Bit", "age": 9}'
,const json = JSON.parse(jsonStr)
十、Web 存储
(一)介绍
sessionStorage
- 存储周期:页面会话期间可用,浏览器或选项卡关闭后数据消失
- 数据传输:不传输到服务器
- 存储限额:大于 Cookie,最大 5MB
localStorage
- 存储周期:浏览器关闭并重新打开后数据仍存在,无过期日期,需手动清除
- 数据传输:不传输到服务器
- 存储限额:大于 Cookie,最大 5MB
(二)用法(以localStorage
为例)
- 存储数据
- 基本存储:
localStorage.setItem(key: string, value: string)
,如localStorage.setItem('uname', 'Bit')
- 存储对象 / 数组:需先序列化,
localStorage.setItem('bit', JSON.stringify(obj))
- 基本存储:
- 获取数据
- 基本获取:
localStorage.getItem(key: string)
,如const uname = localStorage.getItem('uname')
,key 不存在时返回 null - 获取对象 / 数组:需反序列化,
const local = JSON.parse(localStorage.getItem('bit'))
- 基本获取:
- 删除数据:
localStorage.removeItem(key: string)
,如localStorage.removeItem('uname')
(三)注意事项
存储对象和数组时必须进行序列化和反序列化操作
十一、Promise + Async/Await
(一)Promise 的必要性
解决回调地狱问题,如多层嵌套的setTimeout
回调,代码可读性差
(二)Promise 介绍
- 本质:一个类,用于包装异步操作,根据异步操作结果确定自身状态
- 作用:支持链式调用,消除回调地狱
(三)Promise 的状态
- 三种状态:Pending(进行中)、Fulfilled(成功)、Rejected(失败)
- 状态变化:只能由 Pending 转为 Fulfilled 或 Pending 转为 Rejected,状态一旦确定不可改变
(四)Promise 基本使用
- 创建 Promise 实例:
const p = new Promise((resolve, reject) => { // 异步代码,成功调用resolve,失败调用reject })
- 处理结果:
p.then((msg) => { // 成功回调 }, (err) => { // 失败回调 })
(五)消除回调地狱示例
- 封装延迟函数:
function delay(duration, n) { return new Promise((resolve) => { setTimeout(() => { resolve(n) }, duration) }) }
- 链式调用:
delay(2000, 1).then(n1 => { console.log(n1); return delay(1000, 2) }).then(n2 => { console.log(n2); return delay(1000, 3) }).then(n3 => { console.log(n3) })
(六)Async/Await(异步终极解决方案)
- 语法规则
await
关键字需在async
修饰的函数内使用await
后接 Promise 实例,返回值为 Promise 的 resolve 参数async
函数内,await
执行结束后代码才继续执行,呈同步执行效果
- 示例:
async function log() { const n1 = await delay(2000, 1); console.log(n1); const n2 = await delay(1000, 2); console.log(n2); const n3 = await delay(1000, 3); console.log(n3) } log()
十二、模块化
(一)概述
- 定义:将复杂程序划分为独立、可互操作的模块,每个模块负责特定功能,通过接口通信
- 目的:提高代码可维护性、可重用性、可测试性和可扩展性,便于处理大型 JavaScript 项目
(二)目录结构准备
- 新建 12-es-module 目录
- 命令行进入该目录,执行
npm init
生成 package.json 文件 - 在 package.json 中添加 "type": "module"
- 根目录下新建 src/index.js 作为入口文件
- 在 src 目录下新建 utils 目录
(三)默认导出与导入
- 默认导出:在 utils/min.js 中,
export default function min(m, n) { return m > n ? n : m }
,一个模块中默认导出最多 1 次 - 默认导入:在 src/index.js 中,
import min from './utils/min.js'
,可直接使用导入的函数
(四)按需导出与导入
- 按需导出:在 utils/math.js 中,
export function add(x, y) { return x + y }
、export function sub(x, y) { return x - y }
,一个模块中按需导出可多次 - 按需导入:在 src/index.js 中,
import {add, sub} from './utils/math.js'
,可使用导入的指定函数