图片上传功能中,预览功能实现
方法一:FileReader
方法二:createObjectURL
const file = document.querySelector('#file')const img = document.querySelector('#img')方法一:file.onchange = () => {// 浏览器中的 fs,但是只能操作用户选择的文件const reader = new FileReader()// 第二步:// 当图片读取转换完成,会触发 load 事件reader.addEventListener("load", function () {console.log(reader.result)// 此处得到的是一个 base64 编码之后的内容// 你可以认为图片文件文本化了img.src = reader.result}, false)// 第一步:// 开始读文件reader.readAsDataURL(file.files[0])}// 方法二:// file.onchange = () => {// // 使用// const data = URL.createObjectURL(file.files[0])// img.src = data// // 最好在使用完毕 data 之后,把它释放掉// // URL.revokeObjectURL(data)// }
HTTP缓存
缓存说的是GET请求
- 用node中原生的http模块来创建http服务进行测试
- 观察请求的打印日志
console.log
- Axios 中的错误对象继承自 JavaScript 中的 Error 对象
- console.log 内容和数据类型无关
- 浏览器输出Error对象时候会读取它内部的 stack 属性
- 所以打印的error只能看到文字,但是在代码中能点出方法
- MDN中的描述:通过Error的构造器可以创建一个错误对象。请注意,这是一个对像!
socket.io
- 浏览器服务端都要用到此插件,同时使用才能进行通信
- socket使用socket协议,http使用http协议,完全不同
- socket可是实现群发和单发功能
- 使用socket能很快速实现一个聊天功能,并不复杂。
简单实现
<!doctype html><html><head><title>Socket.IO chat</title><style>* { margin: 0; padding: 0; box-sizing: border-box; }body { font: 13px Helvetica, Arial; }form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }form input { border: 0; padding: 10px; width: 90%; margin-right: 0.5%; }form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }#messages { list-style-type: none; margin: 0; padding: 0; }#messages li { padding: 5px 10px; }#messages li:nth-child(odd) { background: #eee; }</style></head><body><div id="app"><form action=""><input v-model="nickname" type="text"><button @click.prevent="handleNickname"></button></form><!-- 消息列表 --><ul id="messages"><liv-for="(item, index) in messageList":key="index">{{ item }}</li></ul><!-- 发送消息的表单 --><form action=""><div style="border: 1px solid #000;"><input v-model="nickname" type="text"><button @click.prevent="handleNickname">昵称</button></div><!-- 广播 --><inputv-model="message"autocomplete="off"/><button@click.prevent="handleSend">广播</button><!-- 私聊 --><div style="border: 1px solid #000;"><input v-model="privateMessage" type="text"><input v-model="privateUser" type="text"><button @click.prevent="handlePrivateMessage">私聊</button></div></form></div><!-- 加载 socket.io 客户端 --><script src="/socket.io/socket.io.js"></script><script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js"></script><script>// WebSocket 通过 HTTP 协议建立连接// 建立连接成功后使用 WebSocket 进行通信const socket = io()// 接收服务端消息// socket.on('hello', data => {// console.log(data)// })socket.on('connect', () => {})const app = new Vue({el: '#app',data: {message: '',messageList: [], // 消息列表nickname: '',privateMessage: '',privateUser: ''},created () {socket.on('message', data => {// console.log('message => ', data)this.messageList.push(`${data.nickname}说:${data.message}`)})socket.on('chat-count', count => {this.messageList.push(`当前在线人数:${count}`)})socket.on('private-message', data => {console.log('private-message', data)this.messageList.push(`${data.nickname} 对你说:${data.message}`)})},methods: {// 发送消息handleSend () {socket.emit('message', this.message)},handleNickname () {socket.emit('nickname', this.nickname)},handlePrivateMessage () {socket.emit('private-message', {privateUser: this.privateUser,privateMessage: this.privateMessage})}}})</script></body></html>
// 后台const express = require('express')const http = require('http')const app = express()// 存储所有的客户端连接 socketconst clients = []// 创建服务实例const server = http.createServer(app)// 在 HTTP 服务中集成 socket.io 用来提供 WebSocket 服务const io = require('socket.io')(server)// 通过 app 设置的都是 HTTP 资源请求处理// 托管 public 目录中的静态资源app.use(express.static('./public'))// 通过 io 设置的都是 WebSocket 资源请求处理io.on('connection', (socket) => {// clients.push(socket)console.log('a user connected')// 当客户端断开连接后触发该事件// socket.on('disconnect', () => {// console.log('user disconnected')// const index = clients.findIndex(c => c.socket === socket)// if (index !== -1) {// clients.splice(index, 1)// }// })socket.on('nickname', nickname => {console.log(nickname)clients.push({// 名字: 连接信息nickname,socket})socket.emit('nickname', '注册成功')})socket.emit('chat-count', clients.length)socket.on('message', data => {const client = clients.find(c => c.socket === socket)// console.log(data)// 广播给所有的聊天室客户端io.emit('message', {isPrivate: false,nickname: client.nickname,message: data})})socket.on('private-message', data => {console.log('private-message', data)// 找到私聊用户,给它发送消息const privateUser = clients.find(c => c.nickname === data.privateUser)if (privateUser) {console.log(privateUser)privateUser.socket.emit('private-message', {nickname: clients.find(c => c.socket === socket).nickname,message: data.privateMessage})}})})server.listen(3000, () => {console.log(`Server is running at http://localhost:3000`)})
后台管理项目总结:
- 用await 的实现方式让代码看起来可阅读性更好了
- loading 的关闭只用写一次了
el-upload 中上传限制部分代码 ```javascript beforeAvatarUpload (file: any) {
const isJPG = file.type === 'image/jpeg'const isLt2M = file.size / 1024 / 1024 < this.limitif (!isJPG) {this.$message.error('上传头像图片只能是 JPG 格式!')}if (!isLt2M) {this.$message.error(`上传头像图片大小不能超过 ${this.limit}MB!`)}return isJPG && isLt2M
},
```
- 阿里云上传
- 没什么难点,就是根据文档,进行API编写和调用
- 而且这个接口是后端实现的,前端需要按照后端的规则进行调用
- new FormData()
- FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去。 —— MDN
- (this.$refs[‘menu-tree’] as Tree) 这中写法
- 在async 中请求没有先后顺序的数据
- const ret = await Promise.all([getAllResources(), getResourceCategories()])
