38

使用Vue构建桌面应用程序:Vuido

 5 years ago
source link: http://www.infoq.com/cn/articles/building-a-desktop-app-with-vue-vuido?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我非常喜欢 Vue 。这是个优秀的框架,可以帮助我们搭建完美的web应用程序。但真正神奇的地方是你不仅仅可以用它搭建web应用程序,还可以使用 WeexNativeScript-Vue 创建本地移动应用程序。你还可以选择 ElectronVuido 库,搭建桌面应用程序。在本文中,我将介绍如何使用Vuido库创建本地应用程序。

Vuido是一款基于Vue.js的框架,由 Michał Męciński 开发,用于创建本地桌面应用程序。使用Vuido开发的应用程序可以运行在Windows、OS X和Linux平台,使用本地的GUI组件,不需要Electron库。

Vuido使用为每款桌面平台提供本地GUI组件的 libui 库,以及Node.js的 libui-node 绑定。

我们将搭建什么?

为了便于介绍,我们将开发一款简单的应用程序,用于查看你指定城市的当前天气。我们将使用 OpenWeatherMap API 获取真实数据。

如果你想查阅完整的代码,请点击 这里

安装

正如Vuido文档所述,要开发桌面应用程序有些预先条件。根据平台的不同,预先条件也不同:

Windows平台

windows-build-tools

Visual Studio 2013的Visual C++ Redistributable

Linux平台

build-essential

GTK+ 3

OSX平台

Xcode

我将使用OSX平台来开发,我已经安装了Xcode了。

同时,你还需要安装 vue-cli 。(如果你要使用Vue CLI 3,你还需要@vue/cli-init。)

运行以下的命令创建新项目:

vue init mimecorg/vuido-webpack-template my-project

在安装完成之后,你将在src文件夹中发现MainWindow.vue组件,代码如下所示:

<template>
  <Window title="some-app" width="400" height="100" margined v-on:close="exit">
    <Box>
      <Text>Welcome to your Vuido application!</Text>
    </Box>
  </Window>
</template>

<script>
export default {
  methods: {
    exit() {
      this.$exit();
    },
  },
};
</script>

然后运行build和start指令,你将看到非常简单的桌面应用程序窗口:

14711-1539371156246.png

接下来,我们就可以创建有趣的程序了。

搭建应用程序

首先你需要了解Vuido使用本地组件。因为没有我们熟悉的HTML标签和CSS样式,只有一组本地的GUI组件,可以与不同桌面平台兼容。Vuido搭建的应用程序在每个平台都有原生的感觉。

这有利有弊,因为你不能搭建完全定制化外观的应用程序,但是它比用Electron搭建的应用程序更加轻量级,且速度更快。

内置组件的完整列表可以在Vuido文档的 这一部分 找到。

我最初想创建一个可以显示用户指定城市天气情况的应用程序,以便我可以测试简单的用户交互和API调用。首先我需要一个有按钮的输入框。同时,我将窗口大小调整为400x150px:

<Window title="Weather" width="400" height="150" margined v-on:close="exit">
    <Box padded>
        <Box horizontal padded>
        <TextInput stretchy></TextInput>
        <Button>Search</Button>
    </Box>
    </Box>
</Window>

要让输入框和按钮水平对齐,并在它们之间保持点距离,我们需要一个有horizontal和padded属性的<Box>容器。Box和HTML的div元素相似,它就像包含组件并对齐组件的包装器。

TextInput是输入框,它的stretchy属性表示它可以根据填充所需的空间拉伸。

现在我们的应用程序看起来是这样的:

15512-1539371157284.png

现在向组件数据添加query属性,为输入框的该属性设置为v-model。同时,如果没有输入字符串,我们应该禁用按钮。这对我来说很棘手,因为我试了非常熟悉的disabled属性,但实际上在Vuido中应该使用 enabled 属性。所以我们的输入框现在是这样的:

<Box horizontal padded>
    <TextInput v-model="query" stretchy></TextInput>
    <Button :enabled="!!query">Search</Button>
</Box>

实现API调用

接下来我们需要根据给定的城市查询字符串来获取当前的天气情况。

我使用 OpenWeatherMap API来获取天气数据。它提供了很多内容,但我们只需要Current weather data这一部分。你可以在 这里 测试JSON响应示例。

所以,要想获得数据,我需要添加axios库:

npm install --save axios

然后导入它,设置好base URL和OpenWeatherMap API key变量:

import axios from 'axios';
axios.defaults.baseURL = 'http://api.openweathermap.org/data/2.5'
const apiKey = process.env.API_KEY;

之后,我们要添加一些天气数据的新属性,以及从API获取数据的方法:

export default {
  data() {
    return {
      query: '',
      error: false,
      city: '',
      country: '',
      weatherDescription: '',
      temp: null,
      tempMin: null,
      tempMax: null,
      humidity: null,
    };
  },
  methods: {
    exit() {
      this.$exit();
    },
    showWeather() {
      axios
        .get(
          `/weather?q=${this.query}&units=metric&&appid=${apiKey}`,
        )
        .then(response => {
          this.city = response.data.name;
          this.country = response.data.sys.country;
          this.weatherDescription = response.data.weather[0].description;
          this.temp = response.data.main.temp;
          this.tempMin = response.data.main.temp_min;
          this.tempMax = response.data.main.temp_max;
          this.humidity = response.data.main.humidity;
          this.error = false;
        })
        .catch(() => {
          this.error = true;
          this.city = '';
        });
    },
  },
};

现在需要给按钮添加新的方法,改变模板,展示所有的数据,或在输入的字段不能匹配任何现有城市的时候给出报错信息。

<Window title="Weather in your city" width="400" height="150" margined v-on:close="exit">
    <Box padded>
    <Box horizontal padded>
        <TextInput stretchy v-model="query"/>
        <Button :enabled="!!query" @click="showWeather">Search</Button>
    </Box>
    <Separator horizontal/>
    <Group margined>
        <Box padded>
          <Text v-if="error">There is no such city in the database</Text>
          <Box v-if="!!city">
            <Box padded horizontal>
              <Text stretchy>{{city}}, {{country}}</Text>
              <Text>{{temp}}°C</Text>
            </Box>
            <Text>{{weatherDescription}}</Text>
            <Separator horizontal/>
            <Box padded horizontal>
              <Text stretchy>Min: {{tempMin}}°C</Text>
              <Text stretchy>Max: {{tempMax}}°C</Text>
              <Text stretchy>Humidity: {{humidity}}%</Text>
            </Box>
          </Box>
        </Box>
    </Group>
    </Box>
</Window>

正如你所看到的,第一个框是我们在前面创建的输入容器。下面是Separator,一条分割不同部分的水平线。接下来是Group,这是个有边框的内容容器。

在Group中你将会看到组合好的许多组件:包含简单文字内容的Text,作为容器的Box以及Separator。现在你的应用程序看起来是这样的:

13613-1539371157874.png

封装

我认为封装Vuido应用程序最简单最好的方式是库作者推荐的一个方法。他建议使用他自己的 LaunchUILaunchUI Packager 库来封装,并分发应用程序给最终用户。

我已经安装了LaunchUI Packager:

npm install --global launchui-packager

之后我要在应用程序root文件夹运行以下指令:

launchui-packager weather-app 1.0 dist/main.min.js

上面的指令中,weather-app是应用程序名称,1.0是版本信息,dist/main.min.js是绑定文件的路径。

下面是我的应用程序的文件夹,大小是39Mb,这比作者所说的要多(文档中说最多20Mb),但也没多得太离谱。

10714-1539371156913.png

如果你试着运行,你会发现它启动得非常快(0.1秒左右)。

总结

优点:

  • 容易搭建
  • 和Electron应用程序相比,封装后的大小非常小
  • 文档很完善

缺点:

  • 外观不好看
  • 还没有正式发布(当前版本是0.2.0)

如果你需要搭建基础外观的小型快速应用程序,Vuido是一个很好的选择。它有非常清晰的文档,可能之后内置的组件会变得更多。

本文作者

8915-1539371157599.png

Natalia Tepluhina是热爱VueJS的前端开发人员。她还是Vue Vixens的CTO,Noob大会的讲师。

查看英文原文: Building a Desktop App with Vue: Vuido

感谢冬雨对本文的审校。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK