## Dropdown组件
- 下拉的每个item都可以拥有自己的属性和逻辑特点-用slot
- 下拉菜单点击其他区域下拉菜单的收起功能
**第一个用到自定义hook的地方:Dropdown组件点击外部区域自动隐藏**
```js
import { ref, onMounted, onUnmounted, Ref } from 'vue'
const useClickOutside = (elementRef: Ref<null | HTMLElement>) => {
const isClickOutside = ref(false)
const handler = (e: MouseEvent) => {
if (elementRef.value) {
if (elementRef.value.contains(e.target as HTMLElement)) {
isClickOutside.value = false
} else {
isClickOutside.value = true
}
}
}
onMounted(() => {
document.addEventListener('click', handler)
})
onUnmounted(() => {
document.removeEventListener('click', handler)
})
return isClickOutside
}
export default useClickOutside
```
### 下拉的每个item都可以拥有自己的属性和逻辑特点-用slot
GlobalHeader.vue
```vue
<ul v-else class="list-inline mb-0">
<li class="list-inline-item" href="#">
<Dropdown :title="`hello ${user.name}`">
<dropdown-item
><router-link :to="`/create`" class="dropdown-item"
>新建文章</router-link
></dropdown-item
>
<dropdown-item disabled
><a href="#" class="dropdown-item">编辑资料</a></dropdown-item
>
<dropdown-item
><a href="#" class="dropdown-item">退出登录</a></dropdown-item
>
</Dropdown>
</li>
</ul>
```
Dropdown.vue
```vue
<ul class="dropdown-menu" style="display: block" v-if="isOpen">
<slot></slot>
</ul>
```
DropdownItem.vue
```vue
<li class="dropdown-option" :class="{'is-disabled': disabled}">
<slot></slot>
</li>
```
### 下拉菜单点击其他区域下拉菜单的收起功能
![image-20210425095345760](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210425095345760.png)
这里可以用自定义hook函数,函数传入参数是一个dom节点,监听document中的点击事件,看点击的区域是否在这个节点内部
**下面用到了vue3的watch监听isClickOutSide的变化,否则它就只会执行一次**
```js
import { ref, onMounted, onUnmounted,Ref } from "vue";
const useClickOutside = (elementRef: Ref<null | HTMLElement>) => {
const isClickOutside = ref(false)
const handler = (e: MouseEvent) => {
if (elementRef.value) {
if (!elementRef.value.contains(e.target as HTMLElement)) {
isClickOutside.value = false
}else{
isClickOutside.value = true
}
}
}
onMounted(() => {
// console.log(123132132);
document.addEventListener('click', handler)
// console.log(isClickOutside.value);
})
onUnmounted(() => {
document.removeEventListener('click', handler)
})
return isClickOutside
}
export default useClickOutside
```
```js
const isClickOutside = useClickOutside(dropRef);
watch(isClickOutside, () => {
// console.log(isClickOutside.value);
if (isOpen.value && !isClickOutside.value) {
console.log("watch");
isOpen.value = false;
}
});
```
## 父子通信
注意:$on $emit 在vue3中被废除了,**但是可以引用第三方库**mitt
![image-20210425151904818](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210425151904818.png)
![image-20210425152924000](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210425152924000.png)
## vue-route
- this.$route - 获取路由的信息
- this.$router - 定义路由的一些列行为
### 路由元信息
![image-20210426154843505](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210426154843505.png)
## Restful API
endpoints
![image-20210425170625621](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210425170625621.png)
url中一般只有名词,没有动词,且名词与数据库的表名对应
![image-20210425170739371](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210425170739371.png)
## login和register组件的表单
> 因为组件是自己写的,所以我觉得登录和注册的时候的表单验证还是有挺多细节的,先是一个大的login组件中有一个form组件,其中form组件又有多个input组件,一旦点击某个Input组件时,就会触发@blur(焦点事件)事件,然后此焦点事件函数会对这个输入框的每个验证规则进行验证,一个输入框是有多个验证规则的,比如这些验证规则(对象数组)是对输入的长度大小等格式验证。此事件函数返回一个Bool值,然后将此事件传给父组件form,父组件定义一个函数数组接收触发每一个input组件的后的验证规则函数的返回值,然后再点击submit按钮的时候,只要一个不满足(every,swtich)会返回false,把结果返回给login组件。根据此结果判断是否需要发送异步登录请求
## token权限管理
> 登录的身份象征,登录后的其他用户信息需要借助此令牌获取
基于cookie和Session的身份验证
![image-20210426121335448](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210426121335448.png)
> 浏览器向服务器提交post请求登录,服务器验证登录账号密码,如果是对的就会创建对应的session数据并且保存,一般保存在数据库中可以用redis缓存,然后服务器发回一个response,有一个set-cookie属性,会把唯一的sessionid带上去,浏览器端会把cookie保存状态,然后此用户接下来的请求会携带此cookie证明自己的身份,拿数据
扩展性不好,如果搭建的是服务器集群,会要求session共享,可以持久化
**基于token的身份验证**
![image-20210426122119291](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210426122119291.png)
> 浏览器用户登录成功之后,服务器会使用JWT算法生成对应的token返回给浏览器,浏览器会把这个token存储在客户端,最常见的是存储在localStorage,或者SessionStorage中,之后发请求会带上token,JWT反向验证,此种方法没有状态,不需要记录用户的状态就可以验证身份,可扩展
用localStorage**持久化用戶的状态**
![image-20210426151210053](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210426151210053.png)
**权限管理**
**先在store的action中分别注册两个函数,一个是(login)登录的action可以传入登录的账号密码然后post到后端登录接口验证,然后另一个action对应获取当前用户信息接口的异步请求,然后将这两个action组合起来形成组合action,所以这个组合action就是dispatch('login')的后面.then回调再dispatch获取当前用户的信息,**
![image-20210426213728256](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210426213728256.png)
**在**login的action中,调用post接口会获取到一个tocken值,commit提交相应的login的mutation中会将这个mutation存储到state的token中,并且还会用localstorage的getItem方法持久化存在本地,而且设置axios.defaults.headers.common.Authorization = `Bearer ${token}`
为以后的每次请求头带上token
并且在当前用户currentUser mutation中设置state中用户的状态
对应的logout登出mutation会将本地的token值都移除
![image-20210426213755161](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210426213755161.png)
![image-20210426214010782](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210426214010782.png)
![image-20210426214536542](C:\Users\47302\AppData\Roaming\Typora\typora-user-images\image-20210426214536542.png)
之后在前置路由beforEach中,判断用户的状态和token值,只要有这个token值在本
没有合适的资源?快使用搜索试试~ 我知道了~
用vue3+ts写的仿知乎系统,用到了vue3.0,composition Api的大部分功能..zip
共42个文件
vue:19个
ts:11个
json:3个
需积分: 0 0 下载量 85 浏览量
2024-01-04
15:03:28
上传
评论
收藏 136KB ZIP 举报
温馨提示
Vue3,springboot,element-ui使用技巧,实战应用开发小系统参考资料,源码参考。 详细介绍了一些Qt框架的各种功能和模块,以及如何使用Qt进行GUI开发、网络编程和跨平台应用开发等。 适用于初学者和有经验的开发者,能够帮助你快速上手Qt并掌握其高级特性。
资源推荐
资源详情
资源评论
收起资源包目录
用vue3+ts写的仿知乎系统,用到了vue3.0,composition Api的大部分功能..zip (42个子文件)
VUE3_new
.browserslistrc 30B
.eslintrc.js 386B
src
store.ts 7KB
helper.ts 2KB
main.ts 2KB
App.vue 3KB
assets
logo.png 7KB
lizhi.jpg 12KB
router.ts 2KB
components
ValidateInput.vue 4KB
createMessage.ts 631B
Uploader.vue 3KB
ColumnList.vue 2KB
GlobalHeader.vue 2KB
Loader.vue 1KB
Message.vue 1KB
Dropdown.vue 2KB
Modal.vue 2KB
UserProfile.vue 1KB
ValidateForm.vue 1KB
DropdownItem.vue 493B
PostList.vue 1KB
testData.ts 3KB
shims-vue.d.ts 147B
hooks
useClickOutside.ts 794B
useLoadMore.ts 841B
useDOMCreate.ts 279B
views
Signup.vue 4KB
ColumnDetail.vue 2KB
Login.vue 3KB
CreatePost.vue 6KB
Home.vue 2KB
PostDetail.vue 4KB
package.json 850B
public
favicon.ico 4KB
index.html 641B
package-lock.json 447KB
vue.config.js 545B
.gitignore 231B
tsconfig.json 670B
shims-vue.d.ts 29B
README.md 19KB
共 42 条
- 1
资源评论
白话Learning
- 粉丝: 3274
- 资源: 2464
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功