网站首页 > 博客文章 正文
渐进式Web应用程序是未来。越来越多的大公司开始与他们合作(例如:Twitter)。
想象一下,一个Web应用程序,你可以在地铁里浏览,通过用户感兴趣通知内容,最新的数据或是应用程序的导航来吸引你的用户,这样你就可以得到你用户对PWAs(谷歌推出的“小程序”增强型网页应用) 中功能的总的看法。
一个渐进式的Web应用(PWA)也是一个Web应用程序,但它提供了一种用户体验。PWAs受益于现代网络技术的不断创新(Service Workers、原生API,JS框架)和不断提高的Web应用的质量标准。
如果你想了解更多关于PWAs的内容,请访问谷歌的开发者页面。
来看看下面的PWA!它看起来像一个本地的应用程序,不是吗?
从开发商的角度来看,PWAs在本地应用有巨大的优势。它基本上就是一个网站,所以:
你可以用你想要的任何框架来编写它们;
一套代码来管理它们:它是跨平台和跨设备(代码由用户的浏览器执行);
易于推广销售:无需通过各种应用中心或者应用商店去下载。
然而,在2017年初,PWAs仍然面临一些限制:
Safari浏览器不支持一些基本的PWAs的特点,如Service workers,但苹果似乎正在准备支持它;
仍然不支持一些原生的函数。
这篇文章的目的
本文的目的是通过使用VueJS和Webpack,从零开始,创建一个基本的但完整的渐进式Web应用程序。我们的应用程序将满足所有简介公布要求:渐进的,反应灵敏,独立连接等等,以及告诉大家通过PWAs可以实现什么的一个概述如:像原生一样流畅的应用,脱机模式,有原生特色的界面,通知推送。
为了保持一定的挑战性,我们要建立一个关于猫的图片消息应用程序:CropChat!
cropchat用户有一个能够看到猫的照片的主要流程,打开查看详细信息和发布新的猫的照片(先从互联网,然后从设备里或相机)。
本文将分为几个部分,将陆续出版:
创建一个单页应用VueJS、Webpack和Material Design精简版
通过远程的API连接应用程序、Vue-Resource和vuefire
与Service Workers实现脱机模式
存取设备上照相机拍摄的照片
通过访问设备上传图片
实现推送通知
接入本地设备
我们的PWA的基本组成
我们的渐进式Web应用程序将基于您将喜欢的最新潮的组件!
vue js 2 视图层:通过使用Material Design Lite来帮助我们渲染我们的视图层
Vue-Router:处理SPA的路由
Vue-Resource & Vuefire:与一个已有的Firebase数据库通信
Service Worker:处理脱机模式下保持数据更新
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".
此过程将创建一个项目文件夹包括下面的子文件夹:
建立:包含Webpack和vue-loader的配置文件
配置:包含我们的应用程序的配置(环境,参数…)
src:放置我们应用程序的源代码
静态:图像,CSS和其他公共文件
测试:由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"
}
你可以在这里设置一些东西:
应用程序名称;
应用程序的图标,将显示在设备主屏幕和屏幕(你可以在GitHub库中找到cropchat官方图标);
启动地址url;
显示与定位;
背景和主题颜色。
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的三个视图:
主页视图:将显示猫图片显示为一个图像列表
细节视图:显示特定的猫图像细节(从主页视图单击进入)
后视图:允许用户发布新图片。
创建一个 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工程师。由汇智网的小智翻译。
猜你喜欢
- 2024-10-21 IntersectionObserver: 教你如何实现一个Vue无限滚动的组件
- 2024-10-21 支持服务器端渲染的移动端Vue组件——NutUI
- 2024-10-21 循序渐进Vue+Element 前端应用开发(6)—常规Element界面组件使用
- 2024-10-21 vue动态路由(支持嵌套路由)和动态菜单UI开发框架,无偿源码
- 2024-10-21 1小时搞定卡片拖拽、自动排列交换位置、拖拽数据存取
- 2024-10-21 如何使用 vue + intro 实现后台管理系统的新手引导
- 2024-10-21 零基础入门vue开发(vue开发步骤)
- 2024-10-21 前端路由与vue-router的基本用法(前端路由实现的两种方式)
- 2024-10-21 Electron-vue客户端开发总结(electron-vue官网)
- 2024-10-21 史上最全 vue-router 讲解 !!!(vue,router)
你 发表评论:
欢迎- 367℃用AI Agent治理微服务的复杂性问题|QCon
- 358℃初次使用IntelliJ IDEA新建Maven项目
- 357℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 351℃Maven技术方案最全手册(mavena)
- 348℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 346℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 345℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 342℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)