class Node { constructor(element) { this.element = element this.next = null } } class LinkedList { constructor() { this.count = 0 this.head = null } push(element) { const node = new Node(element) if (this.head === null) { this.head = node } else { let current = this.head while (current.next !== null) { current = current.next } current.next = node } this.count++ } //指定位置删除 removeAt(index) { if (index >= 0 && index < this.count) { let current = this.head if (index === 0) { this.head = this.head.next } else { let previous = this.getNodeAt(index - 1) current = this.getNodeAt(index) previous.next = current.next } this.count-- return current.element } return } //获取指定下标的节点 getNodeAt(index) { if (index >= 0 && index < this.count) { let node = this.head for (let i = 0; i < index; i++) { node = node.next } return node } return } equalFn(a, b) { return JSON.stringify(a) === JSON.stringify(b) } indexOf(element) { let current = this.head for (let i = 0; i < this.count; i++) { if (this.equalFn(element, current.element)) { return i } current = current.next } return -1 } //删除指定元素 remove(element) { const index = this.indexOf(element) return this.removeAt(index) } insert(element, index) { if (index >= 0 && index <= this.count) { const node = new Node(element) if (index === 0) { let current = this.head node.next = current this.head = node } else { let previous = this.getNodeAt(index - 1) let current = previous.next node.next = current previous.next = node } this.count++ return true } return false } isEmpty() { return this.size() === 0 } size() { return this.count } getHead() { return this.head } } let link = new LinkedList()
]]>class Queue { constructor() { this.items = [] } //入列 enqueue(data) { this.items.push(data) } //出列 dequeue() { return this.items.shift() } front() { return this.items[0] } isEmpty() { return this.items.length === 0 } size() { return this.items.length } clear() { this.items = [] } toString() { return this.items.join() } } function game(list, num) { let queue = new Queue() for (let i = 0; i < list.length; i++) { queue.enqueue(list[i]) } while (queue.size() > 1) { for (let i = 0; i < num; i++) { queue.enqueue(queue.dequeue()) } console.log(queue.dequeue(), "out!"); } return queue.dequeue() }
]]>class Stack { constructor() { this.items = [] } push(data) { this.items.push(data) } pop() { return this.items.pop() } peek() { return this.items[this.items.length - 1] } isEmpty() { return this.items.length === 0 } size() { return this.items.length } clear() { this.items = [] } toString() { return this.items.join() } } function convert(data, base) { let stack = new Stack() let string = "" let number = data let baseString = "0123456789ABCDEF" while (number > 0) { stack.push(number % base) number = Math.floor(number / base) } while (!stack.isEmpty()) { string += baseString[stack.pop()] } return string } let res = convert(500, 16) console.log(res);
]]>Axios相信对前端熟悉的同学对它不会感到陌生了,这简直就是前端近年来的一大杀器,
官方推荐使用axios来进行网络请求,后面基本大部分项目都能瞧见它的身影。虽然axios很强,
但是单纯的axios并不能满足我们日常的使用,因此很多时候我们都需要对axios进行二次封装,
接下来我们就来详细讨论讨论。
通常我们的项目会越做越大,页面也会越来越多,如果页面非常的少,直接用axios也没有什么大的影响,
那页面组件多了起来,上百个接口呢,这个时候后端改了接口,多加了一个参数什么的呢?那就只有找到那个页面,
进去修改.整个过程很繁琐不易于项目的维护和迭代.
这个时候如果我们统一的区管理接口,需要修改某一个接口的时候直接在api里修改对应的请求是不是很方便呢?
总结:api统一管理,不管接口有多少,所有的接口都可以非常清晰,容易维护.
yarn create vite
这里我们使用vite来初始化一个Vue项目
yarn add axios
以图灵官网的接口为例
我们在项目中创建 api
文件夹用来管理所有的API,创建axios.js
文件二次封装axios.
//axios.jsimport axios from "axios";function myAxios(axiosConfig) { const service = axios.create({ baseURL: "https://www.turingteam.me:8081", // 设置统一的请求前缀 timeout: 10000 // 设置统一的超时时长 }); return service(axiosConfig);}export default myAxios
这里的service(axiosConfig)
返回的是一个Promise对象
如所有成员相关的API就放在 member.js
文件中,所有项目相关的API就放在 project.js
中,
这样子就很有条理性。
下面我们来 project.js
中编写获取项目列表的API。
//project.jsimport myAxios from "../axios";//团队项目查询export function queryProjectAPI(offset, page) { return myAxios({ url: "/guest/project/queryProject", method: 'get', params: { offset, page } })}//通过id查询团队项目详细信息export function queryProjectByIdAPI(id) { return myAxios({ url: "/guest/project/queryProjectById", method: 'get', params: { id } })}
在 App.vue 文件中随便加一个按钮,点击触发请求。
<template> <button @click="getList">点击</button></template><script lang='js'>import {defineComponent} from 'vue'import {queryProjectAPI} from '@/api/project.js';export default defineComponent({ setup() { const getList = async () => { try{ let res = await queryProjectAPI(offset, page) console.log(res); }catch(error){ console.log(error); } } return { getList } }})</script>
到此,我们就封装了一个最简单的axios,我们每次新增加一个 API,只需要找到对应模块的 API 文件去添加即可,然后再到具体页面导入使用
在POST请求中的 Content-Type
常见的有以下3种形式:
Content-Type: application/jsonContent-Type: application/x-www-form-urlencodedContent-Type: multipart/form-data
现在主流基本在用application/json形式,Axios默认以这种形式工作,我们给后端接口传递参数也简单,直接丢在其data参数就行了。
我们在 resume.js
文件中编写简历API
import myAxios from "../axios";//创新组内容填写export function resumeInnovateAddAPI(data) { return myAxios({ url: "/guest/resume/resumeInnovateAdd", method: 'post', data: data, });}
但是有时候后端要求Content-Type必须以application/x-www-form-urlencoded形式,那么通过上面传递的参数,后端是收不到的,我们必须对参数数据进行所谓的序列化处理才行,让它以普通表单形式(键值对)发送到后端,而不是json形式
import myAxios from "../axios";//创新组内容填写export function resumeInnovateAddAPI(data) { return myAxios({ url: "/guest/resume/resumeInnovateAdd", method: 'post', data: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, transformRequest: [ (data) => { let result = '' for (let key in data) { result += encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) + '&' } return result.slice(0, result.length - 1) } ],}
我通过 headers 来指定Content-Type的形式,对于 transformRequest 就是允许在向服务器发送前,修改请求数据,但只能用在 ‘PUT’,’POST’ 和 ‘PATCH’ 这几个请求方法,且后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream,更多的还有 transformResponse 能在传递给 then/catch 前,允许修改响应数据,其余更多参数的可以去 Axios文档查看。
在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装;
service.interceptors.request.use(function (config) { // 在发送请求之前做些什么,例如加入token ....... return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); });
同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等。
service.interceptors.response.use(function (response) { // 在接收响应做些什么 ...... return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); });
未完待续
]]>最近我在使用yarn的时候出现下面这种提示的频率越来越高了:
例如:info There appears to be trouble with your network connection. Retrying…
info There appears to be trouble with your network connection. Retrying…
信息:网络连接似乎出了点问题,请重试… 但我仔细检查下来,自己的网络似乎并没有什么问题,
网络一切正常,问题就很可能出现在了代理连接上。
更换安装依赖的镜像,使用淘宝镜像安装,代码如下:
yarn config set registry https://registry.npm.taobao.org
yarn config delete proxynpm config rm proxynpm config rm https-proxy
npm install -g cnpm --registry=https://registry.npm.taobao.orgnpm config set registry https://registry.npm.taobao.org
这样问题就解决了
]]>一年前的自己刚刚度过了高考难关,满心欢喜(bushi)的踏入了大学,
在师兄师姐的介绍下,懵懵懂懂的选择了前端这个方向,经过一年的摸索
也算是入了前端的门。下面就总结一下个人的前端学习路线
这份学习路线并不完美,也不会有最终形态,正如前端不可预见、永无止境的未来。
仅供参考,此路线仅供零基础想入门的前端的同学,以及我的师弟师妹们有个参考。
等你入门了之后,对前端有个大概了解就知道以后深入需要学习什么了。
工欲善其事,必先利其器。
浏览器:
编辑器:
文档笔记
tip:建议从实战开始,边学边练,培养兴趣,快速入门。
前端三剑客:HTML CSS JavaScript
俗话说:基础不牢,地动山摇。基础的重要性不需要我多讲了吧。
HTML CSS JavaScript 作为前端最基础,同时我认为也是最重要的。
这一阶段的学习一定要慢而细,最重要的是一定要动手敲代码!动手敲代码!动手敲代码!
重要的事情说三次,不要只是跟着视频看而不去自己动手操作,很多东西你只有上手过后才能
有更深的理解,看十遍百遍不然自己动手敲一遍。
HTML + CSS
JavaScript
到了这里,恭喜你!你已经能用前端三剑客写一些静态的网页了。
下面我们继续学习!
当然如果你有更适合自己的学习方法,可自行学习。
交互和JS高级知识
团队协作 代码托管
集中存储、备份你的代码,还能和团队成员协作开发。
Node Js
一个开源与跨平台的 JavaScript 运行时环境。它是一个可用于几乎任何项目的流行工具!
包管理
用于安装 Node.js 的扩展、工具等。
数据库
到了这里相信你的基础y已经比较扎实了,开始框架的学习。
优先学习Vue,然后是React,小程序后面根据自己需要学
]]>以上就是我大一到大二一年时间的学习路线,如果你是刚入门的小白,
不知道从哪里学起,可以参考我的学习路线,当然可能不适合所有人。
根据自己的需求学习。当然,我们前端的学习才刚刚开始,一入前端深似海,后面就要靠你们自己努力了。
一起加油把!!
一直都想拥有自己的一个博客,今日愿望实现了
此博客用于个人的学习记录,单纯用来做笔记,顺便用来分享一下,
就这样,记录下开博客的第一天