使用Vue构建Ionic混合APP系列教程(四):数据存储
来源:互联网 发布:团伙研发作弊软件 编辑:程序博客网 时间:2024/06/03 13:04
大多数应用程序基本都需要保存一些在应用重新加载时需要的数据。我们经常使用用户设备上的本地存储来实现。当使用Ionic/Angular的时候,我们可以简单的使用Ionic内置的Storage API,并不需要知道背后的原理——Ionic会自动地选择最合适的存储方式。
再说一次,在Vue里我们没有现成的东西可以用,是安装一个库还是自己搭建解决方案全决定于我们自己。
在这篇教程,我们将扩展上篇教程里的Reddit应用,允许我们可以切换多个不同的subreddits方法。我们会存储用户的选择,当重新进入应用时会使用保存的数据。
开始
本教程紧跟前面的教程。如果你想一步步走, 你应该先完成之前的教程。不过, 您可以轻松地将本教程中的概念应用于任何应用程序, 因此如果您不想完成前面的教程也无大碍。
localForage 和 Ionic 存储模块
进入代码之前我们先讨论一点理论知识。我们会在ionic-angular库的Ionic Storage Module代码的基础上进行。具体点说,我们会参考 the Storage class的代码。
Ionic使用 localForage来和存储后台交互。通过使用 localForage我们可以有一些外部的API进行交互,不用管具体使用了哪个技术:Native SQLite storage, IndexedDB, WebSQL或者是简单的浏览器的local storage。
Ionic的存储模块封装了localForage ,而且根据可用的选择,去自动的设置合适的方法。这意味着如果你使用Cordova搭建的应用而且安装了SQLite 插件,那这个就会用于存储数据。如果SQLite 不可用它会回头使用IndexedDB 或者 WebSQL,如果这些都不可用那么local storage API就是最后的选择 。
我们想在Ionic/Vue应用里模拟这种行为,所以来看看Ionic是怎么做的。我们会专注于 storage.ts里最关键的部分:
import LocalForage from 'localforage';import CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
localForage 库必须安装和导入,如果我们想支持使用SQLite,还需要安装CordovaSQLiteDriver 。使用SQLite 的好处是我们不需要担心浏览器数据被系统清空。
constructor(config: StorageConfig) { this._dbPromise = new Promise((resolve, reject) => { let db: LocalForage; const defaultConfig = getDefaultConfig(); const actualConfig = Object.assign(defaultConfig, config || {}); LocalForage.defineDriver(CordovaSQLiteDriver).then(() => { db = LocalForage.createInstance(actualConfig); }) .then(() => db.setDriver(this._getDriverOrder(actualConfig.driverOrder))) .then(() => { this._driver = db.driver(); resolve(db); }) .catch(reason => reject(reason)); });}
在构造函数constructor 里创建了一个实例化localForage的Promise。我们先要定义CordovaSQLiteDriver,一旦完成我们可以用构造对象创建一个Local Forage实例。
默认的Ionic Storage API 的构造是这样的:
{ name: '_ionicstorage', storeName: '_ionickv', driverOrder: ['sqlite', 'indexeddb', 'websql', 'localstorage']};
这个配置最重要的部分就是drivers,这决定了存储机制的性能。在这个例子里,sqlite是首选,localstorage 是最后的选择。为了确保这些驱动命名正确,用到了下面这个方法:
_getDriverOrder(driverOrder) { return driverOrder.map((driver) => { switch (driver) { case 'sqlite': return CordovaSQLiteDriver._driver; case 'indexeddb': return LocalForage.INDEXEDDB; case 'websql': return LocalForage.WEBSQL; case 'localstorage': return LocalForage.LOCALSTORAGE; } });}
这个方法会映射driver order数组来使用由localForage提供的合适的值。如果你不熟悉数组的map方法,你可能会对这个视频感兴趣。基本概念就是map操作会对数组里的每个元素进行一些转换。在这个例子里,我们会使用由localForage定义的实际的名称来替换数组里的值。
剩下的API基本都是一些围绕着localForage 的方法的简单封装:
get(key: string): Promise<any> { return this._dbPromise.then(db => db.getItem(key));}set(key: string, value: any): Promise<any> { return this._dbPromise.then(db => db.setItem(key, value));}
所有Ionic存储模块在做的事情就是通过检查dbPromise 的类成员,来确保存储已经完成了正确的实例化。一旦promise完成,getItem 和setItem 方法就会被用来在存储空间里设置(或者销毁)值。
在Vue里创建Storage服务
我们可以直接在我们的组件里使用localForage 接口,但是如果我们想做的像Ionic的Staorage API那样智能,把它独立到它自己的服务里会更有意义。我们将使用刚才学习到的那些概念,用它们在Ionic/Vue应用里来创建一个Storage服务。
首先,我们需要安装必要的依赖库:
npm install localforage --savenpm install localforage-cordovasqlitedriver --save
创建src/services/storage.js文件:
import LocalForage from 'localforage';import CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';export default class Storage { dbPromise; constructor(){ this.dbPromise = new Promise((resolve, reject) => { let db; let config = { name: '_vuestorage', storeName: '_vuekv', driverOrder: ['sqlite', 'indexeddb', 'websql', 'localstorage'] } LocalForage.defineDriver(CordovaSQLiteDriver).then(() => { db = LocalForage.createInstance(config); }) .then(() => db.setDriver(this.getDriverOrder(config.driverOrder))) .then(() => { resolve(db); }) .catch(reason => reject(reason)); }); } ready(){ return this.dbPromise; } getDriverOrder(driverOrder){ return driverOrder.map((driver) => { switch(driver){ case 'sqlite': return CordovaSQLiteDriver._driver; case 'indexeddb': return LocalForage.INDEXEDDB; case 'websql': return LocalForage.WEBSQL; case 'localstorage': return LocalForage.LOCALSTORAGE; } }); } get(key){ return this.dbPromise.then(db => db.getItem(key)); } set(key, value){ return this.dbPromise.then(db => db.setItem(key, value)); } remove(key){ return this.dbPromise.then(db => db.removeItem(key)); } clear(){ return this.dbPromise.then(db => db.clear()); }}
这只是Ionic Storage API 相同代码的简化版——它或多或少地以同样的方式起作用。为了看起来更友好我留下了一些功能没封装,但是你没有理由不去实现剩下的那些功能。
使用Storage服务保存和获取数据
现在,我们要做的是使用我们的服务。保存数据很简单:
storage.set('something', 'somevalue');
获取数据:
storage.get('something').then((value) => { console.log(value);});
修改 src/components/HelloWorld.vue如下:
<template> <ion-app> <ion-header> <ion-navbar> <ion-title>REDDIT!</ion-title> </ion-navbar> </ion-header> <ion-content> <ion-button @click="switchSubreddit('funny')">Funny</ion-button> <ion-button @click="switchSubreddit('gifs')">Gifs</ion-button> <ion-button @click="switchSubreddit('worldnews')">Worldnews</ion-button> <ion-list> <ion-item v-for="post in posts" v-bind:key="post.data.id"> {{post.data.title}} </ion-item> </ion-list> </ion-content> </ion-app></template><script>import RedditService from '../services/reddit';import Storage from '../services/storage';const storage = new Storage();export default { name: 'HelloWorld', data () { return { posts: [] } }, created() { storage.get('subreddit').then((value) => { if(value === null){ value = 'gifs'; } RedditService.getPosts(value).then(response => { this.posts = response.body.data.children; }); }); }, methods: { switchSubreddit(subreddit){ storage.set('subreddit', subreddit); RedditService.getPosts(subreddit).then(response => { this.posts = response.body.data.children; }); } }}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped>h1, h2 { font-weight: normal;}ul { list-style-type: none; padding: 0;}li { display: inline-block; margin: 0 10px;}a { color: #42b983;}</style>
我们引入了刚创建的storage服务,我们首先在created里调用了get方法。created 方法会在组件已创建就执行,所以它会立即检查storage里subreddit存不存在,如果存在,subreddit值会被用于调用API,如果不存在,默认的使用gifs代替。
我们也设置了三个按钮以不同的值触发switchSubreddit 。这个方法会保存新的值到storage,然后调用getPosts。下次应用重启的时候,保存在Storage的值会代替默认的gifs 被使用。
备注:如果你没有看之前的教程,你可能不知道如何使用这个模板的组件。
总结
没有做太多额外的工作,我们就创建了自己的storage服务,和Ionic/Angular应用的存储机制一样的便利和有用。
- 使用Vue构建Ionic混合APP系列教程(四):数据存储
- 使用Vue构建Ionic混合APP系列教程(一):Vue语法 vs Angular语法
- 使用Vue构建Ionic混合APP系列教程(二):导航
- 使用Vue构建Ionic混合APP系列教程(三):服务和Http请求
- 【D3.js数据可视化系列教程】--(四)使用数据
- 使用Ionic构建Hybrid App初体验
- Cordova+Angularjs+Ionic混合开发入门篇(四)—— 插件的简单使用
- 【D3.V3.js数据可视化系列教程】--(四)使用数据
- ionic app中如何使用PouchDB+SQLite作为本地存储
- Flexigrid系列使用教程(四)同时操作选择的多条数据
- 混合APP开发环境配置-ionic、cordora
- 关于混合app 开发框架Ionic
- ionic 数据存储 StorageHelper
- 使用PVCS系列软件构建配置管理环境(四)
- Vue, App与我(四)
- 【ionic App问题总结系列】ionic登录拦截机制-使用Modal作为登录框
- Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(四)调整 App.vue 和 router 路由
- Vue2+VueRouter2+Webpack+Axios 构建项目实战2017重制版(四)调整 App.vue 和 router 路由
- 10027---kafka集群环境搭建
- SpringCloud(2):架构流程、Eureka配置、代码
- 2017/12/21 第十二天培训
- Asp.net MVC WebApi项目的自动接口文档及测试功能打开方法
- Pycharm如何添加第三方库和插件
- 使用Vue构建Ionic混合APP系列教程(四):数据存储
- C实现银行家算法(避免死锁)
- [数学公式]常用数学公式(一)——高等数学
- jquery UI dialog 缓存问题解决
- List使用
- JavaWeb学习基本内容一 tomacat 和 程序目录
- Android模块化(一)——模块化概念和路由
- asp.net core 全局注入
- java实现文件的下载功能