---
author: Bestony
category: 软件开发
comments_data: []
count:
  commentnum: 0
  favtimes: 0
  likes: 0
  sharetimes: 0
  viewnum: 3720
date: '2020-02-03 11:34:00'
editorchoice: false
excerpt: 在这一部分中，借助 Vue 的 method 、onkeydown 和 computed 实现了页面基本逻辑的构建。并借助 Vuetify 的一些基础组件来构建页面。
fromurl: ''
id: 11848
islctt: false
largepic: /images/p/202002/03/113623vii331edifue131i.jpg
permalink: /article-11848-1.html
pic: /images/p/202002/03/113623vii331edifue131i.jpg.thumb.jpg
related:
- displayorder: 0
  raid: 11844
- displayorder: 0
  raid: 11851
reviewer: ''
selector: ''
summary: 在这一部分中，借助 Vue 的 method 、onkeydown 和 computed 实现了页面基本逻辑的构建。并借助 Vuetify 的一些基础组件来构建页面。
tags:
- 云开发
thumb: false
title: 跟我学 “Linux” 小程序 Web 版开发（二）：UI 开发
titlepic: true
translator: ''
updated: '2020-02-03 11:34:00'
---

![](/images/p/202002/03/113623vii331edifue131i.jpg)


### 工作量分析


在我们进行这部分开发的时候，接下来我们需要进行相应的功能安排和分类。


![](/images/p/202002/03/113440r3csjjygyzx6ygnc.png)


简单看来，我需要开发 3 个页面：


1. **首页**：首页负责用户默认访问。
2. **列表页**：列表页面则是在搜索过程中，如果有多个结果，则进入到列表页面。如果有单个结果，则应该进入到详情页面。
3. **结果页**：结果页负责显示命令的具体的翻译结果。


根据实际的工作拆分组件的化，我需要有一个 Layout 组件来负责整体的页面的环境渲染。但是，考虑到组件的复用，于是决定将首页的 Title 进行优化，使首页和详情页保持一致。


![](/images/p/202002/03/113440g90kd0lf2h06blof.png)


在新版的布局情况下，我就可以将顶部的的 title 和底部的 Link 放在最外侧的组件中。


### 创建 Router & Page


在思考情况后，接下来我们来创建 Router 和 Page。首先，删除 `views` 下的 `About.vue`（因为这个页面我们不需要）。然后创建 `List.vue` 和 `Result.vue` ，用作后续的开发准备。


![](/images/p/202002/03/113441anvwv7iiirew7zne.png)


创建完成后，修改 `router/index.js` 中的 `routes` 部分：



```
const routes = [
  {
    path: '/',
    name: 'home',
    component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')
  },
  {
    path: '/list/:cmd',
    name: 'list',
    component: () => import(/* webpackChunkName: "list" */ '../views/List.vue')
  },
  {
    path: '/cmd/:cmd',
    name: 'command',
    component: () => import(/* webpackChunkName: "cmd" */ '../views/Result.vue')
  }
]
```

完成定义后，我们就可以通过形如 <https://tldr.linux.cn/list/ls> 和 <https://tldr.linux.cn/cmd/ls> 这样的方式来访问具体的命令了。


### 定义页面


接下来需要编写 Home、List 和 Result 这三个页面。由于这三个页面在内容方面没有太多的可以借鉴的点，所以我们更多关注于使用页面中 `<script>` 的部分。



```
<template>
  <div class="home">
        <v-text-field
        v-model="cmd"
        @keydown="onKeyDown"
        autofocus
        ></v-text-field>        
  </div>
</template>

<script>
export default {
  name: 'home',
  data:function(){
    return {
      cmd:""
    }
  },
  methods:{
    onKeyDown: function(e)  {
     
    }
  },
  computed:{
    isLoaded:function(){
        return !this.loaded
    }
  }
}
</script>
```

上述代码是我在三个页面几乎都会使用到的结构，删除其中的一些无用的代码以后，基本上在每个页面都可以看到。这里我重点说一下其中的一些比较特殊的用法。


首先第一个是在 `v-text-field` 上加入的 `@keydown="onKeyDown"` 这个绑定，这个绑定将会帮助实现用户点击回车以后，自动触发事件。这样在用户输入完命令后，按下回车就自动执行后续的操作，而不需要再移动鼠标指针去点击按钮启动搜索。


其次，在 `v-text-field` 上加入了`autofocus` ，来实现进入页面后，自动为输入框加入`focus`，从而实现页面加载完成后，用户就可以输入命令。


这样的一些配置，可以让**用户的体验做到最好**。


除此之外，我还用到了 `computed` ，来做数据调整，确保我可以控制内容。


### 一些小的特性的点


#### 使用骨架图来优化体验


由于我们的应用在列表页面和详情页面存在数据的查询时间，为了让应用在加载的时候，不会因为加载中而退出页面，我加入了 v-skeleton-loader 组件，这样用户在数据查询的时候，看骨架图来缓解用户的焦虑。


![](/images/p/202002/03/113441pjrrtjd90q09rk3q.png)


在组件层面，我配置了 `v-if` 来做显示的控制，并将 type 设置为 `card,article,card,article` 来实现多样化的组件加载支持。



```
 <v-skeleton-loader
    v-if="isLoaded"
    type="card,article,card,article"
    min-height="800"
    ></v-skeleton-loader>
```

### 总结


在这一部分中，借助 Vue 的 `method` 、`onkeydown` 和 `computed` 实现了页面基本逻辑的构建。并借助 Vuetify 的一些基础组件来构建页面。


在这一部分，我想告诉大家的更多是在 UI 的部分，我们在做的时候不仅仅需要考虑的是界面，更多还需要考虑在 UX 侧体验的优化，组件库提供给我们的配置项目，可以优化产品体验。