refactor: save
This commit is contained in:
parent
596d8897dc
commit
24b6b4076d
418
README2.md
Normal file
418
README2.md
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
---
|
||||||
|
theme: cyanosis
|
||||||
|
highlight: vs2015
|
||||||
|
---
|
||||||
|
|
||||||
|
# 前言
|
||||||
|
|
||||||
|
随着手机性能的提升,如今移动端APP的用户体验越来越好了,页面流畅不卡顿,转场动画优雅又丝滑
|
||||||
|
|
||||||
|
而大部分的 `web` 页面,尽管功能上比起 `10` 年前 `jQuery`
|
||||||
|
时代丰富了不少,但似乎在使用体验上还是一尽难尽的地步,应用最广泛的动画可能是弹框组件了,毕竟 `UI` 库直接提供了动画
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
这是我的 [**模仿抖音**](https://juejin.cn/column/7357362143396118528) 系列文章的第四篇:这篇我们将实现页面缓存,就像我们访问传统新闻网站一样
|
||||||
|
> 第一篇:[200行代码实现类似Swiper.js的轮播组件](https://juejin.cn/post/7360512664317018146)
|
||||||
|
> 第二篇:[实现抖音 “视频无限滑动“效果](https://juejin.cn/post/7361614921519054883)
|
||||||
|
> 第三篇:[Vue 路由使用介绍以及添加转场动画](https://juejin.cn/post/7362528152777130025)
|
||||||
|
|
||||||
|
# 最终效果
|
||||||
|
|
||||||
|
在线预览:[dy.ttentau.top/](https://dy.ttentau.top/)
|
||||||
|
|
||||||
|
Github地址:[https://github.com/zyronon/douyin](https://github.com/zyronon/douyin)
|
||||||
|
|
||||||
|
路由定义源码:[routes.ts](https://github.com/zyronon/douyin/blob/master/src/router/routes.ts)
|
||||||
|
转场动画源码:[App.vue](https://github.com/zyronon/douyin/blob/master/src/App.vue)
|
||||||
|
|
||||||
|
## 思考
|
||||||
|
|
||||||
|
- 如何判断是“前进”还是“后退”而使用不同的动画方式?
|
||||||
|
|
||||||
|
# 一、路由使用
|
||||||
|
|
||||||
|
## 1. 初始化路由
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Vue from 'vue'
|
||||||
|
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHashHistory(),
|
||||||
|
routes,
|
||||||
|
scrollBehavior(to, from, savedPosition) {
|
||||||
|
if (savedPosition) {
|
||||||
|
return savedPosition
|
||||||
|
} else {
|
||||||
|
return { top: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
app.use(router)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. 定义路由
|
||||||
|
|
||||||
|
接下来就可以进行路由组件的映射:
|
||||||
|
为了践行模块化组件化思想,组件是从其他文件import进来
|
||||||
|
|
||||||
|
---
|
||||||
|
可以 `静态` 导入(在文件顶部用 `import` 导入组件) 使用
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Home from '../pages/home/index.vue'
|
||||||
|
```
|
||||||
|
|
||||||
|
静态导入的组件会 `全部` 默认打包到一个 `js` 文件中
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
也可以 `动态` 导入使用
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
path: '/home', component
|
||||||
|
:
|
||||||
|
() => import('@/pages/home/index.vue')
|
||||||
|
}
|
||||||
|
,
|
||||||
|
```
|
||||||
|
|
||||||
|
动态的导入的 `每一个` 组件,会被单独打包成一个 `js` 文件,一对一的,定义了 `50` 个路由,就会打包出 `50` 个 `js`
|
||||||
|
文件(当然我们可以在 `vite.config.js` 或 `vue.config.js` 里面配置打包分割,将组件进行分组统一打包到一个 `js` 文件中)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```js
|
||||||
|
import Home from '../pages/home/index.vue'
|
||||||
|
import Test from '../pages/test/Test.vue'
|
||||||
|
|
||||||
|
//创建routes数组,然后传入 createRouter 的 ‘routes’ 配置中
|
||||||
|
const routes = [
|
||||||
|
//每个路由映射一个组件
|
||||||
|
{ path: '/', redirect: '/home' },
|
||||||
|
{ path: '/test', component: Test },
|
||||||
|
{ path: '/home', component: Home },
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 路由出口
|
||||||
|
|
||||||
|
```js
|
||||||
|
App.vue
|
||||||
|
|
||||||
|
< router - view > < /router-view>
|
||||||
|
```
|
||||||
|
|
||||||
|
我们定义好了路由映射之后,还需要定义一个路由`出口`,即 `<router-view></router-view>`
|
||||||
|
,这个标签放在哪个位置,哪个位置就会显示当前所匹配路由映射的 `Vue` 组件
|
||||||
|
|
||||||
|
默认我们是放在 `App.vue` 里面,这样就可以访问所有定义的 `一级` 路由了
|
||||||
|
|
||||||
|
## 4. 嵌套路由
|
||||||
|
|
||||||
|
上面只是路由的普通使用,只能访问一级页面,但我们做后台、管理系统等网站,基本上都有嵌套路由的要求
|
||||||
|
嵌套路由只需在 `children` 字段里放同样的路由映射即可
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
path: '/layout',
|
||||||
|
component
|
||||||
|
:
|
||||||
|
Layout,
|
||||||
|
children
|
||||||
|
:
|
||||||
|
[
|
||||||
|
{ path: '/layout-child1', component: LayoutChild1 },
|
||||||
|
{ path: '/layout-child2', component: LayoutChild1 },
|
||||||
|
{ path: '/layout-child3', component: LayoutChild1 },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
,
|
||||||
|
```
|
||||||
|
|
||||||
|
再定义子路由 `出口`,同样还是 `<router-view></router-view>` 标签,我们知道这个标签放在哪里,就会显示当前匹配的组件
|
||||||
|
我们在 `App.vue` 里面放了一个,那么 `App.vue` 就会显示当前所匹配路由映射的 `Vue` 组件
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
子路由的出口也是同样的,你想在在哪显示就放在哪里,我们的 `Layout.vue` 组件需要有子路由,那么就放在 `Layout.vue` 里面就行了
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# 二、转场动画
|
||||||
|
|
||||||
|
我们需要用到 `Vue` 的 `Transition` 这个组件
|
||||||
|
具体使用请看官网,这里不详细介绍
|
||||||
|
https://cn.vuejs.org/guide/built-ins/transition.html
|
||||||
|
|
||||||
|
还用到了 `css` 的 `transform` 属性,它允许你旋转,缩放,倾斜或平移给定元素,我们用它来平移两个路由页面
|
||||||
|
https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform
|
||||||
|
|
||||||
|
还用到了 `css` 的 `transition` 属性,它可以使在不同 `css` 属性状态切换的时候产生过渡效果(可以理解为简单动画)
|
||||||
|
,我们用它来给 `transform` 加过渡效果
|
||||||
|
https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition
|
||||||
|
|
||||||
|
## 1. Transition组件
|
||||||
|
|
||||||
|
```js
|
||||||
|
Vue3
|
||||||
|
< router - view
|
||||||
|
v - slot = "{ Component }" >
|
||||||
|
< transition
|
||||||
|
:
|
||||||
|
name = "transitionName" >
|
||||||
|
< component
|
||||||
|
:
|
||||||
|
is = "Component" / >
|
||||||
|
< /transition>
|
||||||
|
</router-view>
|
||||||
|
|
||||||
|
Vue2
|
||||||
|
< transition
|
||||||
|
:
|
||||||
|
name = "transitionName" >
|
||||||
|
< router - view > < /router-view>
|
||||||
|
</transition>
|
||||||
|
```
|
||||||
|
|
||||||
|
**需要注意的是,`Vue3` 和 `Vue2` 的写法不同**
|
||||||
|
|
||||||
|
- `transition` 中 `name` 属性用于定义动画, `Vue` 会根据提供的 `name` 值去寻找对应的 `css`
|
||||||
|
类名,并在合适的时机添加、移除 `css` 类名
|
||||||
|
- `transition` 的子元素只能有一个,并且当子元素符合以下条件时,会自动触发
|
||||||
|
- 由`v-if`所触发的切换
|
||||||
|
- 由`v-show`所触发的切换
|
||||||
|
- 由特殊元素`<component>`切换的动态组件
|
||||||
|
- 改变特殊的`key`属性
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
比如说,我们将 `name` 定义为 `test`,那么每次动画执行时,`Vue` 会自动给我们添加上图的 6 个 `css`
|
||||||
|
类名:`test-enter-from` `test-enter-active` `test-enter-to` `test-leave-from` `test-leave-active` `test-leave-to`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
当我们前进时:
|
||||||
|
**当前页面需要从 0(屏幕中间) 平移至 -100%(屏幕左侧) ,下个页面 需要从 100%(屏幕右侧) 平移至 0(屏幕中间)**
|
||||||
|
|
||||||
|
当我们后退时:
|
||||||
|
**当前页面需要从 0(屏幕中间) 平移至 100%(屏幕右侧) ,下个页面 需要从 -100%(屏幕左侧) 平移至 0(屏幕中间)**
|
||||||
|
|
||||||
|
所以我们需要两种动画,一种是 `前进` ,一种是 `返回`,不同状态展示不同动画
|
||||||
|
|
||||||
|
具体使用什么动画,我们用一个变量 `transitionName` 来定义
|
||||||
|
|
||||||
|
## 2.动画
|
||||||
|
|
||||||
|
我们在前进时,当前页面和下个页面的需要执行的动画是不同的,后退时也一样
|
||||||
|
|
||||||
|
这里直接放最终的 `css` 代码,
|
||||||
|
下面解释为什么这样写
|
||||||
|
|
||||||
|
### 前进动画
|
||||||
|
|
||||||
|
```css
|
||||||
|
/
|
||||||
|
/页面最终/ 最初的状态:屏幕正中间
|
||||||
|
.go-enter-to,
|
||||||
|
.go-leave-from {
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/
|
||||||
|
/
|
||||||
|
动画持续时间
|
||||||
|
.go-enter-active,
|
||||||
|
.go-leave-active {
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/
|
||||||
|
/
|
||||||
|
离去动画,表示离去页面最终的css:屏幕左侧
|
||||||
|
.go-leave-to {
|
||||||
|
transform: translate3d(-100%, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/
|
||||||
|
/
|
||||||
|
进入动画,表示进入页面,初始的状态:屏幕右侧
|
||||||
|
.go-enter-from {
|
||||||
|
transform: translate3d(100%, 0, 0);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 后退动画
|
||||||
|
|
||||||
|
```css
|
||||||
|
/
|
||||||
|
/
|
||||||
|
和上面同理,只时 css 是反着的而已
|
||||||
|
.back-enter-to,
|
||||||
|
.back-enter-from {
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-enter-active,
|
||||||
|
.back-leave-active {
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-enter-from {
|
||||||
|
transform: translate3d(-100%, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-leave-to {
|
||||||
|
transform: translate3d(100%, 0, 0);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 动画原理
|
||||||
|
|
||||||
|
**两个页面平移动画的原理:**
|
||||||
|
|
||||||
|
当我们前进时:
|
||||||
|
**当前页面需要从 0(屏幕中间) 平移至 -100%(屏幕左侧) ,下个页面 需要从 100%(屏幕右侧) 平移至 0(屏幕中间)**
|
||||||
|
|
||||||
|
当我们后退时:
|
||||||
|
**当前页面需要从 0(屏幕中间) 平移至 100%(屏幕右侧) ,下个页面 需要从 -100%(屏幕左侧) 平移至 0(屏幕中间)**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
通过上图可以看到
|
||||||
|
一、当我们导航到下一页时,两个路由页面最外层的 `div` 是平级的,所以当动画执行时,*
|
||||||
|
*会看到当前页面从屏幕中间向左平移出去了,但下个页面并没有从屏幕右侧向屏幕中间平移,而是在动画结束后,突然显示在屏幕中间**
|
||||||
|
。这是因为按照正常的文档流,两个页面最外层的 `div` 都是 `block` ,所以下个页面单起一行放在当前页面的正下方
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
解决办法:给每个页面加个统一的 `class` ,将页面统一设置为 `position:absolute;`,此时页面脱离文档流,不占空间,这样就不会把下一页挤下去,完成平滑过渡
|
||||||
|
|
||||||
|
二、由图可知,离去的页面 `Vue` 会自动给我们加上 `xxx-leave-active, xxx-leave-to` 这两个 `class`
|
||||||
|
而进入的页面,`Vue` 会自动给我们加上 `xxx-enter-active, xxx-enter-to` 这两个 `class`
|
||||||
|
还有这 `xxx-leave-from, xxx-enter-from`两个 `class` 是动画一开始就加上,然后立刻又删除了,截图里面展示不出来😅
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
所以,当我们知道 `Vue` 执行动画时有哪些 `class`,就可以对应的编写 `css` 过渡了
|
||||||
|
|
||||||
|
就拿 **前进** 时 **离去的页面** 举例:
|
||||||
|
|
||||||
|
- 动画开始:`go-leave-from`,然后又立马就删除了。所以我们可以在这个 `class` 编写用于启动过渡的 `css` ,用于表明这个页面的初始状态
|
||||||
|
|
||||||
|
```css
|
||||||
|
/
|
||||||
|
/
|
||||||
|
页面的初始状态
|
||||||
|
.go-leave-from {
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 动画行程中:`go-leave-active, go-leave-to`,我们在这里定义整个过渡的时间,以及我们页面最终的 `css` 的样式
|
||||||
|
|
||||||
|
```css
|
||||||
|
/
|
||||||
|
/
|
||||||
|
整个过渡过程需要300毫秒
|
||||||
|
.go-leave-active {
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/
|
||||||
|
/
|
||||||
|
最终状态,当动画结束时,页面需要 平移到
|
||||||
|
|
||||||
|
-
|
||||||
|
100
|
||||||
|
%
|
||||||
|
的地方
|
||||||
|
.go-leave-to {
|
||||||
|
transform: translate3d(-100%, 0, 0);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
其他的动画,基本同理。需要注意的是,同一个动画中,离去的页面和进入的页面的 `translate3d` 是相反的
|
||||||
|
|
||||||
|
## 4. 区分是“前进”还是“后退”
|
||||||
|
|
||||||
|
`$route` 作为 `vue` 实例的一个响应式属性,和在 `data` 中写的属性本质上是一样的,都可以通过 `this`
|
||||||
|
的方式拿到。既然你可以监听 `data` 中的属性变化,同样也可以监听 `$route` 的变化。`watch`
|
||||||
|
中监听的对象默认回调函数中的参数值就是 `newVal, oldVal`。作为 `$route` 属性来说当然也就是 `to` 和 `from` 的概念了
|
||||||
|
|
||||||
|
`to、from` 是最基本的路由对象,分别表示从(`from`)某个页面跳转到(`to`)另一个页面,`to.path`
|
||||||
|
(表示要跳转到的路由地址),`from.path` 同理
|
||||||
|
|
||||||
|
**该功能的难点在于怎样分辨是“前进”还是“后退”?**
|
||||||
|
|
||||||
|
还记得我们前面定义的 `routes` 数组吗?我们现在需要将每个路由**按层级依次排序**(暂不考虑嵌套路由的情况)
|
||||||
|
,依次排列每个路由的下一页、下下页...即保证每个“上一页”在“下一页”前面
|
||||||
|
|
||||||
|
总结下来就是:根据 `routes` 数组里定义的路由目录的顺序,在 `watch` 到路由变更的时候,用 `to.path` 和 `from.path`
|
||||||
|
去 `routes` 数组里去查找下标,**下标靠前的是上一页,靠后的是下一页,可由此判断是“前进”还是“后退”**
|
||||||
|
|
||||||
|
### Vue2写法
|
||||||
|
|
||||||
|
```js
|
||||||
|
// watch $route 决定使用哪种过渡
|
||||||
|
watch: {
|
||||||
|
'$route'(to, from)
|
||||||
|
{
|
||||||
|
//底部tab的按钮,跳转是不需要用动画的
|
||||||
|
let noAnimation = ['/', '/home', '/slide', '/me', '/attention', '/message', '/publish']
|
||||||
|
if (noAnimation.indexOf(from.path) !== -1 && noAnimation.indexOf(to.path) !== -1) {
|
||||||
|
return this.transitionName = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const toDepth = routes.findIndex(v => v.path === to.path)
|
||||||
|
const fromDepth = routes.findIndex(v => v.path === from.path)
|
||||||
|
this.transitionName = toDepth > fromDepth ? 'go' : 'back'
|
||||||
|
}
|
||||||
|
,
|
||||||
|
}
|
||||||
|
,
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vue3写法
|
||||||
|
|
||||||
|
```js
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
// watch $route 决定使用哪种过渡
|
||||||
|
watch(
|
||||||
|
() => route.path,
|
||||||
|
(to, from) => {
|
||||||
|
//底部tab的按钮,跳转是不需要用动画的
|
||||||
|
let noAnimation = ['/', '/home', '/slide', '/me', '/attention', '/message', '/publish']
|
||||||
|
if (noAnimation.indexOf(from) !== -1 && noAnimation.indexOf(to) !== -1) {
|
||||||
|
return transitionName.value = ''
|
||||||
|
}
|
||||||
|
const toDepth = routes.findIndex((v: RouteRecordRaw) => v.path === to)
|
||||||
|
const fromDepth = routes.findIndex((v: RouteRecordRaw) => v.path === from)
|
||||||
|
transitionName.value = toDepth > fromDepth ? 'go' : 'back'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
至此我们已经学会了路由使用,以及如何在 `Vue`
|
||||||
|
中怎么给路由添加转场动画了,我文章中所介绍的只是普通的平移动画,大家如果想要其他样式的动画,只需要对照着那几个 `Vue`
|
||||||
|
定义的那几个 `css` 修改就可以了
|
||||||
|
|
||||||
|
本来想把 `页面缓存` 也一起写了,不过由于篇幅所致,很多人都是 `太长不看`,所以还是单独写一篇吧~
|
||||||
|
|
||||||
|
# 结束
|
||||||
|
|
||||||
|
>
|
||||||
|
以上就是文章的全部内容,感谢看到这里,希望对你有所帮助或启发!创作不易,如果觉得文章写得不错,可以点赞收藏支持一下,我会更新更多实用的前端知识与技巧,期待与你共同成长~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.8 KiB |
@ -43,7 +43,7 @@ watch(
|
|||||||
() => route.path,
|
() => route.path,
|
||||||
(to, from) => {
|
(to, from) => {
|
||||||
store.setMaskDialog({ state: false, mode: store.maskDialogMode })
|
store.setMaskDialog({ state: false, mode: store.maskDialogMode })
|
||||||
//footer下面的5个按钮,对跳不要用动画
|
//底部tab的按钮,跳转是不需要用动画的
|
||||||
let noAnimation = [
|
let noAnimation = [
|
||||||
'/',
|
'/',
|
||||||
'/home',
|
'/home',
|
||||||
|
|||||||
@ -78,7 +78,7 @@ const state = reactive({
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
width: 70vw;
|
width: 70%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
.location-wrapper {
|
.location-wrapper {
|
||||||
|
|||||||
@ -19,8 +19,8 @@
|
|||||||
import SlideVerticalInfinite from '@/components/slide/SlideVerticalInfinite.vue'
|
import SlideVerticalInfinite from '@/components/slide/SlideVerticalInfinite.vue'
|
||||||
import { onMounted, onUnmounted, reactive, ref } from 'vue'
|
import { onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
import bus, { EVENT_KEY } from '@/utils/bus'
|
import bus, { EVENT_KEY } from '@/utils/bus'
|
||||||
import { useSlideListItemRender } from '@/utils/hooks/useSlideListItemRender'
|
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
|
import { slideItemRender } from '@/utils'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
cbs: {
|
cbs: {
|
||||||
@ -63,7 +63,7 @@ const p = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const render = useSlideListItemRender({ ...props.cbs, ...p })
|
const render = slideItemRender({ ...props.cbs, ...p })
|
||||||
const listRef = ref(null)
|
const listRef = ref(null)
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
index: props.index,
|
index: props.index,
|
||||||
|
|||||||
@ -116,10 +116,9 @@ import ConfirmDialog from '../../components/dialog/ConfirmDialog.vue'
|
|||||||
import FollowSetting2 from '@/pages/home/components/FollowSetting2.vue'
|
import FollowSetting2 from '@/pages/home/components/FollowSetting2.vue'
|
||||||
import ShareToFriend from '@/pages/home/components/ShareToFriend.vue'
|
import ShareToFriend from '@/pages/home/components/ShareToFriend.vue'
|
||||||
import { DefaultUser } from '@/utils/const_var'
|
import { DefaultUser } from '@/utils/const_var'
|
||||||
import { _checkImgUrl } from '@/utils'
|
import { _checkImgUrl, slideItemRender } from '@/utils'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import SlideVerticalInfinite from '@/components/slide/SlideVerticalInfinite.vue'
|
import SlideVerticalInfinite from '@/components/slide/SlideVerticalInfinite.vue'
|
||||||
import { useSlideListItemRender } from '@/utils/hooks/useSlideListItemRender'
|
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@ -164,7 +163,7 @@ const state = reactive({
|
|||||||
pageNo: 0
|
pageNo: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
const render = useSlideListItemRender()
|
const render = slideItemRender()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// console.log('s', store.routeData)
|
// console.log('s', store.routeData)
|
||||||
|
|||||||
13
src/utils/hooks/useBase.ts
Normal file
13
src/utils/hooks/useBase.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { onActivated, onDeactivated } from 'vue'
|
||||||
|
|
||||||
|
export function useBase() {
|
||||||
|
const mainScroll = $ref()
|
||||||
|
const mainScrollTop = $ref(0)
|
||||||
|
onActivated(() => {
|
||||||
|
console.log('onActivated')
|
||||||
|
})
|
||||||
|
|
||||||
|
onDeactivated(() => {
|
||||||
|
console.log('onDeactivated')
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1,35 +0,0 @@
|
|||||||
import SlideUser from '@/components/slide/SlideUser.vue'
|
|
||||||
import BaseVideo from '@/components/slide/BaseVideo.vue'
|
|
||||||
|
|
||||||
export function useSlideListItemRender(props) {
|
|
||||||
return function render(item, index, play, uniqueId) {
|
|
||||||
// console.log('item', item)
|
|
||||||
let node
|
|
||||||
switch (item.type) {
|
|
||||||
case 'img':
|
|
||||||
node = <img src={item.src} style="height:100%;" alt={''} />
|
|
||||||
break
|
|
||||||
// case 'imgs':
|
|
||||||
// node = <SlideAlbum isPlay={play} index={index} position={{ uniqueId, index }} {...props} />
|
|
||||||
// break
|
|
||||||
case 'user':
|
|
||||||
node = <SlideUser {...props} />
|
|
||||||
break
|
|
||||||
case 'send-video':
|
|
||||||
node = <video src={item.src} style="height:100%;" />
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
node = (
|
|
||||||
<BaseVideo
|
|
||||||
isPlay={play}
|
|
||||||
item={item}
|
|
||||||
index={index}
|
|
||||||
position={{ uniqueId, index }}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -7,6 +7,8 @@ import { IMG_URL, IS_DEV, IS_GITEE_PAGES } from '@/config'
|
|||||||
import NoticeDialog from '../components/dialog/NoticeDialog.vue'
|
import NoticeDialog from '../components/dialog/NoticeDialog.vue'
|
||||||
import bus, { EVENT_KEY } from './bus'
|
import bus, { EVENT_KEY } from './bus'
|
||||||
import { ArchiveReader, libarchiveWasm } from 'libarchive-wasm'
|
import { ArchiveReader, libarchiveWasm } from 'libarchive-wasm'
|
||||||
|
import SlideUser from '@/components/slide/SlideUser.vue'
|
||||||
|
import BaseVideo from '@/components/slide/BaseVideo.vue'
|
||||||
|
|
||||||
export function _updateItem(props, key, val, emit) {
|
export function _updateItem(props, key, val, emit) {
|
||||||
const old = cloneDeep(props.item)
|
const old = cloneDeep(props.item)
|
||||||
@ -411,3 +413,36 @@ export async function _fetch(url: string): Promise<{ json(): Promise<any> } | Re
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function slideItemRender(props) {
|
||||||
|
return function render(item, index, play, uniqueId) {
|
||||||
|
// console.log('item', item)
|
||||||
|
let node
|
||||||
|
switch (item.type) {
|
||||||
|
case 'img':
|
||||||
|
node = <img src={item.src} style="height:100%;" alt={''} />
|
||||||
|
break
|
||||||
|
// case 'imgs':
|
||||||
|
// node = <SlideAlbum isPlay={play} index={index} position={{ uniqueId, index }} {...props} />
|
||||||
|
// break
|
||||||
|
case 'user':
|
||||||
|
node = <SlideUser {...props} />
|
||||||
|
break
|
||||||
|
case 'send-video':
|
||||||
|
node = <video src={item.src} style="height:100%;" />
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
node = (
|
||||||
|
<BaseVideo
|
||||||
|
isPlay={play}
|
||||||
|
item={item}
|
||||||
|
index={index}
|
||||||
|
position={{ uniqueId, index }}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user