专业的编程技术博客社区

网站首页 > 博客文章 正文

使用Vue.js,Webpack和Material Design开发一个渐进的Web应用

baijin 2024-10-21 03:38:55 博客文章 4 ℃ 0 评论

渐进式Web应用程序是未来。越来越多的大公司开始与他们合作(例如:Twitter)。

想象一下,一个Web应用程序,你可以在地铁里浏览,通过用户感兴趣通知内容,最新的数据或是应用程序的导航来吸引你的用户,这样你就可以得到你用户对PWAs(谷歌推出的“小程序”增强型网页应用) 中功能的总的看法。

一个渐进式的Web应用(PWA)也是一个Web应用程序,但它提供了一种用户体验。PWAs受益于现代网络技术的不断创新(Service Workers、原生API,JS框架)和不断提高的Web应用的质量标准。

如果你想了解更多关于PWAs的内容,请访问谷歌的开发者页面。

来看看下面的PWA!它看起来像一个本地的应用程序,不是吗?

从开发商的角度来看,PWAs在本地应用有巨大的优势。它基本上就是一个网站,所以:

  1. 你可以用你想要的任何框架来编写它们;

  2. 一套代码来管理它们:它是跨平台和跨设备(代码由用户的浏览器执行);

  3. 易于推广销售:无需通过各种应用中心或者应用商店去下载。

然而,在2017年初,PWAs仍然面临一些限制:

  1. Safari浏览器不支持一些基本的PWAs的特点,如Service workers,但苹果似乎正在准备支持它;

  2. 仍然不支持一些原生的函数。

这篇文章的目的

本文的目的是通过使用VueJS和Webpack,从零开始,创建一个基本的但完整的渐进式Web应用程序。我们的应用程序将满足所有简介公布要求:渐进的,反应灵敏,独立连接等等,以及告诉大家通过PWAs可以实现什么的一个概述如:像原生一样流畅的应用,脱机模式,有原生特色的界面,通知推送。

为了保持一定的挑战性,我们要建立一个关于猫的图片消息应用程序:CropChat!

cropchat用户有一个能够看到猫的照片的主要流程,打开查看详细信息和发布新的猫的照片(先从互联网,然后从设备里或相机)。

本文将分为几个部分,将陆续出版:

  1. 创建一个单页应用VueJS、Webpack和Material Design精简版

  2. 通过远程的API连接应用程序、Vue-Resource和vuefire

  3. 与Service Workers实现脱机模式

  4. 存取设备上照相机拍摄的照片

  5. 通过访问设备上传图片

  6. 实现推送通知

  7. 接入本地设备

我们的PWA的基本组成

我们的渐进式Web应用程序将基于您将喜欢的最新潮的组件!

  1. vue js 2 视图层:通过使用Material Design Lite来帮助我们渲染我们的视图层

  2. Vue-Router:处理SPA的路由

  3. Vue-Resource & Vuefire:与一个已有的Firebase数据库通信

  4. Service Worker:处理脱机模式下保持数据更新

  5. Webpack & Vue-loader:构建我们的应用程序,提供热加载,es2016和预处理。

让我们从第1部分开始!

创建一个精简版的单页应用通过VueJS、Webpack和Material Design Lite

如果你不熟悉vue.js 2,我强烈建议你看看官方教程。

建立vue.js应用基础

我们将使用Vue CLI脚手架创建应用:

npm install -g vue-cli

Vue CLI会同时带来一些模板,我们将选择pwa的模板。Vue CLI将创建一个虚拟的vuejs应用,通过使用Webpack、vue-loader (hot reload!)一个给定的manifest文件和通过service workers的基本离线支持。

Vue pwa模板是建立在Vue Webpack顶部的模板。Webpack是一个功能强大的JavaScript应用程序,将负责我们的构建、模块打包等过程。

vue init pwa cropchat

可能有人会问几个问题。那下面是我使用的配置:

项目名称?cropchat

项目简称?cropchat

项目描述?一个猫图片消息应用程序

作者?Charles BOCHET charlesb@theodo.fr

用什么开发?Vue

安装Vue-router?是的。

使用ESLint?是的,选择一个ESLint预设的标准。

Karma + Mocha来设置单元测试?是的

用Nightwatch建立端到端的测试?不

vue-cli · Generated "cropchat".

此过程将创建一个项目文件夹包括下面的子文件夹:

  1. 建立:包含Webpack和vue-loader的配置文件

  2. 配置:包含我们的应用程序的配置(环境,参数…)

  3. src:放置我们应用程序的源代码

  4. 静态:图像,CSS和其他公共文件

  5. 测试:由Karma & Mocha负责的单元测试文件

然后运行:

cd cropchatnpm install
npm run dev

这将打开您的浏览器localhost:8080:

Manifest.json文件:安装你的应用程序

一个PWA应用程序的最大优点是易于安装和共享。所有的Web应用程序,它们都提供了一个有效的manifest.json文件在index.html文件安装的时候。

Vue PWA模板提供了一个默认的manifest.json文件文件。

编辑static/manifest.json文件,自定义项目信息:

{

"name": "cropchat",

"short_name": "cropchat",

"icons": [

{

"src": "/static/img/icons/cropchat-icon-64x64.png",

"sizes": "192x192",

"type": "image/png"

},

{

"src": "/static/img/icons/cropchat-icon-128x128.png",

"sizes": "128x128",

"type": "image/png"

},

{

"src": "/static/img/icons/cropchat-icon-256x256.png",

"sizes": "256x256",

"type": "image/png"

},

{

"src": "/static/img/icons/cropchat-icon-512x512.png",

"sizes": "512x512",

"type": "image/png"

}

],

"start_url": "/",

"display": "fullscreen",

"orientation": "portrait",

"background_color": "#2196f3",

"theme_color": "#2196f3"

}

你可以在这里设置一些东西:

  1. 应用程序名称;

  2. 应用程序的图标,将显示在设备主屏幕和屏幕(你可以在GitHub库中找到cropchat官方图标);

  3. 启动地址url;

  4. 显示与定位;

  5. 背景和主题颜色。

Mozilla开发者网站上有清单选项的完整列表。

看一下index.html会看到这个manifest已经链接到这里:

<link rel="manifest" href="<%= htmlWebpackPlugin.files.publicPath %>static/manifest.json">

请确保在index.html头部中还声明了一个viewport:

<meta name="viewport" content="width=device-width, initial-scale=1">

这样就OK了!让我们尝试在移动设备上安装CropChat。有许多方法来访问我们的localhost:8080从外网的移动设备上。我最喜欢的一个是使用ngrok。

ngrok是一种服务,可以让你将本地环境和一个远端外网的DNS建立一个通道,即反向代理,最重要它是免费的!

安装它:

npm install -g ngrok

然后,跑一下:

ngrok http 8080

这应该给你follolwing输出:

ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online 
Version 2.1.18 
Region United States (us) 
Web Interface http://127.0.0.1:4040 
Forwarding http://5ef29506.ngrok.io -> localhost:8080 
Forwarding https://5ef29506.ngrok.io -> localhost:8080 
Connections 
ttl opn rt1 rt5 p50 p90 
39 3 0.01 0.01 120.01 881.89

浏览ngrok的网址:http://5ef29506.ngrok.io这样ngrok就与你的智能手机连上了,你可以添加它到你的设备的桌面!

cropchat的源代码可以在GitHub上找到。

要了解更多关于ngrok,你可以阅读Matthieu Auger的文章:Expose your local environment to the world with ngrok.

创建视图框架和处理路由

现在,我们有一个基础了,我们将开始建设cropchat。cropchat的三个视图:

  1. 主页视图:将显示猫图片显示为一个图像列表

  2. 细节视图:显示特定的猫图像细节(从主页视图单击进入)

  3. 后视图:允许用户发布新图片。

创建一个 src/components/HomeView.vue,查看以下框架:

<template>

<ul class="list">

</ul>

</template>

<script>

export default {

}

</script>

<style scoped>

.list {

width: 100%;

padding: 0;

}

</style>

同样的道理,src/component/DetailView.vue

<template>

<div class="card-image">

</div>

</template>

<script>

export default {

}

</script>

<style scoped>

</style>

同样的道理,src/components/PostView.vue

<template>

<div class="waiting">

Not yet available

</div>

</template>

<script>

export default {

}

</script>

<style scoped>

.waiting {

padding: 10px;

color: #555;

}

</style>

最后, 更新路由文件src/router/index.js:

import Vue from 'vue'

import Router from 'vue-router'

import HomeView from '@/components/HomeView'

import DetailView from '@/components/DetailView'

import PostView from '@/components/PostView'

Vue.use(Router)

export default new Router({

routes: [

{

path: '/',

name: 'home',

component: HomeView

},

{

path: '/detail/:id',

name: 'detail',

component: DetailView

},

{

path: '/post',

name: 'post',

component: PostView

}

]

})

删除没有使用的hello.vue视图文件。你应该直接看到你的移动应用程序的变化(Hot reload是很nb的,不是吗?)

安装 Material Design Lite

如果你不知道 Material Design Lite,那就太low了?这是一个nb的框架,可以让你轻松地在Web应用程序上实现界面设计。

你可以在这里找到一个详尽的文档:GetMDL.io

更新cropchat的依赖:

npm install material-design-lite --save

更新src/App.vue 文件为组件导入MDL样式并加载MDL模块:

<script>

require('material-design-lite')

...

</script>

<style>

@import url('https://fonts.googleapis.com/icon?family=Material+Icons');

@import url('https://code.getmdl.io/1.2.1/material.blue-red.min.css');

</style>

提供带有导航条的单页应用程序:

更新主组件的模版文件src/App.vue

<template>

<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">

<header class="mdl-layout__header">

<div class="mdl-layout__header-row">

<span class="mdl-layout-title">CropChat</span>

</div>

</header>

<div class="mdl-layout__drawer">

<span class="mdl-layout-title">CropChat</span>

<nav class="mdl-navigation">

<router-link class="mdl-navigation__link" to="/" @click.native="hideMenu">Home</router-link>

<router-link class="mdl-navigation__link" to="/post" @click.native="hideMenu">Post a picture</router-link>

</nav>

</div>

<main class="mdl-layout__content">

<div class="page-content">

<router-view></router-view>

</div>

</main>

</div>

</template>

由于 Material Design Lite 不是专门用来构建单页应用程序的,所以当用户单击菜单链接时,我们需要隐藏一下菜单:

<script>

...

export default {

name: 'app',

methods: {

hideMenu: function () {

document.getElementsByClassName('mdl-layout__drawer')[0].classList.remove('is-visible')

document.getElementsByClassName('mdl-layout__obfuscator')[0].classList.remove('is-visible')

}

}

}

</script>

填充视图并应用在应用程序

我们还没有连接到后端服务器。我们现在将使用一些测试数据。

建一个数据文件src/data.js

export default {

pictures: [

{

'id': 0,

'url': 'https://25.media.tumblr.com/tumblr_m40h4ksiUa1qbyxr0o1_400.gif',

'comment': 'A cat game',

'info': 'Posted by Kevin on Friday'

},

{

'id': 1,

'url': 'https://25.media.tumblr.com/tumblr_lhd7n9Qec01qgnva2o1_500.jpg',

'comment': 'Tatoo & cat',

'info': 'Posted by Charles on Tuesday'

},

{

'id': 2,

'url': 'https://24.media.tumblr.com/tumblr_m4j2atctRm1qejbiro1_1280.jpg',

'comment': 'Santa cat',

'info': 'Posted by Richard on Monday'

},

{

'id': 3,

'url': 'https://25.media.tumblr.com/tumblr_m3rmbwhVB51qhwmnpo1_1280.jpg',

'comment': 'Mexico cat',

'info': 'Posted by Richard on Monday'

},

{

'id': 4,

'url': 'https://24.media.tumblr.com/tumblr_mceknxs4Lo1qd477zo1_500.jpg',

'comment': 'Curious cat',

'info': 'Posted by Richard on Monday'

}

]

}

引用数据通过这个文件HomeView.vue 。 Vue脚本中链接图片对应细节视图。

<script>

import data from '../data'

export default {

methods: {

displayDetails (id) {

this.$router.push({name: 'detail', params: { id: id }})

}

},

data () {

return {

'pictures': data.pictures

}

}

}

</script>

更新HomeView.vue模版和样式:

<template>

<div>

<div class="mdl-grid">

<div class="mdl-cell mdl-cell--3-col mdl-cell mdl-cell--1-col-tablet mdl-cell--hide-phone"></div>

<div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-phone">

<div v-for="picture in this.pictures" class="image-card" @click="displayDetails(picture.id)">

<div class="image-card__picture">

<img :src="picture.url" />

</div>

<div class="image-card__comment mdl-card__actions">

<span>{{ picture.comment }}</span>

</div>

</div>

</div>

</div>

<router-link class="add-picture-button mdl-button mdl-js-button mdl-button--fab mdl-button--colored" to="/post">

<i class="material-icons">add</i>

</router-link>

</div>

</template>

...

<style scoped>

.add-picture-button {

position: fixed;

right: 24px;

bottom: 24px;

z-index: 998;

}

.image-card {

position: relative;

margin-bottom: 8px;

}

.image-card__picture > img {

width:100%;

}

.image-card__comment {

position: absolute;

bottom: 0;

height: 52px;

padding: 16px;

text-align: right;

background: rgba(0, 0, 0, 0.5);

}

.image-card__comment > span {

color: #fff;

font-size: 14px;

font-weight: bold;

}

</style>

DetailView.vue继续增强效果:

<template>

<div class="mdl-grid">

<div class="mdl-cell mdl-cell--8-col">

<div class="picture">

<img :src="this.pictures[$route.params.id].url" />

</div>

<div class="info">

<span>{{ this.pictures[$route.params.id].info }}</span>

</div>

</div>

<div class="mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet">

<div class="comment">

<span>{{ this.pictures[$route.params.id].comment }}</span>

</div>

<div class="actions">

<router-link class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored" to="/post">

ANSWER

</router-link>

</div>

</div>

</div>

</template>

<script>

import data from '../data'

export default {

data () {

return {

'pictures': data.pictures

}

}

}

</script>

<style scoped>

.picture > img {

color: #fff;

width:100%;

}

.info {

text-align: right;

padding: 5px;

color: #555;

font-size: 10px;

}

.comment {

padding: 10px;

color: #555;

}

.actions {

text-align: center;

}

</style>

最后的效果是什么样?

我们完成了, CropChat 跑!

源代码可以在这个GitHub库中找:https://github.com/charlesbochet/vuejspwa

结论

我希望我能让你相信的vuejs和Webpack的能力,可以很快的不太费力的创建一个Web应用。概括起来:

  • Vue CLI命令行可以创建一个虚拟vuejs + WebPACK的应用

  • 通过添加一个manifest.json文件使您的Web应用程序的可以安装

  • 使用Vue-Router和Material Design创建一个用户可以体验应用程序

然而,CropChat不是一个渐进的Web应用程序:让我们看看PWA的要求清单:

很多的需求还没有满足。这将是我们后面要讲的。

本文来自charlesBochet,敏捷开发高手,web工程师。由汇智网的小智翻译。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表