【一】动态组件
【1】基本使用
- 比如:
<one :is="type"></one>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js2/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<!-- 三个按钮-->
<button @click="type='home'">首页</button>
<button @click="type='goods'">商品页</button>
<button @click="type='order'">订单页</button>
</div>
<!-- 方法一:判断-->
<!-- 这里的为什么要用==应为是比较,不可以用=-->
<!-- <home v-if="type=='home'"></home>-->
<!-- <goods v-else-if="type=='goods'"></goods>-->
<!-- <order v-else></order>-->
<!-- 方法二-->
<!-- 这个标签随便起名字,因为is绑定了属性-->
<one :is="type"></one>
</div>
</body>
<script>
// 全局组件
Vue.component("home", {
template: `<div>
<h1>首页</h1>
</div>`,
})
// 全局组件
Vue.component("goods", {
template: `<div>
<h1>商品页</h1>
</div>`,
})
// 全局组件
Vue.component("order", {
template: `<div>
<h1>订单页</h1>
</div>`,
})
var vm = new Vue({
el: "#app",
data: {
type: "home"
}
})
</script>
</html>
【2】keep-alive
keep-alive
可以让输入框内有的内容一致保持,不会因为切换而重置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js2/vue.js"></script>
</head>
<body>
<div id="app">
<div>
<!-- 三个按钮-->
<button @click="type='home'">首页</button>
<button @click="type='goods'">商品页</button>
<button @click="type='order'">订单页</button>
</div>
<!-- 方法一:判断-->
<!-- 这里的为什么要用==应为是比较,不可以用=-->
<keep-alive>
<home v-if="type=='home'"></home>
<goods v-else-if="type=='goods'"></goods>
<order v-else></order>
</keep-alive>
<!-- 方法二-->
<!-- <keep-alive>-->
<!-- <component :is="type"></component>-->
<!-- </keep-alive>-->
</div>
</body>
<script>
// 全局组件
Vue.component("home", {
template: `<div>
<h1>首页</h1>
</div>`,
})
Vue.component("goods", {
template: `<div>
<h1>商品页</h1>
</div>`,
})
Vue.component("order", {
template: `<div>
<h1>订单页</h1>
<input type="text">
</div>`,
})
var vm = new Vue({
el: "#app",
data: {
type: "home"
}
})
</script>
</html>
【二】插槽
【1】基本插槽
-
插槽:你写的全局组件,在body里面使用,然后你又在里面添加了标签
-
<home> <div> <img src="./img/1.png" alt=""> <img src="./img/2.png" alt=""> </div> </home>
-
-
<slot></slot>
:写在组件中的数据,都会被赋值并替换掉组件中得
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js2/vue.js"></script>
</head>
<body>
<div id="app">
<home>
<div>
<img src="./img/1.png" alt="">
<img src="./img/2.png" alt="">
</div>
</home>
</div>
</body>
<script>
Vue.component("home", {
template: `<div>
<h1>首页</h1>
<slot></slot>
</div>
`,
})
var vm=new Vue({
el:"#app",
data:{
}
})
</script>
</html>
【2】具名卡槽
- 就是有名的卡槽,指定使用的卡槽的位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js2/vue.js"></script>
</head>
<body>
<div id="app">
<home>
<div slot="two">
<img src="./img/3.png" alt="">
<img src="./img/4.png" alt="">
</div>
<div slot="one">
<img src="./img/1.png" alt="">
<img src="./img/2.png" alt="">
</div>
</home>
</div>
</body>
<script>
Vue.component("home", {
template: `<div>
<slot name="one"></slot>
<h1>首页</h1>
<slot name="two"></slot>
</div>
`,
})
var vm=new Vue({
el:"#app",
data:{
}
})
</script>
</html>
【三】Vue
的项目创建和运行
【1】前言
- 版本
- `vue2`:只能用`vue-cli`创建
- `vue3`:即可用`vue-cli`创建又可以用`vite`
- `vue-cli`:又称之为vue的脚手架。`vue-cli` 是一个官方提供的命令行工具,用于简化 `Vue.js` 项目的创建和管理。它提供了一些便捷的命令来生成新项目、配置开发环境、运行开发服务器、构建生产版本等。`vue-cli` 能够帮助你快速启动一个` Vue.js `项目,自动配置所需的工具和插件,使得开发过程更加高效
# 安装必须依赖于:nodejs的环境---》就好比django-admin
【2】安装nodejs
# 搭建node环境
-我们需要nodejs:20.16版本
- 下载安装包
- 下一部安装就可以
# 在cmd命令中检验
- 有两个命令
node:就是python
npm:就是pip
- npm换源
-npm 下载第三方包时,去国外下,速度很慢
-替换一下国内镜像站:阿里云源
-npm config set registry http://registry.npmmirror.com
-使用阿里云提供的cnpm替代npm:提示和显示更友好
-npm install -g cnpm --registry=https://registry.npmmirror.com
-以后用cnpm替代npm即可
- nodejs的包管理工具
npm、yarn、cnpm
安装 vue-cli--就能创建vue项目
# 去官网下载:npm install -g @vue/cli
-------我们要换成cnpm install -g @vue/cli
# 安装成功过后会释放出一个命令:vue命令
- 创建vue的项目
# 你需要将路径切换到你存储vue项目的路径
vue create 项目名
- 上下选择自定义设置
- 上下选择自定义设置
- 选择版本
- 选则下面那个即可
- 是否保存(保存到的话,下次你可以直接使用这个配置)
【3】运行vue项目
- 在terminal中
# 第一:切换到你的vue项目:cd 项目名字
# 第二:运行:npm run serve
- 在pycharm中:找到你创建的vue项目直接打开
# 上面运行的绿色按钮:
- 添加一个npm命令,脚本的地方写:serve
【四】vue项目目录的结构
# vue_demo001 项目名
-node_modules:黄色是被git管理了表示忽略文件--》当前项目的所有依赖--》如果没有项目运行不了
相当于python项目中有个文件夹 .venv
特别多小文件--》把项目发送给别人,这个文件夹删除
cnpm install #项目根路径下执行,就会重新创建出来,根据package.json安装
-public # 文件夹
-favicon.ico # 网页小图标
-index.html # vue:spa 单页面应用--》只有一个html页面--》不要动它
-src #文件夹 ,vue的核心代码,后期我们都在这里面写代码
-assets # 文件夹,放公共静态资源,js,css,图片
-logo.png # 静态图片
-components #文件夹 组件,以后小组件放在这个文件夹内【页面组件和小组件】
-HelloWorld.vue # 默认提供的小组件
-后期我们写的小组件放这里
-router #文件夹,第三方包,vue-routr的东西,后面会详细学 路由
-index.js # vue-router的代码
-store #文件夹,第三方包,vuex的东西,后面会详细学 状态管理器
-index.js # vuex的代码
-views # #文件夹 组件,以后页面组件放在这个文件夹内【页面组件和小组件】
-AboutView.vue # 关于页面
-HomeView.vue # 首页
-App.vue # 根组件
-main.js # vue项目的核心js文件,项目运行从他开始
-.gitignore # git管理软件的忽略文件--》后面会学git
-babel.config.js # babel的配置文件,不用动,vue支持最新es语法--》把新版本语法--转成es5语法
-jsconfig.json # 不用管
-package.json # 配置信息,项目依赖,后面会用axios,装完后,在里面就有
-package-lock.json# package锁定文件,锁定版本
-README.md # 项目描述文件
-vue.config.js # vue项目配置文件--》settings.py
# 补充:
svg图片:可以无限放大缩小
ico,png,jpg:图片文件,放大后看不清
# pycharm中删除的文件找回
-项目上点右键--》show history--——》revert回来即可
dist: 打包的项目目录(打包后会生成)
node_modules: 项目依赖(删掉,不上传git,使用npm install重新安装)
public: 共用资源
--favicon.ico
--index.html:项目入口页面,单页面
src: 项目目标,书写代码的地方
-- assets:资源
-- components:组件
-- views:视图组件
-- App.vue:根组件
-- main.js: 入口js
-- router.js: 路由文件
-- store.js: 状态库文件
vue.config.js: 项目配置文件(没有可以自己新建)
package.json:项目配置依赖(等同于python项目的reqirement.txt)
【五】vue的开发规范
【1】vue项目的执行流程
# 1 我们运行:npm run serve --》编译并运行项目
-xx.vue--->浏览器识别不了--》浏览器只能识别 html,css,js
-把vue项目--》编译--》编译成功纯粹的 html,css,js--》运行起来--》浏览器中访问xxxxxxxxxx # # 1 我们运行:npm run serve --》编译并运行项目 -xx.vue--->浏览器识别不了--》浏览器只能识别 html,css,js -把vue项目--》编译--》编译成功纯粹的 html,css,js--》运行起来--》浏览器中访问
# 2:重点
- index.html--->div-->id叫app
- App.vue ---> 组件--》在固定的位置写固定的代码即可
-<template> html内容
-<style> css内容
-<script> js内容
- main.js--》js代码
# 找到 index.html-->app这个div--》把App.vue组件中写的东西,放到index.html中
new Vue({
render: h => h(App.vue)
}).$mount('#app')
【2】vue的开发
- 访问根路径,显示
HomeView.vue
这个组件
- 通过vue-router来控制:在router-->index.js中
# 这个就好比我们的路由
- 找打:const routes = [
{
# 这个就是根路径的意思
path: '/',
name: 'home',
component: HomeView
},
{
# 这个是about的路径
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
- vue-routeru用来控制访问的路径
- 访问这个路径:http://192.168.1.252:8081/ ---》显示 HomeView 组件
- 访问这个路径:http://192.168.1.252:8081/about---》显示 AboutView 组件
App.vue
:根组件
# 如果没有vue-router,访问 根路径会显示 App.vue中写的东西
# 我们想每次访问的都只我们写的组件内容:方法
- 将App.vue里面只保留:
<template>
<div id="app">
<router-view/>
</div>
</template>
- 总结
- 在view文件夹下创建 xx.vue--- >页面组件
- 在router---》index.js 注册路由
- 浏览器中访问路径,就会显示 刚刚创建的组件
- 页面组件编写规范:三部分
# <template> html内容
# <style> css内容
# <script> js内容
# 必须加下面的内容
export default {
}
- 引入组件使用
1 导入
2 注册成局部组件
3 在template 写即可
-自定义属性--》父传子
-自定义事件--》子传父
【六】es6语法
【1】let、const
# let :定义变量
# const :定义常量
------块级作用域----
# var 以后尽量少用,用它声明的都是全局作用域
# 在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。
# ES6 新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束
# "暂时性死区"(Temporal Dead Zone,简称 TDZ)是指在 ES6 中使用 let 或 const 声明变量时,变量存在但无法访问的区域。这种行为是为了在 JavaScript 中引入块级作用域而设计的。
# 在 JavaScript 中,使用 var 声明的变量在其声明语句之前就可以被访问,这种行为称为"变量提升"。而在使用 let 或 const 声明变量时,变量虽然存在于作用域中,但是在声明语句之前访问这些变量会导致引发 ReferenceError 异常。
# 下面是例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js2/vue.js"></script>
</head>
<body>
</body>
<script>
function one(){
console.log(two)
var two=76 // 得到的是undefined
let two=76 // 会报错
}
one()
</script>
</html>
# 暂时性死区的产生原因是,let 和 const 声明的变量在进入作用域时就已经被创建,并且被绑定到了该作用域中,但是在变量的声明语句之前,访问这些变量会进入暂时性死区,因为此时变量尚未初始化
# python的LEGB---》查找顺序
【2】箭头函数
- 简化了代码
- 想了解细节的话,笔记里面写了
# 记住一句话:箭头函数内部没有自己的this---使用上一级
【3】this指向的问题
-
在全局上下文中,this之现象全局对象[可以放值取值]
- 放值取值:
- 放值取值:
-
在浏览器环境中通常是window对象,在
Node.js
中是global对象 -
-
函数调用:
-
如果函数作为普通函数调用,this指向全局对象(在严格模式下为undefined)
-
什么是严格模式:是 JavaScript 中的一种运行模式,它通过对语言的某些特性进行限制或改进来帮助开发者写出更安全、更规范的代码
-
<script> function one(){ console.log(this) // window对象 } one() </script>
-
-
如果函数作为对象的方法调用,this指向该方法的对象
- 尽头函数内部没有this,会往上找
<script> let this_one = { name: "jack", age: 18, one: () => { // 这里的this就是window对象 console.log(this) }, two: function(){ // 这里的this是one的对象 console.log(this) } } this_one.one() this_one.two() </script>
-
-
只要记住:箭头函数没有this,会往上找,找不到就是window(在严格模式下为undefined)
-
箭头函数的 this 指向定义时所在的作用域的 this 值,而不是调用时的 this 值。换句话说,箭头函数的 this 是词法作用域,而不是动态作用域
-
在 ES6 类方法中,this 指向调用该方法的对象实例
【4】模板字符串
- 插值表达式
const name = "Alice";
const age = 25;
const message = `Hello, my name is ${name} and I am ${age} years old.`;
【5】解构赋值
- 解构赋值允许从数组或对象中提取数据,并将其赋值给变量
- 如果结构的值在对象中没有,就会的到
undefind
,可以赋初值 - 解构赋值可以方便地交换变量的值,同时还支持默认值
<script>
// 解对象
let resume={name:"lsk",age:18,hobby:["dance","sing"]}
// 这里必须是个大括号
// 可以赋初值
let {name,age,one=666,hobby,two}=resume
console.log(name) // lsk
console.log(age) // 18
// 也可以用作赋值
console.log(one) // 666
hobby.pop()
// 就会将最后一个给pop掉
console.log(hobby)// [["dance"]
console.log(two) // undefined
// 解数组
let data=[67,11,99]
let [a,b]=data
console.log(a) //67
console.log(b) //11
// 结构函数返回值
function l(){
return {name:"lsk",age:18,hobby:["dance","sing"]}
}
let {name,age,hobby}=l()
console.log(name) // lsk
console.log(age) // 18
console.log(hobby) // ["dance","sing"]
</script>
【6】默认参数
ES6
允许在函数参数中设置默认值,当调用函数时未提供参数时,将使用默认值
function dom(name,age=22){
console.log(name)
console.log(age)
}
// 没有传age,使用默认的
dom('lsk')
【7】展开算法
- 记住展开算法的符号
...
- 可以将可迭代对象(如数组,字符串,对象)展开为多个参数或元素,也可以用作函数的参数
// 对象
let l = {name: "lsk", age: 18}
let i = {hobby: ["dance", "sing"],...l}
console.log(i) //{hobby:["dance","sing"],name:"lsk",age:18}
// 列表
let l = [1,2,3,4]
let i = [5,6,7,8,...l]
console.log(i) // [5,6,7,8,1,2,3,4]
// 函数
function l(a,...b){
console.log(a) // 接受一个值
console.log(b) // 接收剩下的所有
}
// 方法一
// l(1,2,3,4,5,6,7)
//方法二
let i=[1,2,3,4,5,6,7]
l(...i)
【8】模块化
(1)默认导入和导出
// 创建一个one.js文件 导出
// 定义一个常量
const NAME='lsk'
// 又名函数
function add(a,b){
return a+b
}
// 默认的导出对象只能有一个
export default {NAME,add,dmo(){
console.log("lsk")
}}
// 在其他的vue的js里面使用
import one from "@/lsk/one";
console.log(one.add(1,2))
console.log(one.NAME)
one.dmo()
(2)命名导入导出
// 命名导出
function dom1(){
console.log('dom1')
}
function dom2(){
console.log('dom1')
dom1()
}
export const f=dom2
export const NAME='lsk'
// 导入
// 方式一
// import {f,NAME} from "@/lsk/one";
// 方式二
import * as a from "@/lsk/one";
// 这个a是一个对象
a.f()
console.log(a.NAME)
(3)导入路径
- 如果在一个文件夹下,js的名字为index.js,你只需要导入到这一层的文件就可以
import index from "@/lsk";
console.log(index.add(1,2))
console.log(index.NAME)
index.dmo()
- @的意思就是当前的是src文件路径
# import index from "@/lsk"; 和 import index from "./lsk/index.js"; 一样
- 定制别名
import one from "@/lsk/one";
// 这个import后面的one只是一个你别名,可以自定义定制
- 起别名
import {f,NAME as a} from "@/lsk/one";
// 给NAME起别名叫a
(4)module使用
- 这个方法是在html中是使用的
// 定义一个js文件
export default {
function dom1(a,b){
return a+b
}}
// 在html中使用
// 如果不加上type="module"就会就会报错,加上就不会
<script type="module">
import lsk from './lsk'
console.log(lqz.dom1(4,5))
</script>
【七】登录的跳转案例
- 前后端分离
【1】解决跨越问题
- 在django的settings里面配置
# 统一按如下方式解决跨域
-1 安装
pip3 install django-cors-headers
-2 app中注册
INSTALLED_APPS = [
。。。
'corsheaders',
]
-3 中间件中注册
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
]
-4 配置文件中配置
# 允许跨域源
CORS_ORIGIN_ALLOW_ALL = True
# 允许的请求头
CORS_ALLOW_HEADERS = (
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
# 额外允许的请求头
'token',
)
【2】前端
- 路由
{
path: '/login',
name: 'login',
component: LoginView
},
{
path: '/film',
name: 'film',
component: FilmView
},
-
登录
-
这里面有一个新的知识,跳转页面
-
this.$router.push('/film')
-
-
<template>
<div>
<p>用户名:<input type="text" v-model="username"></p>
<p>密码:<input type="password" v-model="password"></p>
<p>
<button @click="handleLogin">点击登录</button>
</p>
<div>
<!-- 签发的token-->
{{ token }}
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
// 格式
name: 'LoginView',
data() {
return {
username: '',
password: '',
token: ''
}
},
methods: {
handleLogin() {
// 发送ajax请求到后端
axios.post('http://localhost:8000/login/', {
// 验证的数据
username: this.username,
password: this.password
}).then(res => {
// 判罚
if (res.data.code == 100) {
// 正确的请求,跳转到电影页面
this.$router.push('/film')
// 得到登录成功的token
this.token = res.data.token
} else {
alert(res.data.msg)
}
}).catch(err => {
alert(err)
})
}
}
}
</script>
<style scoped>
</style>
- 展示电影
<template>
<div>
<h1>最新的电影</h1>
<div v-for="film in film_list">
<h2>电影的名字:{{ film.name }}</h2>
<h2>电影的简介:{{ film.name }}</h2>
<div><img :src="film.poster" alt=""></div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: 'FilmView',
data() {
return {
film_list: []
}
},
created() {
axios.get('http://localhost:8000/api/v1/film/film/').then(res => {
this.film_list = res.data.result.films
})
}
}
</script>
<style>
</style>
【3】后端
- 登录:配一个签发有token的路由和定制返回格式,记得配置全局
# 全局配置
SIMPLE_JWT = {
"TOKEN_OBTAIN_SERIALIZER": "app1.common.TokenCommon.CommonToken",
}
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app1.common.exception.common_exception_handler',
}
# 定制返回的格式
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CommonToken(TokenObtainPairSerializer):
def validate(self, attrs):
res = super().validate(attrs)
data = {
"code": 100,
"msg": "登录成功!",
"token": res["access"]
}
return data
# 全局异常
from rest_framework.response import Response
from rest_framework.views import exception_handler
def common_exception_handler(exc, context):
res = exception_handler(exc, context)
if res:
response = Response({'code': 101, "msg": res.data.get('detail')})
else:
response = Response({'code': 000, "msg": '错误!'})
return response
- 视图层
import json
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
class FilmViewSet(ViewSet):
@action(methods=["get"], detail=False)
def film(self, request):
# 以运行的py文件所在目录为根
with open('./app1/package.json', 'r', encoding="utf-8") as fp:
data = json.load(fp)
return Response({
'code': 100,
'msg': '查看成功!',
'result': data
})
【八】scoped的使用
- 在你的style标签上添加scoped属性,表示当前style中的所有样式只对当前样式有效
<style scoped>
h1{
color: darkmagenta;
}
</style>
【九】开源的样式库地址
# 1 开源的样式库,方便在vue中使用
-elementui:饿了么团队开源的 web端
https://element.eleme.cn/#/zh-CN
-vant:有赞团队,移动端,微信小程序
https://vant-ui.github.io/vant/v2/#/zh-CN/grid
-ant design:阿里团队
https://1x.antdv.com/docs/vue/introduce-cn/
-iView
https://v2.iviewui.com/components/grid
-nutui:京东团队
https://nutui.jd.com/2x/#/dialog 移动端
# 使用
# elementui
# 2 项目中集成
1 安装:cnpm install element-ui -S
2 集成到项目:main.js 中加入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI); // 使用插件
3 去官网,找样式,复制,粘贴
【作业】
0 今天讲的代码都敲一遍
1 之前点击切换美女案例--》写在vue项目中--》创建页面组件
2 显示电影案例--》写在vue项目中--》创建页面组件
3 聊天案例--》写在vue项目中--》创建页面组件
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<script>
import axios from 'axios'
export default {
data(){
return {
name:''
}
},
created() {
axios.get().then(res=>{
this.name=res.data.name
})
}
}
# 1 登录跳转电影案例--》使用elementui美化
登录页面
电影页面
# 2 我讲的练习一下
# 3 聊天web
-登陆,注册
-登陆--》显示所有用户--表格
-每条用户有一个按钮---》申请
-对方同意--》是好友
-进入好友列表
-点用名字---》页面--》聊天
定时器
-群聊
# 思路
- 你需要创建好用户,存到数据库中
- 创建一个登录的vue组件
- 点击登录,发送ajax请求,到后端
- 后端,你需要判断用户名密码是否在正确,你也可以签发token
- 登入成功,返回所有的用户信息
- 前端接收后端返回的数据,渲染到页面,进行for循环,挨个显示用户信息
- 给每个用户后面都加一个按钮,添加好友的按钮(这个你可以在建立一个多对多的表,来存放关系)
- 点击按钮发送添加好友的请求(也就是建立关系),你点击添加好友的请求是发送给好友的当请求,而不是直接建立了关系
- 注册的话,你可以在等率的页面上添加一个按钮,点击按钮进入到注册页面(前提是拟建立好了注册的vue组件)
- 点击注册-将你的username和password发给后端,后端接收进行储存
- 点击好友头像或名字,进行如到聊天页面(新的vue的组件),可以进行聊天,你可以给你发送的信息,添加定时器
# 【作业】
````python
0 今天讲的代码都敲一遍
1 之前点击切换美女案例--》写在vue项目中--》创建页面组件
2 显示电影案例--》写在vue项目中--》创建页面组件
3 聊天案例--》写在vue项目中--》创建页面组件
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<script>
import axios from 'axios'
export default {
data(){
return {
name:''
}
},
created() {
axios.get().then(res=>{
this.name=res.data.name
})
}
}
# 1 登录跳转电影案例--》使用elementui美化
登录页面
电影页面
# 2 我讲的练习一下
# 3 聊天web
-登陆,注册
-登陆--》显示所有用户--表格
-每条用户有一个按钮---》申请
-对方同意--》是好友
-进入好友列表
-点用名字---》页面--》聊天
定时器
-群聊
# 思路
- 你需要创建好用户,存到数据库中
- 创建一个登录的vue组件
- 点击登录,发送ajax请求,到后端
- 后端,你需要判断用户名密码是否在正确,你也可以签发token
- 登入成功,返回所有的用户信息
- 前端接收后端返回的数据,渲染到页面,进行for循环,挨个显示用户信息
- 给每个用户后面都加一个按钮,添加好友的按钮(这个你可以在建立一个多对多的表,来存放关系)
- 点击按钮发送添加好友的请求(也就是建立关系),你点击添加好友的请求是发送给好友的当请求,而不是直接建立了关系
- 注册的话,你可以在等率的页面上添加一个按钮,点击按钮进入到注册页面(前提是拟建立好了注册的vue组件)
- 点击注册-将你的username和password发给后端,后端接收进行储存
- 点击好友头像或名字,进行如到聊天页面(新的vue的组件),可以进行聊天,你可以给你发送的信息,添加定时器