#一、web项目的导入与导出
###1、导出,
保存方法如下
1、找到自己项目所在文件夹,如C盘用户目录或者D盘projects目录内部的helloworld
2、删除helloworld内部的node_modules
3、压缩工具压缩helloworld项目,拷贝到自己的网盘或者微信qq
###2、导入
把自己的项目用idea打开,并更新好项目所需要的类库
具体操作如下:
1、打开终端,输入 npm install -g @vue/cli (此处是安装脚手架工具,只针对学校电脑,自己电脑无需操作)。
2、解压自己的helloworld项目到D盘projects目录,
3、用idea 选择File---Open 打开helloworld项目
4、在Idea的终端输入 npm install 进行项目所需第三方库下载,下载完成后会在本项目内生成node_modules目录。
#二、复习
上周分别进行了以下内容的学习
1、行业与岗位、薪资与技术要求;实训基本安排,微信网页聊天程序的展示
2、JAVASE的复习,封装、继承、多态、匿名内部类、多线程的复习,飞翔的小鸟游戏制作。
3、前端技术的复习,Html、CSS、JS、Jquery的复习,登录页面的制作。
4、前端环境搭建与技术学习:Nodejs安装与配置,vue脚手架安装与项目创建,微信登录页面的制作。
上一天的知识点的复习
vue是渐进式前端框架,vue/cli是vue的脚手架工具,用vue create命令可以快速搭建一个vue项目
vue项目的package.json是项目的描述性文件,包含一些测试运行项目的脚本,以及第三方依赖的列表
vue项目的main.js是入口文件,内部创建了vue的全局对象。并将主组件App.vue渲染到public的index.html页面中
App.vue是vue项目的主组件,
vue组件的结构
template scripts style三个部分。
ant-design-vue是基于vue的框架,有很多写好的标签直接搭建页面。
Ant-design-vue框架的标签
a-form a-input a-button a-icon
form表单的验证,
第一步给 a-form添加动态属性 :form="form"
第二步,在组件的生命周期钩子函数中给this.form赋值,
beforeCreate() {
this.form = this.$form.createForm(this, {});
},
第三步:给要添加验证的标签添加v-decorator属性,属性内部写规则,
第四步:给表单登录按钮添加点击事件,在事件函数中调用this.form.validateFields(function(err){});
这里提到组件的生命周期钩子函数,可以简单理解为vue在创建运行这个组件的时候调用的一些列函数,钩子函数有5个,本次只用到beforeCreate代表组件创建前自动调用该函数。
#三、本周的计划
1、微信聊天界面的制作
2、前端网页路由跳转,前端异步请求 axios
3、springboot搭建后端项目
4、登录与聊天前后台逻辑实现。
#四、微信聊天界面的实现
此处用到的依然是ant-design-vue框架(简称antd vue)
主要有以下几个标签完成
a-layout
a-menu 与 a-menu-item
a-list 与 a-list-item
a-col
a-tooltip
以及组件属性相关的知识 。
五、开始开发
###1、新建Index.vue
在src目录新建一个Vue组件,命名Index.vue
选中src---new---vue components ----Index
并在template中键入以下内容
<template>
<div>
聊天界面
</div>
</template>
###2、切换根组件,方便测试
目前项目中App是登录页面,同时App.vue还是根组件,vue项目中根组件只有一个,在没有学到新知识之前,我们是不能切换页面的。我们需要将根组件换成Index.vue才可以显示出页面内容,
做法如下
在main.js中删除原来的App.vue的导入语句,新增Index.vue的导入
删除import App from './App.vue'
新增import Index from './Index.vue'
将Index.vue映射到public 的首页中去,将全局Vue对象参数中h函数参数改为Index
new Vue({
render: h => h(Index),
}).$mount('#app')
###3、说明:建议将现有的App.vue页面重命名为Login.vue,起到见名知意的作用,
重命名方式:选中App.vue---右键---refactor---rename---Login.vue
打开Login.vue 找到scripts代码,修改name的值为Login
之后学习路由知识之后,我们会重新建立一个App.vue,并会将登录页面和聊天界面做路由处理,可以进行页面切换,显示到根组件App上,
#六、编写Index页面
###1、用layout和layout-sider布局整个页面,含左侧菜单和右侧内容区。
<template>
<div>
<a-layout>
<a-layout-sider>
</a-layout-sider>
<a-layout-content>
</a-layout-content>
</a-layout>
</div>
</template>
###2、在sider区添加menu菜单,
<template>
<div>
<a-layout>
<a-layout-sider>
.................键入部分...................................
<a-layout>
<a-layout-header>
<a-menu theme="dark" mode="horizontal" >
<a-menu-item>
最近
</a-menu-item>
<a-menu-item>
通讯录
</a-menu-item>
<a-menu-item>
我的
</a-menu-item>
</a-menu>
</a-layout-header>
<a-layout-content>
这里显示最近聊天列表
</a-layout-content>
</a-layout>
.................键入部分...................................
</a-layout-sider>
<a-layout-content>
</a-layout-content>
</a-layout>
</div>
</template>
###3、给菜单设置主题和显示方式
<a-menu theme="dark" mode="horizontal">
设置完成以后,菜单变为黑色,选中的选项变为蓝色,显示方式为水平,这时“我的”由于sider的宽度不够,导致隐藏,可以设置sider的宽度与父layout宽度的百分,如40%
###4、设置右侧内容区
页面中根layout中的a-layout-content标签为右侧聊天内容区,我们在里面继续布局,上中下结构,代码如下:
<a-layout-content>
--------------键入内容---------------------------
<a-layout>
<a-layout-header></a-layout-header>
<a-layout-content></a-layout-content>
<a-layout-footer></a-layout-footer>
</a-layout>
--------------键入内容---------------------------
</a-layout-content>
此时页面的结构基本清晰,左侧为操作区,右侧为聊天内容区,
###5、修饰
######1、全局
给template的根div添加show类选择器
<div class="show">
在style区定义,show类选择器
.show{
width:900px;
height:600px;
border:1px solid gray;
margin: auto;
margin-top:50px;
}
######2、右侧顶部
给右侧顶部修改背景,右侧顶部显示的是聊天人的名字
在右侧顶部的标签引用right-top类选择器,为了显示效果,给header标签添加测试内容
<a-layout-header class="right-top">
张三风
</a-layout-header>
在style区定义right-top类选择器
.right-top{
background-color: #e5e5e5;
text-align:center;
}
######3、右侧中间
右侧中间为显示聊天内容的地方,需要设定高度,保证这片区域的高度不随着内容的变化而变化
给标签添加right-center 类选择器
<a-layout-content class="right-center">
在style区定义类选择器
.right-center{
border-top:1px solid snow;
background-color:#e5e5e5;
min-height: 450px;
}
#七、内容编写:显示菜单内容区数据
微信网页聊天的左侧菜单内容区(a-layout-content),是最近聊天,通讯录,和我的之间切换的面板,目前我们先不做切换,只做最近聊天的内容,后续学习了路由以后再来添加通讯录和我的的面板
内容区是一个列表,显示了最近的聊天的人,每行是一个头像,聊天人的名字和最新的聊天记录,
a-list是AndV的常用标签,用于以列表的形式显示数据,如法结构如下
<a-list :dataSource="数据源">
<a-list-item slot="renderItem" slot-scope="item,index">
</a-list-item>
</a-list>
其中dataSource是动态数据,来自于vue组件的属性值,
其中a-list-item被slot=“renderItem”修饰,代表集合每个元素,
sloat-scope中item是每个元素的变量名,index是每个元素的角标顺序,
拓展:在之前我们在a-input标签中见过slot,
<a-input>
<a-icon slot="prefix">
</a-input>
当时的解释是,input标签有一个属性,叫prefix,代表输入框的前缀图标,prefix相当于一个插槽,他的值是一个真正的图标标签,因此给这个标签添加slot=“prefix”,这样就把图标作为一个楔子插到了input的插槽中。
同理,这里也是,a-list标签有一个属性,叫renderItem,代表每个元素,renderItem相当于一个插槽,他的值
是一个list-item,因此给list-item添加slot="renderItem"作为一个楔子插到list的插槽中,这个list-item就是每个元素了。
接下来给菜单内容区添加内容,代码如下
第一步:在vue组件的script代码中添加数据部分,用于准备list的测试数据。
vue组件中可以定义很多数据,数据以data(){return {} }的形式表示,即,将数据放在return中以json的形式表示。
在script代码中写入以下内容
<script>
export default {
name: "Index",
.........................键入内容(注意包含上一行的逗号)...................
data(){
return {
}
}
.........................键入内容...................
}
</script>
第二步:定义lastChat数组,并制作一些假数据,表示最近的聊天的人的记录
<script>
export default {
name: "Index",
data(){
return {
.........................键入内容...................
lastChat:[
{nickName:"张三",msg:"你吃饭了吗",time:"刚刚"},
{nickName:"李四",msg:"亲爱的,你吃饭了吗",time:"刚刚"},
],
.........................键入内容...................
}
}
}
</script>
第三步:在template中菜单聊天区的content中添加list标签
<template>
<div class="show">
<a-layout >
<a-layout-sider width="40%">
<a-layout>
<a-layout-header>
<a-menu theme="dark" mode="horizontal" >
<a-menu-item>
最近
</a-menu-item>
<a-menu-item>
通讯录
</a-menu-item>
<a-menu-item>
我的
</a-menu-item>
</a-menu>
</a-layout-header>
<a-layout-content>
.........................键入内容...................
<a-list :dataSource="lastChat">
<a-list-item slot="renderItem" slot-scope="item,index">
</a-list-item>
</a-list>
.........................键入内容...................
</a-layout-content>
</a-layout>
</a-layout-sider>
<a-layout-content >
<a-layout>
<a-layout-header class="right-top">
张三丰
</a-layout-header>
<a-layout-content class="right-center">
</a-layout-content>
<a-layout-footer></a-layout-footer>
</a-layout>
</a-layout-content>
</a-layout>
</div>
</template>
第四步:显示列表的测试数据。
这里我们用到 a-row a-col,And常用的栅格,row代表一个行,col代表行中的列,一个行有24列,可以用col的span方便的将行拆分成n列。
例如把一个行按3:4:13:4的比例拆分成4行,分别表示头像位置,名字位置,最近聊天内容位置,时间位置
在list-item中添加以下内容
<a-list :dataSource="lastChat">
<a-list-item slot="renderItem" slot-scope="item,index">
.........................键入内容...................
<a-col :span="3">
</a-col>
<a-col :span="4">
</a-col>
<a-col :span="13" >
</a-col>
<a-col :span="4">
</a-col>
.........................键入内容...................
</a-list-item>
</a-list>
(这里我们并没有用a-row标签,经测试a-row有自己的边距样式,添加以后还需要调整样式,因此略掉了)
第五步:显示每行的头像,名字,最近聊天和时间
<a-col :span="2">
<a-avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"/>
</a-col>
<a-col :span="4">
{{item.nickName}}}
</a-col>
<a-col :span="14" >
{{item.msg}}
</a-col>
<a-col :span="4">
{{item.time}}
</a-col>
其中头像是从网上找的一个头像,名字,消息,时间均来自数据集合,用{{}}获取。
#八、内容编写:显示聊天内容区顶部数据
此处编辑的是整个面板中右侧顶部位置的数据,即显示对方的名字的地方
第一步:构建测试数据
在script的data中添加聊天人的数据 friendNickName
<script>
export default {
name: "Index",
data(){
return {
lastChat:[
{nickName:"张三",msg:"你吃饭了吗",time:"刚刚"},
{nickName:"李四",msg:"亲爱的,你吃饭了吗",time:"刚刚"},
],
........................键入内容...................
friendNickName:"张三丰",
.........................键入内容...................
}
}
}
</script>
第二步:替换header中的数据
原来的是张三丰的字,现在改为 {{friendNickName}}
<a-layout-content >
<a-layout>
<a-layout-header class="right-top">
........................键入内容...................
{{friendNickName}}
........................键入内容...................
</a-layout-header>
<a-layout-content class="right-center">
</a-layout-content>
<a-layout-footer></a-layout-footer>
</a-layout>
</a-layout-content>
#九、内容编写:显示聊天内容区中部数据
此处编辑的是整个面板中右侧中间位置的数据
依然用到的是a-list此处不再赘述,直接写代码
第一步:构建聊天测试数据
在script代码中添加和张三丰聊天的测试数据,数据是一个json类型数组,每个json包含头像,聊天消息内容。另外还需要构建一个用户ID作为己方聊天人的ID,因为对方聊天信息在左侧,己方聊天信息在右侧。
<script>
export default {
name: "Index",
data(){
return {
lastChat:[
{nickName:"张三",msg:"你吃饭了吗",time:"刚刚"},
{nickName:"李四",msg:"亲爱的,你吃饭了吗",time:"刚刚"},
],
friendNickName:"张三",
........................键入内容...................
userId:1,
records:[
{userId:2,msg:"你吃饭了吗"},
{userId:1,msg:"正想吃啥呢,你有啥建议吗"},
{userId:2,msg:"走,跟我去吃吧,我吃啥你吃啥"},
{userId:1,msg:"正有此意,肘!"},
],
........................键入内容...................
}
}
}
</script>
第二步:在聊天区的标签中用list标签
在right-center中添加以下内容
<a-layout-content class="right-center">
........................键入内容...................
<a-list :dataSource="records">
<a-list-item slot="renderItem" slot-scope="item">
<a-tooltip placement="right" visible=true>
<span slot="title">{{ item.msg }}</span>
<a-avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"/>
</a-tooltip>
</a-list-item>
</a-list>
........................键入内容...................
</a-layout-content>
这里用用到tooltip标签,这是一个冒泡,泡是在头像右侧(placement=right)长久显示(visible=tue)的,内容是一个span,作为楔子插入到titile插槽中。
第三步:当是自己的消息的时候,消息显示在头像左侧
将placement属性改为动态获取,根据userID的判断来选择到底是左还是右
<a-tooltip :placement="item.userId==userId? 'left' : 'right'" visible=true>
刷新页面查看效果,发现消息虽然在头像左侧,但是头像还在界面左侧,我们需要将头像移动到界面右侧。这里运用到一个css的浮动特性,直接在父标签添加justifyContent=flex-end即可。但需要动态添加
给tooltip的父标签list-item添加 style样式,修改后的代码如下
<a-list-item slot="renderItem"
slot-scope="item"
:style="{justifyContent:(item.userId == userId ? 'flex-end' : '')}" >
注意在标签的结束符号”>“前中间添加
#十、内容编写:显示聊天内容区底部表单
<a-layout-footer>
<a-textarea placeholder="在这里输入信息" />
<a-button >发送</a-button>
</a-layout-footer>
给footer添加类选择器修饰样式
<a-layout-footer class="right-footer">
在style代码中添加样式
.right-footer{
padding:0px;
text-align: right;
}
#十一、完整代码如下
<template>
<div class="show">
<a-layout >
<a-layout-sider width="40%">
<a-layout>
<a-layout-header>
<a-menu theme="dark" mode="horizontal" >
<a-menu-item>
最近
</a-menu-item>
<a-menu-item>
通讯录
</a-menu-item>
<a-menu-item>
我的
</a-menu-item>
</a-menu>
</a-layout-header>
<a-layout-content>
<a-list :dataSource="lastChat">
<a-list-item slot="renderItem" slot-scope="item">
<a-col :span="3">
<a-avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"/>
</a-col>
<a-col :span="4">
{{item.nickName}}
</a-col>
<a-col :span="13" >
{{item.msg}}
</a-col>
<a-col :span="4">
{{item.time}}
</a-col>
</a-list-item>
</a-list>
</a-layout-content>
</a-layout>
</a-layout-sider>
<a-layout-content >
<a-layout>
<a-layout-header class="right-top">
{{friendNickName}}
</a-layout-header>
<a-layout-content class="right-center">
<a-list :dataSource="records">
<a-list-item slot="renderItem"
slot-scope="item"
:style="{justifyContent:(item.userId == userId ? 'flex-end' : '')}"
>
<a-tooltip :placement="item.userId==userId? 'left' : 'right'" visible=true>
<span slot="title">{{ item.msg }}</span>
<a-avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"/>
</a-tooltip>
</a-list-item>
</a-list>
</a-layout-content>
<a-layout-footer class="right-footer">
<a-textarea placeholder="在这里输入信息" />
<a-button >发送</a-button>
</a-layout-footer>
</a-layout>
</a-layout-content>
</a-layout>
</div>
</template>
<script>
export default {
name: "Index",
data(){
return {
lastChat:[
{nickName:"张三",msg:"你吃饭了吗",time:"刚刚"},
{nickName:"李四",msg:"亲爱的,你吃饭了吗",time:"刚刚"},
],
friendNickName:"张三",
userId:1,
records:[
{userId:2,msg:"你吃饭了吗"},
{userId:1,msg:"正想吃啥呢,你有啥建议吗"},
{userId:2,msg:"走,跟我去吃吧,我吃啥你吃啥"},
{userId:1,msg:"正有此意,肘!"},
],
}
}
}
</script>
<style scoped>
.show{
width:900px;
height:600px;
border:1px solid gray;
margin: auto;
margin-top:50px;
}
.right-top{
background-color: #e5e5e5;
text-align:center;
}
.right-center{
border-top:1px solid snow;
background-color:#e5e5e5;
height: 450px;
}
.right-footer{
padding:0px;
text-align: right;
}
</style>