黑马头条项目-Vue-day10-小智同学聊天功能,退出功能的实现,websocket用法,白名单,关于nextTick()方法
个人中心
组件基本布局
目标:实现个人中心组件基本布局
- 组件模板
<div class="user-profile"><div class="info"><van-image round src="https://img.yzcdn.cn/vant/cat.jpeg" /><h3 class="name">用户名<br /><van-tag size="mini">申请认证</van-tag></h3></div><van-row><van-col span="8"><p>0</p><p>动态</p></van-col><van-col span="8"><p>0</p><p>关注</p></van-col><van-col span="8"><p>0</p><p>粉丝</p></van-col></van-row>
</div>
<van-row class="user-links"><van-col span="8"><van-icon name="newspaper-o" color="#7af"/>我的作品</van-col><van-col span="8"><van-icon name="star-o" color="#f00"/>我的收藏</van-col><van-col span="8"><van-icon name="tosend" color="#fa0"/>阅读历史</van-col>
</van-row><van-cell-group class="user-group"><van-cell icon="edit" title="编辑资料" to="/user/profile" is-link /><van-cell icon="chat-o" title="小智同学" to="/user/chat" is-link /><van-cell icon="setting-o" title="系统设置" is-link /><van-cell icon="warning-o" title="退出登录" is-link />
</van-cell-group>
- 布局样式
.user {&-profile {width: 100%;height: 300px;display: block;background: #3296fa;color: #fff;.info {display: flex;padding: 20px;align-items: center;.van-image {width: 128px;height: 128px;}.name {font-size: 32px;font-weight: normal;margin-left: 20px;}.van-tag {background: #fff;color: #3296fa;}}p {margin: 0;text-align: center;}}&-group {margin-bottom: 30px;}&-links {padding: 30px 0;font-size: 12px;text-align: center;background-color: #fff;.van-icon {display: block;font-size: 48px;padding-bottom: 10px;}}
}
总结:切图(工作量)
用户信息动态渲染
目标:实现用户信息的动态渲染
- 封装用户信息接口调用方法
export const getUserInfo = () => {return request({method: 'get',url: 'v1_0/user'})
}
- 获取用户个人信息
import { getUserInfo } from '@/api/my.js'
export default {name: 'User',data () {return {info: null}},methods: {async getUserInfo () {// 调用接口获取用户信息const ret = await getUserInfo()this.info = ret.data}},created () {this.getUserInfo()}
}
- 组件的动态渲染
<div class="user-profile"><div class="info"><van-image round :src="info.photo" /><h3 class="name">{{info.name}}<br /><van-tag size="mini">申请认证</van-tag></h3></div><van-row><van-col span="6"><p>{{user.art_count}}</p><p>动态</p></van-col><van-col span="6"><p>{{user.follow_count}}</p><p>关注</p></van-col><van-col span="6"><p>{{user.fans_count}}</p><p>粉丝</p></van-col><van-col span="6"><p>{{user.like_count}}</p><p>被赞</p></van-col></van-row>
</div>
总结:调用接口;获取数据;填充页面
退出功能
目标:实现退出功能
- 事件绑定
<van-cell @click="logout()" icon="warning-o" title="退出登录" is-link />
- 功能实现
// 退出功能
this.$dialog.confirm({title: '退出',message: '真的得退出吗?'
}).then(() => {// 实现退出功能:删除token,跳转到登录页面sessionStorage.removeItem('mytoken')this.$router.push('/login')}).catch(() => {// on cancelconsole.log('取消')})
},
总结:
- 像删除、退出等类似操作一般都要确认
- 基于token的退出,可能需要调用接口,也可能仅仅需要删除token即可。
小智同学-基本布局
目标:实现聊天功能基本布局
- 基本布局
<div class="container"><van-nav-bar fixed left-arrow @click-left="$router.back()" title="小智同学"></van-nav-bar><div class="chat-list"><div class="chat-item left"><van-image fit="cover" round src="https://img.yzcdn.cn/vant/cat.jpeg" /><div class="chat-pao">ewqewq</div></div><div class="chat-item right"><div class="chat-pao">ewqewq</div><van-image fit="cover" round src="https://img.yzcdn.cn/vant/cat.jpeg" /></div></div><div class="reply-container van-hairline--top"><van-field v-model="value" placeholder="说点什么..."><span @click="send()" slot="button" style="font-size:12px;color:#999">提交</span></van-field></div>
</div>
- 布局样式
.container {height: 100%;width: 100%;position: absolute;left: 0;top: 0;box-sizing: border-box;background:#fafafa;padding: 92px 0 100px 0;.chat-list {height: 100%;overflow-y: scroll;.chat-item{padding: 20px;.van-image{vertical-align: top;width: 80px;height: 80px;}.chat-pao{vertical-align: top;display: inline-block;min-width: 80px;max-width: 70%;min-height: 80px;line-height: 76px;border: 0.5px solid #c2d9ea;border-radius: 8px;position: relative;padding: 0 20px;background-color: #e0effb;word-break: break-all;font-size: 28px;color: #333;&::before{content: "";width: 20px;height: 20px;position: absolute;top: 24px;border-top:0.5px solid #c2d9ea;border-right:0.5px solid #c2d9ea;background: #e0effb;}}}}
}
.chat-item.right{text-align: right;.chat-pao{margin-left: 0;margin-right: 30px;&::before{right: -12px;transform: rotate(45deg);}}
}
.chat-item.left{text-align: left;.chat-pao{margin-left: 30px;margin-right: 0;&::before{left: -10px;transform: rotate(-135deg);}}
}
.reply-container {position: fixed;left: 0;bottom: 0;height: 88px;width: 100%;background: #f5f5f5;z-index: 9999;
}
- 状态数据
export default {data () {return {value: ''}},methods: {send () {}}
}
总结:
- 聊天组件路由配置
- 实现基本的布局效果
websocket介绍
目标:熟悉websocket通信规则
- http通信流程
- 建立连接(三次握手)
- 发送接收数据
- 断开连接(四次挥手)
- websocket通信流程(双向的:客户端可以向服务器发送消息,服务器也可以主动向客户端发送消息)
- 首次发送请求时,需要建立连接
- 后续收发消息就不再需要建立连接
- 长时间没有数据交互会自动断开连接(也可以手动断开连接)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N5JA7f2x-1623913719462)(imgs/image-20210131195932810.png)]
结论:websocket做双向通信更加高效(比如聊天功能,推送服务)
websocket基本使用
目标:熟悉websocket基本用法
浏览器为 HTTP 通信提供了 XMLHttpRequest 对象,同样的,也为 WebSocket 通信提供了一个操作接口:WebSocket。(http https) === (ws wss)
- 基本通信流程
- 拨号(建立连接)
- 通话(双向通信)
- 结束通话(关闭连接)
// 创建连接(和服务器建立连接,回复你)
var ws = new WebSocket("wss://echo.websocket.org");// 连接成功
ws.onopen = function(evt) { console.log("Connection open ..."); // 发送消息ws.send("Hello WebSockets!");
};// 接受信息
ws.onmessage = function(evt) {// 服务回复消息console.log( "Received Message: " + evt.data);// 关闭连接ws.close();
};// 连接已经关闭
ws.onclose = function(evt) {console.log("Connection closed.");
};
websocket第三方包用法
目标:熟悉socket.io基本信息和用法
官方网站:https://socket.io/get-started/chat/
既支持服务器,也支持客户端
- 服务端代码(基于socket.io自己做)
/*websocket服务端作用:1、接收客户端发送的请求;2、向客户端返回数据
*/
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);// 监听跟路径
app.get('/', function(req, res){// 返回的结果是一个网页res.sendFile(__dirname + '/index.html');
});// 监听客户端的链接
io.on('connection', function(socket){// 监听客户端端开链接事件socket.on('disconnect', function(){console.log('user disconnected');});// 监听客户端发送消息的事件socket.on('chat message', function(msg){// 客户端发送的消息msg// emit方法的作用是向客户端返回消息// emit参数一表示客户端监听的接收消息的事件// emit参数二表示服务器返回给客户端的消息io.emit('chat message', msg);});
});http.listen(3000, function(){console.log('listening on *:3000');
});
- 客户端代码
<!doctype html>
<html><head><title>Socket.IO chat</title><meta charset="utf-8" > <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: .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><!-- 消息列表 --><ul id="messages"></ul><!-- 发送消息的表单 --><form action=""><input id="m" autocomplete="off" /><button>Send</button></form><!-- SocketIO 提供了一个客户端实现:socket.io.js --><script src="https://cdn.bootcdn.net/ajax/libs/socket.io/3.0.0-rc4/socket.io.min.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script><script><script>// 建立连接,得到 socket 通信对象var socket = io('ws://localhost:3000/')socket.on('connect', () => {console.log('建立连接成功了')})$('form').submit(function(e){e.preventDefault();// 向服务器发送消息// chat message事件名称与谁有关?服务器的事件监听有关socket.emit('chat message', $('#m').val());$('#m').val('');return false;});// 客户端监听服务器返回消息的事件socket.on('chat message', function(msg){// msg表示服务器返回的消息,通过jQuery把消息添加到页面$('#messages').append($('<li>').text(msg));});</script></body>
</html>
总结:我们关注的是客户端代码。
- 发消息:
socket.emit('chat message', '内容');
- 收消息:
socket.on('chat message', function(msg){}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JuHUwdzc-1623913719466)(imgs/image-20210616103412907.png)]
小智同学聊天功能
目标:实现小智同学聊天功能
- 小智头像
import xzAvatar from '@/assets/xz.png'
// data中数据
xzAvatar: xzAvatar
<van-image fit="cover" round :src="xzAvatar" />
- 自己的头像
<van-image fit="cover" round :src="photo" />
总结:图片也可以模块化导入
- 开始聊天
- 聊天记录
list: []
- 建立连接
// 直接导入图片的地址
import xzAvatar from '@/assets/xz.png'
// 服务器端使用socket.io包,客户端使用socket.io-client包
import { io } from 'socket.io-client'
export default {name: 'Chat',data () {return {// 小智的头像xzAvatar: xzAvatar,// 输入的聊天数据value: '',// 聊天记录list: [],// socket链接对象ws: null,// 我的头像photo: null}},methods: {// 初始化Socket链接initConnection () {// 初始化链接配置this.ws = io('ws://localhost:3000/')// 监听链接成功的动作this.ws.on('connect', () => {// 链接成功后,向服务器发送一条消息// 1、把消息添加到页面const info = {name: this.name,msg: '你好'}this.list.push(info)// 2、把消息发送给后端this.ws.emit('chat message', info)})// 监听服务器返回的消息this.ws.on('chat message', (info) => {this.list.push({name: 'xz',msg: info.msg})})}},created () {// 初始化websocket链接this.initConnection()}
}
- 渲染记录
<div class="chat-item" :class='[{left: item.name==="xz"}, {right: item.name === name}]' v-for='(item,index) in list' :key='index'><van-image fit="cover" v-if='item.name==="xz"' round :src="xzAvatar" /><div class="chat-pao">{{item.msg}}</div><van-image fit="cover" v-if='item.name===name' round :src="photo" />
</div>
- 发送消息
methods: {// 向服务器发送消息send () {// 1、把消息内容添加到页面列表中const info = {name: this.name,msg: this.value}this.list.push(info)// 2、把消息发送给服务器this.ws.emit('chat message', info)// 清空表单this.value = ''}
},
- 接收消息
// 监听服务器返回的消息
this.ws.on('chat message', (info) => {this.list.push({name: 'xz',msg: info.msg})
})
- 关闭链接
destroyed () {this.socket.close()
}
总结:
- 安装依赖包
- 导入依赖包
- 收发消息
- 初始化链接时发送问候消息
- 监听返回的消息
- 手动触发发送消息动作
- 断开连接
组件缓存
目标:熟悉组件缓存的概念
默认情况:显示组件时,组件内容是重新渲染(created生命周期函数是否会再次调用?会的)
动态路由本身有组件的缓存机制(动态路由组件是否会重新渲染?不会)
path: ‘/students/:id’ component: Student
to=’/students/123’
to=’/students/456’
解决方案:侦听器监听 $route
注意:如果组件被缓存,那么组件的生命周期 created 仅仅触发一次
- 如果给组件包裹一层 keep-alive标签,那么组件的实例对象会被缓存,普通的生命周期(比如created)不会再次触发。
- 这样做的优点:提高页面打开的效率;缺点:内存开销(占用)较大
- 缓存的效果:保持组件当前的状态
<keep-alive><router-view/>
</keep-alive>
- 组件缓存相关的生命周期
export default {name: 'Tom',data () {return {active: 1}},activated () {// 被缓存的组件再次显示时触发console.log('activated')this.active = 1},deactivated () {// 离开缓存组件时触发console.log('deactivated')},created () {console.log('tom')}
}
</script>
总结:熟悉缓存相关的两个组件的生命周期函数的触发条件
- 项目中进行组件的按需缓存
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OPctj8ea-1623913719467)(imgs/image-20210202100025914.png)]
总结:
- 配置路由映射时,添加meta字段,里面添加标志位,用于区分是否缓存
- 配置路由填充位时,基于上述标志位作为缓存的条件
白名单效果
需求:有一些组件(白名单),不登录也可以访问到
- 在路由映射中meta值中添加标志位
{ path: 'main', component: Main, meta: { keepAlive: true, auth: true } },
- 导航守卫中验证标志位
if (to.meta.auth) {// 如果条件成立,不需要做权限验证,可以直接访问对应的路由组件return next()
}
总结:基于路由映射的meta配置实现白名单效果。
关于nextTick()方法
目标:熟悉nextTick方法的应用场景
- Vue.nextTick()
- this.$nextTick()
<template><div><div>Jerry</div><hr><div>{{msg}}</div><div><input ref='myinput' type="text" v-model='msg'><button @click='handleClick'>点击</button></div></div>
</template>
<script>
export default {name: 'Jerry',data () {return {msg: 'hello'}},methods: {handleClick () {// 渲染数据的策略:不是修改一次数据就更新一次页面// 这些数据的更新会先添加到一个队列中,然后下次渲染时会把队列中内容一次性更新到页面中// 这样做主要用于提高性能this.msg = 'nihao'this.msg = 'hi'this.msg = 'abc'// 修改完成数据后直接就可以得到最新的数据console.log(this.msg)// 采用这种方式获取的结果依然是原始的值// 数据的变化导致页面的更新过程是异步的// console.log(this.$refs.myinput.value)// --------------------------------------// window.setTimeout(() => {// // 这样就会得到渲染后的结果// console.log(this.$refs.myinput.value)// }, 0)// --------------------------------------// 保证当前队列里面的数据更新已经被渲染到了页面,此时可以获取DOM最新数据this.$nextTick(() => {// 这样就会得到渲染后的结果console.log(this.$refs.myinput.value)// this.$refs.myinput.focus()})// 如果不是有回调,可以使用promise方式处理this.$nextTick().then(() => {console.log(this.$refs.myinput.value)})}}
}
</script>
总结:
- 数据更新后,页面不是立刻更新的,需要时间(异步的)
- 通过$nextTick可以获取DOM更新后的数据
- 针对data中数据的操作,不是理解生效,而是把操作的流程放到队列中,特定时间内自动清空队列把此时的数据一次性更新到页面中。如果同一个属性被多次赋值,那么只有最后一次有效。
- 每次把队里中的数据更新到页面的过程称之为一个Tick
- $nextTick支持Promise的用法
this.info = 'nihao'
this.$nextTick().then(() => {console.log('==================' + this.$refs.myinfo.value)this.info = 'hi'// return this.$nextTick()
}).then(() => {console.log('------------------' + this.$refs.myinfo.value)
})
总结,如果使用Promise用法,那么不可以使用回调方式。
更新已经被渲染到了页面,此时可以获取DOM最新数据
this.KaTeX parse error: Expected '}', got 'EOF' at end of input: …nsole.log(this.refs.myinput.value)
// this.KaTeX parse error: Expected 'EOF', got '}' at position 28: ….focus() }̲) // 如果不是…nextTick().then(() => {
console.log(this.$refs.myinput.value)
})
}
}
}
> 总结:
>
> 1. 数据更新后,页面不是立刻更新的,需要时间(异步的)
> 2. 通过$nextTick可以获取DOM更新后的数据
> 3. 针对data中数据的操作,不是理解生效,而是把操作的流程放到队列中,特定时间内自动清空队列把此时的数据一次性更新到页面中。如果同一个属性被多次赋值,那么只有最后一次有效。
> 4. 每次把队里中的数据更新到页面的过程称之为一个Tick- $nextTick支持Promise的用法```js
this.info = 'nihao'
this.$nextTick().then(() => {console.log('==================' + this.$refs.myinfo.value)this.info = 'hi'// return this.$nextTick()
}).then(() => {console.log('------------------' + this.$refs.myinfo.value)
})
总结,如果使用Promise用法,那么不可以使用回调方式。
黑马头条项目-Vue-day10-小智同学聊天功能,退出功能的实现,websocket用法,白名单,关于nextTick()方法相关推荐
- 前端基础第四天项目 社交媒体黑马头条项目-登录注册和个人中心
一.项目初始化 目标 能使用 Vue CLI 创建项目 了解 Vant 组件库的导入方式 掌握制作使用字体图标的方式 掌握如何在 Vue 项目中处理 REM 适配 理解 axios 请求模块的封装 使 ...
- 11-vue移动端项目(小智机器人聊天使用websocket协议使用socket.io客户端第三方包, 让div滚动条自动滚到最底部)
小智同学 01 - 创建组件 创建组件 & 创建路由 设置入口 02 - 完成静态页面 头部标题 聊天区域 设置内容高度时会出现一个问题: 由于不同的手机型号的高度是不一样的,但是聊天区域的高 ...
- 黑马头条项目 一 项目设计及基础搭建
黑马头条项目之项目设计及基础搭建 一.概述 工程基于Spring-boot 2.1.5.RELEASE 版本构建,工程父项目为heima-leadnews,并通过继承方式集成Spring-boot. ...
- 前端基础第五天项目 社交媒体黑马头条项目-文章模块和评论
七.文章详情 创建组件并配置路由 1.创建 views/article/index.vue 组件 <template><div class="article-contain ...
- 新黑马头条项目经验(黑马)
swagger (1)简介 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务(API Documentation & Design ...
- 软件测试项目实战32讲,软件测试入门-黑马头条项目实战
课程简介 本课程以黑马头条实战项目为例,将项目的整个测试流程做了详细的介绍,并带着大家一起进行产品需求评审,项目测试计划编写,测试需求分析,以及测试用例的设计编写和执行操作,通过完成实际的功能业务测试 ...
- 黑马头条项目 JWT—4.3 头条项目实施方案(生成token接口测试)
头条项目实施方案 需求 设置有效期,但有效期不宜过长,需要刷新. 如何解决刷新问题? 手机号+验证码(或帐号+密码)验证后颁发接口调用token与refresh_token(刷新token) Toke ...
- 黑马头条项目-Vue-day9-文章详情模块、关注与取消关注,点赞和喜欢功能
文章详情模块 配置文章详情路由 目标:配置文章详情组件路由 路由配置 import Detail from '@/views/detail/index.vue' { path: '/detail', ...
- 【愚公系列】2022年10月 微信小程序-电商项目-微信支付小程序确认支付结果和退款功能实现(node)
文章目录 前言 一.微信支付小程序确认支付结果和退款功能实现 1.确认支付结果 2.退款功能实现 前言 微信小程序在支付成功后会给注册的接口发消息来通知订单支付成功的状态,下面是微信和接口通信的数据格 ...
- Vuex——黑马头条项目(vuex体验版)
1.搭建项目 1.1通过vue-cli脚手架搭建项目:vue create toutiao (选择 vuex/eslint(standard)/pre-cssprocesser(less)) 1.2在 ...
最新文章
- Oracle技术之和分区表相关的一点总结(三)
- OpenGL starfield星空的实例
- js最简单数组去重_js简单数组去重
- git的使用1[转]
- 在Java里重写equals和hashCode要注意什么问题
- iphone字体_iPhone 适合老人盘吗?
- PHP 使用concat的无限分类
- centos 7 安装kvm 虚拟机
- 【C++】 12_经典问题解析 一
- 用quartus搭建soc-串口发送学号完整流程(软件+硬件)
- flutter ios上踩的一个坑
- linux 0.11 内核学习 -- sched.c,调度进程。
- 批量word转pdf——VBS脚本,在office宏中运行即可
- apache连接mysql配置_Apache+PHP配置及连接mysql数据库
- word简历排版技巧
- 京东话费充值,点击出现的css样式
- Python非线性拟合笔记
- 电脑硬件知识入门之内存篇
- 绝对干货!初学者也能看懂的DPDK解析
- CF小组训练赛 Holiday 19
热门文章
- 基于PythonGUI的原神圣遗物游戏装备管理与角色数值模拟系统
- {黑掉这个盒子} \\ FluxCapacitor Write-Up
- 7-33 电话聊天狂人 (25 分)(map水题)
- mysql的group by语句不会产生_MySQL:为什么查询列表中多了它,GROUP BY语句就会报错呢?...
- 【mud】xyj450里的toy下的buwawa脚本问题
- 计算机主机usb端口使用不了,解答电脑usb接口不能用怎么解决
- 石河子市谷歌高清卫星地图下载
- 最新个人发卡网系统源码-全开源版
- tic tac toe php,Python函数找出tic tac toe获胜者
- 如何用阿里云云盘快照恢复部分数据