Vue3的基础知识
本章我们会使用JS语言来讲解Vue3的前置知识
变量和常量
变量
定义一个盒子,往这个盒子里添加数据,这个盒子里的数字可以更改
使用格式
let num=50;
演示代码
<script>let num=50;console.log(num)num=90console.log(num)
</script>
演示结果
这里的num的值可以更改,从50更改到了90
常量
定义一个盒子,往这个盒子里添加数据,这个盒子里的数据不可被更改
使用格式
const num1=50
演示代码
<script>const num1=50console.log(num1)num1=60console.log(num1)
</script>
演示结果
这里的报错意思是num1是一个常量,常量值不可被修改
模板字符串
普通字符串
使用单引号或双引号定义称之为普通字符串
使用格式
<script>let ST='STRING'let ST1="STRING2"
</script>
模板字符串
使用``定义的是模板字符串
特点
1.可以换行
使用格式
let st1=`<p>hello,world</p>`
代码演示
let st1=`<p>hello,world</p>`console.log(st1)console.log(typeof(st1))
演示结果
这里输出了st1的值和st1的类型
2.可以内嵌
使用格式
let num1="hello"let num2="world"let st1=`!!!${num1}${num2}!!!`
演示代码
<script>let num1="hello"let num2="world"let st1=`!!!${num1}${num2}!!!`console.log(st1)
</script>
演示结果
对象
和C++差不多就是一个结构体,里面有内置类型和方法
使用格式
let obj={num1:20,num2:30,num3:"hello"}
点取值
演示代码
let obj={num1:20,num2:30,num3:"hello"}console.log(obj.num3)//点取值console.log(obj['num3'])//等同于上面的取值
演示结果
中括号取值
演示代码
let obj={num1:20,num2:30,num3:"hello"}let x="num1"let y="num2"console.log(obj[x])console.log(obj[y])
演示结果
方法
就像C++一样每个对象中都有方法
演示代码
let obj={num1:20,num2:30,num3:"hello",FUNC(){console.log("HELLO,WORLD")}}obj.FUNC()
演示结果
解构赋值
让赋值更加简便
数组赋值
演示代码
let arr=[10,20,30,40,50]let [num1,num2,...ret]=arrconsole.log(num1)console.log(num2)console.log(ret)
演示结果
这里的"..."用于将arr的剩于数据赋值给ret,这样ret就成了数组,前面的num1和num2是单个变量
对象赋值
第一种
通过解构赋值,但是需要被赋值的变量名和对象中的保持一致
let obj={name:"GanChuHao",num:69,trade:1253}let{name,num,trade}=objconsole.log(name)console.log(num)console.log(trade)
演示结果
第二种
点赋值,可以和对象中的变量名不一致
let obj={name:"GanChuHao",num:69,trade:1253}let NUM1=obj.namelet NUM2=obj.numlet NUM3=obj.tradeconsole.log(NUM1)console.log(NUM2)console.log(NUM3)
演示结果
第三种
通过"..."赋值
let obj={name:"GanChuHao",num:69,trade:1253}let{name,...ret}=objconsole.log(name)console.log(ret)
演示结果
对象结构和数组结构的不同在于,在解构赋值中,数组可以不同名,但是对象解构需要同名,对象结构需要用{}而数组解构需要用[]
箭头函数
普通函数
function FUNC1(){console.log("HELLO,WORLD")}FUNC2=function(){console.log("hello,world")}FUNC1()FUNC2()
箭头函数
let FUNC=()=>{console.log("HELLO,WORLD")}FUNC()
箭头函数的优点
当没有大括号时,箭头函数可以默认返回
let FUNC=(x,y)=>x+yconsole.log(FUNC(20,60))
演示结果
返回结构体需要使用小括号
let FUNC=()=>({NUM1:12,NUM2:"HELLO",NUM3:60})let obj=FUNC()console.log(obj.NUM1)console.log(obj.NUM2)console.log(obj.NUM3)
演示结果
数组的重要方法
push和unshift
push用来在数组后面添加数据,unshift用来在数组前面添加数据
演示代码
let arr=[11,22,33,44]arr.push(55)console.log(arr)arr.unshift(22)console.log(arr)
演示结果
pop和shift
pop在数组删除数组最后面的一个数据,shift删除数组最前面的一个数据
演示代码
let arr=[11,22,33,44]arr.pop(22)console.log(arr)arr.shift()console.log(arr)
演示结果
splice
删除元素
演示代码
let arr=[11,22,33,44]let arr1=arr.splice(1,2)console.log(arr)console.log(arr1)
演示结果
添加元素
如果将第二个元素设置为零,意味着不删除元素,splice功能为添加元素
演示代码
let arr=[11,22,33,44]arr.splice(1,0,22)console.log(arr)
演示结果
splice可以用于在指定位置删除指定数量或添加指定数量元素
includes
检验数组是否包含某个数据,如果是返回true,如果不是返回false
演示代码
let arr=[11,22,33,44]let ret1=arr.includes(22)let ret2=arr.includes(55)console.log(ret1,ret2)
演示结果
forEach
forEach用于遍历数组,传统的遍历数组的方式:
let arr=[11,22,33,44]for(let i=0;i<arr.length;i++){console.log(arr[i])}
forEach遍历数组的方式
arr.forEach((ITEM,INDEX,ARRAY)=>{console.log(ITEM)})
forEach需要包含一个箭头函数,这个函数有三个参数,ITEM对应当前遍历下的数组数据,INDEX 对应当前遍历下的数组下标,ARRAY对应整个数组
全部演示一遍
let arr=[11,22,33,44]arr.forEach((ITEM,INDEX,ARRAY)=>{console.log(ITEM)console.log(INDEX)console.log(ARRAY)})
演示结果
filter
filter可以将数组中满足条件的数据保存,将不满足条件的数据过滤
演示代码
let arr=[11,22,33,44,55,66,77,88]let end=arr.filter((ITEM,INDEX,ARRAY)=>{if(ITEM%2==0){return true}else{return false}})console.log(arr)console.log(end)
演示结果
map
可以让一个数组得到另一个数组,并且数组间的数据是一一对应的关系
演示代码
let arr=[11,22,33,44,55,66,77,88]let end=arr.map((ITEM,INDEX,ARRAY)=>{return ITEM=ITEM*2})console.log(arr)console.log(end)
演示结果
这里将arr的数组数据全部都乘以2将计算后的结果放入end数组中
同时数组也能返回结构体,比如下面演示代码
let arr=[11,22,33,44,55,66,77,88]let end=arr.map((ITEM,INDEX,ARRAY)=>{return {index:INDEX,value:ITEM}})console.log(arr)console.log(end)
演示结果
every
用于检测数组所有的数据是否满足条件,全部数据满足条件返回true,只要有一个数据不满足条件返回false
演示代码
let arr1=[12,22,32,42,55,66,77,88]let ret=arr1.every((ITEM,INDEX,ARRAY)=>{console.log(ITEM)return ITEM%2==0})console.log(ret)let arr2=[12,22,32,42,52,62,72,82]let ret2=arr2.every((ITEM,INDEX,ARRAY)=>{console.log(ITEM)return ITEM%2==0})console.log(ret2)
演示结果
reduce
reduce用于计算数组的总值
演示代码
let arr1=[12,22,32,42,55,66,77,88]let sum=arr1.reduce((PREV,ITEM,INDEX,ARRAY)=>{return PREV+ITEM},0)console.log(sum)
其中PREV表示的是上一个返回的数值
上一个返回的数据加当前遍历的数据,一致遍历到最后一个数据,那么返回的数据就是数组的所有数据之和
reduce(函数,初始值),其中0为计算开始的初始值
演示结果
对于对象数据的求和
演示代码
const goodsList = [{ id: 1, name: '篮球', num: 1 },{ id: 2, name: '玩具', num: 3 },{ id: 3, name: '书籍', num: 2 }]let ret=goodsList.reduce((PREV,ITEM)=>{return PREV+ITEM.num},0)console.log(ret)
演示结果
对象的重要方法
Object.keys
传入一个对象,返回一个数组,数组包含对象所有的key
演示代码
let ARRAY=Object.keys(obj)console.log(ARRAY)
演示结果
遍历对象演示代码
let obj={name:"anchuhao",idcard:20230101,school:"ajxzyydx",other:"abgadsf",room:4325}Object.keys(obj).forEach((ITEM)=>{console.log(obj[ITEM])})
演示结果
扩展运算符
复制数组和对象
当我们创建了一个数组,想要一份它的赋值时
我们可能会采用这种方法
let arr1=[10,20,30,40,50]let arr2=arr1arr1.push(60)console.log(arr2)
演示结果
这里的arr2并不是复制了arr1的数组,而是复制了数组的地址,当修改arr1时,arr2也会修改,并不是真正意义上的复制数组
使用扩展运算符的方法复制数组
let arr1=[10,20,30,40,50]let arr2=[...arr1]arr1.push(60)console.log(arr2)
演示结果
这里的arr2并没有因为arr1多增一个数据而发生改变
对象赋值也是同理
演示代码
let obj1={num1:11,num2:22,num3:33,}let obj2=obj1obj1.num4=44console.log(obj2)let obj3={...obj1}obj1.num5=55console.log(obj3)
演示结果
合并数组或对象
合并两个或两个以上的数组或对象
演示代码
let obj1={num1:11,num2:22,num3:33,}let obj2={num4:44,num5:55,num6:66}let arr1=[11,22,33]let arr2=[44,55,66]let obj3={...obj1,...obj2}let arr3=[...arr1,...arr2]console.log(arr3)console.log(obj3)
演示结果
序列化和反序列化
序列化
将对象转化为JSON类型的字符串
演示代码
let arr={NUM1:11,NUM2:22,NUM3:33,NUM4:44}let ARR=JSON.stringify(arr)console.log(ARR)
演示结果
我们观察到这里的键值对都加了双引号,所以序列化的对象的键值对都需要加双引号
反序列化
将JSON类型的字符串转化为JSON类型的数据
演示代码
let arr='{"NUM1":11,"NUM2":22,"NUM3":33,"NUM4":44}'let ARR=JSON.parse(arr)console.log(ARR)
演示结果
这里的键值对必须加双引号不然会报错
Web存储
在我们的Web网页中有一块数据库可以给我们存放,获取,删除数据
数据是一个映射表,有key和value
localStorage.setItem
函数原型
localStorage.setItem(key,value)
演示代码
localStorage.setItem("SET",11)
演示结果
这里在网页的数据库中存放了一个key对应的value
localStorage.getItem
使用格式
localStorage.getItem(key)
返回值为value
let num=localStorage.getItem("SET")console.log(num)
演示结果
localStorage.removeItem
使用格式
localStorage.removeItem(key)
localStorage.removeItem("SET")
演示结果
这里的SET被删除了
关于数组和对象的存储方式
对象和数组存放进去的时候要进行序列化,取出来需要反序列化
演示代码
let obj={NUM1:11,NUM2:22,NUM3:33}localStorage.setItem(1,JSON.stringify(obj))let ret=JSON.parse(localStorage.getItem(1))console.log(ret)
演示结果
Promise+async/await
回调地狱
因为有了回调地狱所以才有了Promise
代码演示
setTimeout(()=>{console.log("Hello,World111111")setTimeout(()=>{console.log("Hello,World222222")setTimeout(()=>{console.log("Hello,World333333")},3000)},3000)},3000)
这里每过3秒都会打印"Hello,World"
但是这种代码很难阅读,很容易出错,所以才有了Promise来解决这个问题
Promiss介绍
Promiss是一个类用来包装异步操作,如果成功返回根据异步操作的结果来判断是成功还是失败,成功则运行成功后果的代码,失败则运行失败后的代码
基本用法
let p=new Promise((NUM1,NUM2)=>{setTimeout(()=>{NUM2("失败")NUM1("成功")},2000)})p.then((FUNC)=>{console.log(FUNC)},(FUNC2)=>{console.log(FUNC2)})
传递数据的方式
当Promiss执行到了NUM1和NUM1中其中一个则停下来
用Promiss消除回调地狱
function name(TIME,NUM) {return new Promise((NUM1)=>{setTimeout(()=>{NUM1(NUM)},TIME)})}name(1000,1).then((N1)=>{console.log(N1)return name(1000,2)}).then((N2)=>{console.log(N2)return name(1000,3)}).then((N3)=>{console.log(N3)})
演示结果
每秒打印一个数字
但是我们还能使用async+await继续优化
代码演示
async+await介绍
await必须要放在async里面使用
演示代码
function name(TIME,NUM) {return new Promise((NUM1)=>{setTimeout(()=>{NUM1(NUM)},TIME)})}async function log() {let num1=await name(1000,1)console.log(num1)let num2=await name(1000,2)console.log(num2)let num3=await name(1000,3)console.log(num3)}log()
演示结果
每秒打印一个数字
模块化
当我们在制作一个项目时,我们会有很多的代码,如果我们将这些代码全都集中在一个文件里,那么就会难以阅读,所以模块化就是将不同需求的代码放入不同的文件当中,当有问题时可以更好的发现
目录结构准备
- 新建ex-module目录
- 命令行进入ex-module目录
- 执行npm init初始化得到package.json文件
- 给package.json添加"type":"module"
- 在src目录底下新建index.js文件
- src目录下新建utils目录
默认导出于导入
默认导出格式
export default function sub(N,M){return N-M
}
默认导入
import jian from "./utils/main.js"
导入的内容的名可以和导出的不同
在导入文件中可以直接使用导出函数的定义
按需导出格式
export function main(N,M){return M>N?M:N
}
export function add(N,M){return N+M
}
按需导入
import {add,main} from './utils/main.js'
函数名必须相同,否则报错