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


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

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

效果图

image-20221018221613004


代码仓库

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。 简单的计算属性

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


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

单文件组件应该总是让

SideBarHref.vue

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

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

image-20221018214833334

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

image-20221018215234879

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





SideBar.vue

遮蔽层

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

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

image-20221018215658616

我们使用自定义类名实现过渡动画。类名也是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