我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)

第二期 · 使用 Vue 3.1 + TypeScript + Router + Tailwind.css 仿 itch.io 平台主页。

我的主题 HapiGames 是仿 itch.ioindie game hosting marketplace

效果图

我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)插图1

代码仓库

alicepolice/Vue at 06 (github.com)

风格指南

当你掌握一门语言的时候,在写项目之前不妨先看看风格指南吧,前人早为你铺好了路。下面是我自己编写项目代码时没有规范到位的几个点。

风格指南 — Vue.js (vuejs.org)

Prop 定义

Prop 定义应该尽量详细,至少需要指定其类型。Props | Vue.js (vuejs.org)

Vue的选项式API为我们提供了Prop校验,你可以向 props 选项提供一个带有 props 校验选项的对象,当 prop 的校验失败后,Vue 会抛出一个控制台警告 (开发模式)。(如果用ts的话更好)

注意 prop 的校验是在组件实例被创建之前,所以实例的属性 (比如 datacomputed 等) 将在 defaultvalidator 函数中不可用。

v-for和v-if同时在一个标签时,将v-if提取到计算属性

因为 v-for 优先级比 v-if 高,所以每次渲染时必定会遍历数组所有元素。避免 v-if 和 v-for 用在一起

将v-if提取到计算属性后的好处

  • 过滤后的列表会在对应数组发生相关变化时才被重新运算,过滤更高效。
  • 使用 v-for="item in afterComputed" 之后,在渲染的时候遍历元素少了,渲染更高效。
  • 解耦渲染层的逻辑,可维护性 (对逻辑的更改和扩展) 更强。

紧密耦合的组件名

和父组件紧密耦合的子组件应该以父组件名作为前缀命名。紧密耦合的组件名

如果一个组件只在某个父组件的场景下有意义,这层关系应该体现在其名字上。因为编辑器通常会按字母顺序组织文件,所以这样做可以把相关联的文件排在一起。

不建议为了紧密耦合搞目录区分,因为会出现文件名名字相同、IDE侧边栏浏览组件花费时间多的问题。

components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue

自闭合组件

在单文件组件、字符串模板和 JSX 中没有内容的组件应该是自闭合的——但在 DOM 模板里永远不要这样做。 自闭合组件





Prop 名大小写

在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板和 JSX 中应该始终使用 kebab-case。 Prop 名大小写

props: {
  greetingText: String
}

简单的计算属性

应该把复杂计算属性分割为尽可能多的更简单的 property。 简单的计算属性

好处是易于测试、易于阅读、更好的“拥抱变化”。

单文件组件的顶级元素的顺序

单文件组件应该总是让

隐性的父子组件通信

应该优先通过 prop 和事件进行父子组件之间的通信,而不是 this.$parent 或变更 prop。 隐性的父子组件通信

数据流应该是单向的,不要反向修改 props。

方便调试

为了方便调试,我们在 index.css 下新增一个样式组合,通过添加test类样式类看到块元素的边框。

  .test{
    @apply border border-gray-900
  }

目录结构

├───assets
│   ├───avater
│   │   用户头像
│   ├───blog
│   │   博文封面图
│   ├───diffuse
│   │   模糊背景
│   ├───game
│   │   游戏封面图
│   ├───logo
│   │   网站logo
│   ├───slideshow
│   │   轮播图样图
│   └───svg
│       很多矢量图
├───components
│   ├───common
│   │       BottomBar.vue
│   │       CommentArea.vue
│   │       SideBar.vue
│   │       SideBarHref.vue
│   │       SlideShow.vue
│   │       TopBar.vue
│   │
│   └───HomeView
│           GameBlog.vue
│           GameInfo.vue
│           GameList.vue
│           HomeFAQ.vue
│           HomeFooter.vue
│           PlatformNavigation.vue
│           TopNavigation.vue
│
├───router
│       index.ts
└───views
        AboutView.vue
        CommentTestView.vue
        HomeLoginView.vue
        HomeView.vue
        LoginView.vue
        RegisterView.vue

网站顶部组件 TopBar.vue

在 src/components/common 下新建 TopBar.vue,并移入之前写的 BottomBar.vue。

先从网站顶部开始,该组件在每个页面都会显示,并在滚动过程中固定定位。

编写代码,实现顶部栏。

我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)插图2


侧边导航栏组件 SideBar.vue

我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)插图4

注释底部导航栏

我的Vue之旅、05 导航栏、登录、注册 (Mobile) - 小能日记 - 博客园 (cnblogs.com)

在前一期内容中,我们创建的导航栏是底部导航栏

我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)插图5

现在我们推倒重来,实现一下侧边导航栏

侧边栏导航也叫抽屉式导航是隐藏在界面侧边的位置,一般是通过点击界面左上角的icon弹出,主要承载的内容是除了核心功能意外的主要功能。侧边栏还分全侧边和半侧边。

我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)插图6

当我们在App.vue中注释掉现有的底部导航栏,此时会出现错误item.routerName => item对象的类型为 "unknown"。



[TS]使用高级类型PropType注释props类型

IDE报错并不影响当前Vue实例,因为BottomBar组件并未挂载。但为了去除报错,使用高级类型注释来修改BottomBar.vue。

运行时 props 选项仅支持使用构造函数来作为一个 prop 的类型,没有办法指定多层级对象或函数签名之类的复杂类型。在这里可以使用 PropType 注释复杂的props类型,报错解决。


SideBarHref.vue

在 src/components/common 下新建 SideBarHref.vue

侧边导航栏有相似之处,不妨将这一块提取成独立的组件,然后复用三次。

我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)插图7

添加样式 hover:text-rose-500 hover:underline,在移动端按下时会改变颜色。

我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)插图8

用于临时超链接占位,后续可改为router-link




SideBar.vue

遮蔽层

在 src/components/common 下新建 SideBar.vue 以下代码片段均为分段表示,不是完整代码。

先写model层(遮蔽层),一般指侧边栏滚出后背景变黑的部分。

我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)插图9

我们使用自定义类名实现过渡动画。类名也是TailWind.css的类样式,给定200毫秒时间,过渡透明度状态。

div嵌套了两层,把opacity-50写到里面的div层能解决opacity-50在外面div层的时候出现背景全黑问题。

fixed 用于固定遮蔽层。z-30用于设置优先级,先显示在前面。v-show由App.vue传入,顶部组件通知App.vue事件对应的方法修改,进而引发当前transition的过渡。

html - Vue Transition with Tailwind - Stack Overflow

侧边栏

侧边栏的动画效果跟遮蔽层一个原理,只不过修改成为了移动而不是改变透明度。

overflow-auto 可以让侧边栏在内容溢出时具备滚动条。

 
   

posted @
2022-10-18 23:15 
小能日记 
阅读(0
评论(0
编辑 
收藏 
举报

文章来源于互联网:我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)

THE END
分享
二维码