一、前言
在学习vue框架中,总是有些知识不是很熟悉,又不想系统的学习JS,因为学习成本太大了,所以用到什么知识就学习什么知识。此文档就用于记录零散的知识点。主要是还是针对与ES6规范的JS知识点。
以下实验环境都是在windows环境下,在vue框架中进行实验,因为这样比较方便,也更方便以后在VUE当中的运用
二、函数
1.回调函数
1.1 概念
如果将 “函数A” 作为"参数"传递给函数B时,我们称函数A为 “回调函数”
1.2 实例
<template>
</template>
<script setup>
// test1作为参数传递给了函数2,那么test1就是一个回调函数
function test1(){
console.log('我是一个回调函数')
}
function test2(fn){
fn()
console.log("我是test2函数")
}
test2(test1)
</script>
查看控制台,发现函数执行成功
2.箭头函数
2.1.没有参数的箭头函数
test = () => console.log('这是最简单的箭头函数')
test()
2.2.单参箭头函数
test = x => console.log('x = ' + x)
test(10)
2.3.多参数箭头函数
多参箭头函数参数的小括号就不能省略了
test = (x,y) => console.log('x = ' + x,'y = ' + y)
test(10,20)
2.4.函数体只有一行内容
如果只有一行语句,可以同时省略大括号和return。
test = () => 10 + 10
console.log(test()
2.5.函数体有多行
如果函数体部分有多行,就需要使用{},如果有多上的话,其实就没必要使用箭头函数了
test = () => {console.log('1'),console.log('2')}
test()
2.6.return和{}必须并存
test = () => {return 10 + 20}
x = test()
console.log(x)
注意:在js中会有很多情况会使用匿名的箭头函数作为函数的参数
三、解构-赋值
1.数组解构
正常的一个例子,将数组的值分别赋值给多个变量
<template>
</template>
<script setup>
const arr = [ 100, 60, 80 ]
const max = arr[0]
const avg = arr[1]
const min = arr[2]
console.log(max,avg,min)
</script>
这样赋值在语法上就比较繁琐。
解构赋值的语法如下:
<template>
</template>
<script setup>
const arr = [ 100, 60, 80 ]
// 对数组进行结构赋值
const [ max,avg,min ] = arr
console.log(max,avg,min)
</script>
2.对象解构
2.1 解构对象
注意点:解构时候的变量名必须要和对象之中的key一致。
<template>
</template>
<script setup>
// 解构之前打印
const obj = {name: "zhangsan",age: 20}
console.log(obj.name,obj.age)
// 解构之后打印
const {name,age } = obj
console.log(name,age)
</script>
2.1.1 解构重命变量
有时候解构的时候,变量名可能和其它的变量冲突了,那么就需要重命名。如下:
<template>
</template>
<script setup>
const name = "lisi"
const age = 200
const obj = {name: "zhangsan",age: 20}
// 解构之后需要给变量重命名,避免和其它变量冲突
const {name:username,age: userage } = obj
console.log(username,userage)
</script>
2.2 解构数组对象
<template>
</template>
<script setup>
//解构之前打印
const obj = [{
name: "zhangsan",
age: 20
}]
console.log(obj[0].name,obj[0].age)
//解构之后打印
const [{ name,age}] = obj
console.log(name,age)
</script>
2.3 多级对象解构
<template>
</template>
<script setup>
const obj = {
name: "zhangsan",
family: {
name: "xiaoli",
age: 20
}
}
console.log(obj.family.name,obj.family.age)
// 这里的family是不能省略的,作用是为了指定解构哪个对象
const {name:name1, family: {name,age}} = obj
console.log(name1,name,age)
</script>
四、字符串
1.模板字符串
1.1 使用场景:
1.拼接字符串和变量
2.在没有它之前,要拼接变量比较麻烦
1.2 语法
`xxxxx${变量名}xxxxxxx`
2.模板字符串实例
2.1 常规字符串拼接
<template>
</template>
<script setup>
let name = "zhangsan"
let age = 20
console.log(name + "今年" + age + "岁了")
</script>
2.2 模板字符串拼接
<template>
</template>
<script setup>
let name = "zhangsan"
let age = 20
console.log(`${name}今年${age}岁了`)
</script>
五、模块化
1.分别暴露
1.1 概念和语法:
1.分别暴露就是 每个变量和函数都需要使用 export 暴露出去.
2.语法: export 要暴露的内容
3.引入:引入的时候需要注意,暴漏的变量名是什么,引入的时候就写什么,不能自定义更改名称
1.2 创建分别暴露模块文件
创建test.js,内容如下:每个变量和函数都单独使用export进行了暴漏
export const data1 = "hello"
export const data2 = "world"
export function test(){
console.log("这是一个test函数")
}
1.3 引入分别暴露模块文件
在app.vue文件中引入模块文件
<template>
</template>
<script setup lang="ts">
# 引入模块文件中变量
import { data1,data2,test } from './utils/test'
console.log(data1)
console.log(data2)
test()
</script>
2.统一暴露
2.1 概念和语法
1.概念: 不需为每个变量都使用单独的export进行暴露,使用一个export即可暴露所有内容
2.语法:export { 要暴露的内容 }
2.2 创建统一暴露模块文件
创建test.js,内容如下:所有的内容需要一个export 暴露即可
const data1 = "hello"
const data2 = "world"
function test(){
console.log("这是一个test函数")
}
export {
data1,data2,
test
}
2.3 引入统一暴漏模块文件
引入的时候和分别暴漏没有区别,用法完全一致
<template>
</template>
<script setup lang="ts">
import { data1,data2,test } from './utils/test'
console.log(data1)
console.log(data2)
test()
</script>
3.默认暴露
3.1 概念和语法
1.默认暴露:在一个模块文件中,只能有一个默认暴漏
2.语法: export default 要暴漏的内容
3.引入: 引入默认暴漏的时候,可以自定义名称,而且不用使用{}解构(就是不用分别引入)。
3.1 默认暴露一个内容
function test(){
console.log("这是一个test函数")
}
export default test
3.2 引入模块文件
这里发现,没有使用{} 也没有和test的变量名对应,而是使用了fn进行接受。结果运行成功
<template>
<div>
<button @click="send">发送请求</button>
</div>
</template>
<script setup lang="ts">
import fn from './utils/test'
fn()
</script>
3.3 默认暴漏多个内容
const data1 = "hello"
const data2 = "world"
function test(){
console.log("这是一个test函数")
}
export default {
data1,data2,test
}
3.4 引入模块文件
注意:此时当默认暴漏多个内容时,引入的时候,用法和默认暴多一个内容时是不一样的!!!!!
暴露一个内容时:引入的内容就是暴露的内容,可以直接使用
暴露多个内容时: 引入的内容不能直接使用,而是按照对象的使用方法进行使用
<template>
<div>
<button @click="send">发送请求</button>
</div>
</template>
<script setup lang="ts">
import test_data from './utils/test'
console.log(test_data.data1)
console.log(test_data.data2)
test_data.test()
</script>
以上三种暴露方法根据场景进行使用区分使用。
六、axios
这里后端使用的是json-server,json-server默认是允许跨域请求的
1.GET请求
1.1 完整版
带请求参数的完整版axios请求.
<template>
<button @click="send">发送请求</button>
</template>
<script setup>
import axios from "axios";
function send() {
const res = axios({
method: "GET",
url: "http://192.168.1.10:3000/students/",
params: {
name: "zhangsan"
}
})
res.then(
response => {
console.log('-----------')
console.log(response.data)
},
error => {
console.log(error)
}
)
}
</script>
1.2 简写版
<template>
<button @click="send">发送请求</button>
</template>
<script setup>
import axios from "axios";
function send(){
axios.get(
"http://192.168.1.10:3000/students",
{params: { name: "zhangsan"}}
).then(
response => {
console.log(response.data)
},
error => {
console.log(error)
}
)
}
</script>
两种写法的区别点要注意:
1.完整版本中 axios中的参数是一个对象形式的实参
2.简写版本中 axios中的参数不是一个对象,而是两个实参
2.POST请求
2.1 完整版
<template>
<button @click="send">发送请求</button>
</template>
<script setup>
import axios from "axios";
function send(){
const res = axios({
method: "POST",
url: "http://192.168.1.10:3000/students",
data: {
id: 4,
name: "xiaoqiang",
age: 26
}
})
res.then(
response => {
console.log(response)
},
error => {
console.log(error)
}
)
}
</script>
2.2 简写版
<template>
<button @click="send">发送请求</button>
</template>
<script setup>
import axios from "axios";
function send(){
axios.post(
"http://192.168.1.10:3000/students",
{ id: 5, name:"xiaohu",age:23}
). then(
response => {
console.log(response)
},
error => {
console.log(error)
}
)
}
</script>
3.create方法
axios有一个create方法,可以构建出具有不同配置的axios实例。这样就可以满足不同的请求。
到这里,不直接在APP.vue文件中进行引入axios,而是单独创建一个axios的模块文件进行封装。
上边的GET和POST方法只是为了讲解语法,所有直接在APP.vue文件中进行请求,比较方便。这里使用了create方法就开始涉及到了自定义配置。所以进行了单独的拆分和封装
3.1 创建模块文件
创建src/utils/request.js文件
import axios from "axios";
# 创建第一个axios的实例
const request = axios.create({
baseURL: "http://192.168.1.10:3000",
# 超时时间为8秒
timeout: 8000
})
# 创建第二个axios的实例
const request1 = axios.create({
baseURL: "http://192.168.1.11:3000",
# 超时时间为3秒
timeout: 3000
})
# 暴露两个axios实例
export { request,request1 }
3.2 使用axios实例
在APP.vue中引入axios实例并使用.
<template>
<button @click="send">发送请求</button>
</template>
<script setup>
import { request } from './utils/request'
function send(){
request.get(
# 这里不用再写完整的目标地址
"/students",
{ params: {age: 23} }
).then(
response => console.log(response.data),
error => console.log(error)
)
}
</script>
4.拦截器
4.1.请求拦截器
这里创建了axios的实例 request, 那么就设置request的请求拦截i,如果没有设置任何axios的实例,就设置axios的拦截器.
return config 是必须的,是不能省略的
import axios from "axios";
const request = axios.create({
baseURL: "http://192.168.1.10:3000",
timeout: 8000
})
# 请求拦截器
request.interceptors.request.use(config => {
console.log('----------')
console.log(config)
console.log('----------')
return config
})
export { request }
4.2.响应拦截器
import axios from "axios";
const request = axios.create({
baseURL: "http://192.168.1.10:3000",
timeout: 8000,
})
request.interceptors.request.use(config => {
console.log('----------')
console.log(config)
console.log('----------')
return config
})
# 响应拦截器,对数据进行解构
request.interceptors.response.use(response => {
console.log('#######')
console.log(response)
console.log('#######')
return response.data
})
export { request }
这里的两种拦截器只写了语法,没有进行特有配置,在项目中根据情况进行配置
5.async函数
5.1 普通函数的返回值
function test(){
console.log('OK')
}
console.log(test())
结果是:undefined
5.2 async加上函数
async函数 加在任意一个函数的前面:
1.这个函数也会被标记为异步函数
2.函数的返回值会变成一个promise对象,
<script setup>
async function test(){
console.log('OK')
}
console.log(test())
</script>
结果是:
OK
Promise {<fulfilled>: undefined}
6.await函数
await函数主要有两个功能:
1.在异步函数中,阻塞 “await语句后边” 的所有的语句,等待await的语句执行完成后才会继续执行后续的语句
2.能够直接提取 await后边promise中的返回值,可以理解为then函数
6.1 编写python后端
这里没有继续使用json-server,要注意 前端要配置跨域,或者后端允许跨域请求
main.py内容如下:
main.py内容如下:
from flask import Flask
import json,time
app = Flask(__name__)
@app.route('/')
def index():
data = json.dumps({ "name": "张三","age": 1000})
time.sleep(5)
return data
if __name__ == "__main__":
app.run(host="0.0.0.0",debug=True)
6.2 配置前端代理
代理的含义就是 把所有的http请求都转发到 127.0.0.1:5137/api接口上。
那么api接口转发的后端是1.18:5000端口。这样就解决了浏览器同源的策略,解决了跨域请求
注意:前端的代理模式 适用于开发环境, 一旦上生产就需要使用nginx进行转发
编辑vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
# 新增以下内容
server: {
port: 5137, //vite的默认端口(别和后端冲突了)
proxy: {
"/api": { //代理的请求
target: "http://192.168.1.18:5000", //后端的地址
changeOrigin: true, //开启跨域访问
rewrite: (path) => path.replace(/^\/api/,''), //重写前缀(如果后端本身就有api这个通用前缀,那么就不用重写)
},
},
}
})
6.3 封装axios
编辑 src/utils/request.js.
这里的baseurl就不在后端的地址了,而是请求本机的/api接口
import axios from "axios";
const request = axios.create({
baseURL: "/api",
timeout: 8000,
})
export { request }
6.4 app.vue文件引入并测试
<template>
<h1>app.vue</h1>
<button @click="send">发送请求</button>
</template>
<script setup>
import { request } from './utils/request'
function send(){
console.log('before')
request.get("/").then(
response => {
console.log(response)
}
)
console.log('---------')
console.log('after')
}
</script>
这里发现,在浏览器点击 “发送请求”,没有任何阻塞,所有请求全部执行完毕。只是后端的python延时5秒返回数据
6.5 增加await函数
async 可以单独出现,但是await必须和async一起出现
<template>
<h1>app.vue</h1>
<button @click="send">发送请求</button>
</template>
<script setup>
import { request } from './utils/request'
async function send(){
console.log('before')
const {data} = await request.get("/")
console.log(data)
console.log('---------')
console.log('after')
}
</script>
这时候发现 awaite后边的所有语句全部阻塞,阻塞的原因是因为request没有执行完,并且加了await函数。
还有一点就是 不用使用then获取值,可以直接获取data的值
7.async和await小实例
异步请求数据后,然后在模板中显示出来
<template>
<h1>app.vue</h1>
<button @click="send">发送请求</button>
<h1>用户名: {{ name }}</h1>
<h1>年龄: {{ age }}</h1>
</template>
<script setup>
import {ref} from 'vue';
import { request } from './utils/request'
const name = ref()
const age = ref()
async function send(){
const {data} = await request.get("/")
name.value = data.name
age.value = data.age
}
</script>