Heim > Web-Frontend > js-Tutorial > Hauptteil

React-Native+Mobx implementiert Mall-APP

php中世界最好的语言
Freigeben: 2018-04-13 15:04:25
Original
3080 Leute haben es durchsucht

Dieses Mal werde ich Ihnen React-Native+Mobx zur Implementierung der Mall-APP vorstellen. Was sind die Vorsichtsmaßnahmen für die Implementierung der Mall-APP mit React-Native+Mobx? Fall. Werfen wir einen Blick darauf.

Ich habe kürzlich WeChat-Miniprogramme gelernt. Während des Lernprozesses habe ich wxapp-mall gesehen Ich fand dieses WeChat-Applet-Projekt sehr gut und die Benutzeroberfläche war recht klein und frisch, also habe ich es geklont, um es zu studieren. Als ich mir den Quellcode ansah, war es für mich wirklich überraschend Verwendet nicht viel Code, um umfangreiche Funktionen zu implementieren. Wäre es also schwierig, React-Native zu verwenden, um ein kleines Projekt wie dieses zu erstellen? Darüber hinaus kann das Schreiben eines Codesatzes sowohl für Android als auch für iOS ausgeführt werden kleine Programme...), wie wäre es, eines zu schreiben? Mit dieser Idee im Hinterkopf habe ich direkt Schreiben wir ein React-Native-Init-Projekt (๑•̀ㅂ•́)و✧

Technische Rahmenbedingungen und Komponenten

  • React „16.0.0“

  • react-native „0.51.0“

  • mobx: „3.4.1“

  • mobx-react: „4.3.5“

  • react-navigation: „1.0.0-beta.21“

  • React-Native-Scrollable-Tab-View: „0.8.0“

  • React-Native-Easy-Toast: „1.0.9“

  • react-native-loading-spinner-overlay: „0.5.2“

Warum Mobx verwenden?

Mobx ist ein skalierbares Zustandsverwaltungstool, das einfacher als React-Redux und schneller zu starten ist. Da es in diesem kleinen Projekt keine Hintergrunddienstschnittstelle gibt, werden alle lokalen gefälschten Daten verwendet, um die Implementierung zu simulieren Produkte durchsuchen =>Zum Warenkorb hinzufügen=>Zur Kasse=>Warenkorb leeren=>Produkte in ihren ursprünglichen Zustand zurückversetzen In einem solchen Prozess wird Mobx verwendet, um alle Daten und den Produktstatus zu verwalten (ob es ausgewählt ist, ob es dem Warenkorb hinzugefügt wird), sodass alle Seiten Daten austauschen und den Status des Produkts ändern können, und die Daten und Produkte zwischen Seiten können geteilt werden. Der Status wird synchron aktualisiert. Insbesondere werde ich im Folgenden meine Erfahrungen mit der Verwendung von Mobx und einige aufgetretene Fallstricke mitteilen, wie Mobx zur Implementierung dieses Prozesses verwendet wird.

Starten

Zuerst reaktionsnativ Starten Sie ein Projekt und installieren Sie dann mit Yarn oder NPM alle Abhängigkeiten und Komponenten. Da bei Verwendung von Mobx der Decorator in ES7 verwendet wird, müssen Sie ihn installieren babel-plugin-transform-decorators-legacy Plug-in und fügen Sie dann einige Inhalte unter der .babelrc-Datei hinzu.

{ 
 "presets": ["react-native"], 
 "plugins": ["transform-decorators-legacy"]
}
Nach dem Login kopieren

Projektstruktur

|-- android 
|-- ios
|-- node_modules
|-- src
 |-- common // 公用组件
 |-- img // 静态图片
 |-- mobx // mobx store
 |-- newGoods.js // 首页新品数据
 |-- cartGoods.js // 购物车数据
 |-- categoryGoods.js // 分类页数据
 |-- store.js // store仓库,管理数据状态 
 |-- scene 
 |-- Cart // 购物车页面
 |-- Category // 分类页
 |-- Home // 首页
 |-- ItemDetail // 商品信息页
 |-- Mine // 我的页面 
 |-- Root.js // root.js主要内容是配置react-navigation(导航器)
|-- index.js // 主入口
Nach dem Login kopieren

Informationen zur Konfiguration und Verwendung von React-Navigation finden Sie in der Root.js-Datei in der offiziellen Dokumentation und in diesem Blog. In diesen beiden Artikeln habe ich Antworten auf Fragen zu React-Navigation gefunden. Die relevante Konfiguration der Reaktionsnavigation, die Verwendungsmethoden und das Seitenlayout des Projekts sowie das Schreiben von Komponenten werden hier nicht näher erläutert, da sie relativ einfach sind. Es geht vielmehr darum, einige Logiken und Methoden der Mobx-Implementierungsfunktionen zu diskutieren. Die Komponenten unter dem Bildschirmordner sind alle kommentiert (°ー°〃)

Reden wir hauptsächlich über Mobx

1. Datenspeicherung und -erfassung

Diese werden mithilfe gefälschter Daten simuliert und implementiert. Schreiben Sie ganz am Anfang die Datenstruktur der gefälschten Daten, zum Beispiel:

"data":
 [{ 
 "name": '那么大西瓜',
 "price": '2.0', 
 "image": require('../img/a11.png'), 
 "count": 0, 
 "isSelected": true
 },...]
Nach dem Login kopieren
store.js im Mobx-Ordner, hier werden hauptsächlich die Daten aller von der App verwendeten Produkte gespeichert und die Logik und der Status von der Komponente in eine unabhängige, testbare Einheit verschoben. Diese Einheit kann verwendet werden unten

import { observable, computed, action } from 'mobx'
import cartGoods from './cartGoods'
import newGoods from './newGoods'import categoryGoods from './catetgoryGoods'
/** 
* 根store 
* @class RootStore 
* CartStore 为购物车页面的数据 
* NewGoodsStore 为首页的数据 
* categoryGoodsStore 为分类页的数据 
*/
class RootStore { 
 constructor() { 
 this.CartStore = new CartStore(cartGoods,this) 
 this.NewGoodsStore = new NewGoodsStore(newGoods,this) 
 this.categoryGoodsStore = new categoryGoodsStore(categoryGoods,this) 
}}
Class CartStore{
 @observable allDatas = {} 
 constructor(data,rootStore) { 
 this.allDatas = data 
 this.rootStore = rootStore 
 }
}
Class NewGoodsStore{
 ...跟上面一样
}
Class categoryGoodsStore{
 ...跟上面一样
}
// 返回RootStore实例 
export default new RootStore()
Nach dem Login kopieren
RootStore wird hier verwendet, um alle Shops zu instanziieren (Warenkorb, Homepage und Kategorieseiten haben ihre eigenen Stores),

Auf diese Weise können Filialen über RootStore verwaltet und betrieben werden und so untereinander kommunizieren und Referenzen austauschen.

Zweitens wird die @observable-Methode von Mobx zum Speichern von Daten verwendet, wodurch die Daten in einen Beobachter umgewandelt werden. Wenn der Benutzer die Ansicht bedient und sich die Daten ändern, kann die Ansicht automatisch mit dem von React-Mobx bereitgestellten @observer aktualisiert werden ist sehr praktisch.

Um den Rootstore von Mobx in reaktionsnative Komponenten einzubinden, muss er außerdem über den von mobx-react bereitgestellten Anbieter implementiert werden. Unter Root.js habe ich Folgendes geschrieben:

// 全局注册并注入mobx的Rootstore实例,首页新品,分类页,商品详情页,购物车页面都要用到store
import {Provider} from 'mobx-react'
// 获取store实例
import store from './mobx/store' 
const Navigation = () => { 
 return ( 
 <provider> 
 <navigator></navigator> 
 </provider> 
)}
Nach dem Login kopieren
Kann die Rootstore-Instanz nach dem Einfügen in den Komponentenbaum durch direkte Verwendung von this.props.rootStore in der Komponente abgerufen werden?

‘'不是的”,我们还需要在要用到Rootstore的组件里,要加点小玩意,在 HomeScreen.js (首页)中这么写:

import { inject, observer } from 'mobx-react'
@inject('rootStore') // 缓存rootStore,也就是在Root.js注入的
@observerexport default class HomeScreen extends Component {
 ......
}
Nach dem Login kopieren

加上了 @inject('rootStore') ,我们就可以愉快地使用 this.props.rootStore 来拿到我们想要的数据啦^_^ ,同样,在商品信息,分类页,购物车页面js下,也需要使用 @inject('rootStore') 来实现数据的获取,然后再一步步地把数据传到它们的子组件中。

2. 加入购物车的实现

在首页和分类页中,都可以点击跳转到商品信息页,然后再加入到购物车里

React-Native+Mobx implementiert Mall-APP 

实现方法 :

在itemDetail.js下,也就是商品信息页面下,加入购物车的逻辑是这样子的:

addCart(value) {
 if(this.state.num == 0) { 
 this.refs.toast.show('添加数量不能为0哦~')
 return; 
} 
// 加入购物车页面的列表上 
// 点一次,购物车数据同步刷新 
this.updateCartScreen(value)
this.refs.toast.show('添加成功^_^请前往购物车页面查看')
}
// 同步更新购物车页面的数据
updateCartScreen (value) { 
 let name = this.props.navigation.state.params.value.name;
 // 判断购物车页面是否存在同样名字的物品 
 let index;
 if(this.props.rootStore.CartStore)
 index = this.props.rootStore.CartStore.allDatas.data.findIndex(e => (e.name === name))
 // 不存在
 if(index == -1) {
 this.props.rootStore.CartStore.allDatas.data.push(value) 
 // 加入CartStore里
 // 并让购物车icon更新
 let length = this.props.rootStore.CartStore.allDatas.data.length 
 this.props.rootStore.CartStore.allDatas.data[length - 1].count += this.state.num}
 else { 
 // 增加对应name的count
 this.props.rootStore.CartStore.allDatas.data[index].count += this.state.num 
 }}
Nach dem Login kopieren

简单的说,先获取水果的名称name,然后再去判断Mobx的CartStore里面是否存在同样的名称的水果,如果有就增加对应name的数量count,如果没有,就往CartStore中增加数据,切换到购物车页面时,视图会同步刷新,看到已加入购物车的水果。

3.改变商品状态同步更新视图

当用户在购物车页面操作商品状态时,数据改变时,视图会跟着同步刷新。

例如,商品的增加数量,减少数据,选中状态,商品全选和商品删除,总价格都会随着商品的数量变化而变化。

 

图又来了~~

实现上面的功能,主要用到了Mobx提供的action方法,action是用来修改状态的,也就是用action来修改商品的各种状态(数量,选中状态...),这些action,我是写在 store.js 的 CartStore类 中的,下面贴出代码

// 购物车store
class CartStore {
 @observable allDatas = {}
 constructor(data,rootStore) { 
 this.allDatas = data
 this.rootStore = rootStore
}
 //加
 @action
 add(money) { 
 this.allDatas.totalMoney += money 
}
 // 减
 @action
 reduce(money) { 
 this.allDatas.totalMoney -= money 
}
 // checkbox true 
 @action
 checkTrue(money) {
 this.allDatas.totalMoney += money
 } 
 // checkbox false
 @action
 checkFalse(money) {
 if(this.allDatas.totalMoney  {
 this.allDatas.totalMoney += e.count * e.price})}
 else { 
 this.allDatas.totalMoney = 0 
}}
 // check全选 
 @action 
 check() { 
 // 所有checkbox为true时全选才为true 
 let allTrue = this.allDatas.data.every(v => ( v.isSelected === true ))
 if(allTrue) { 
 this.allDatas.isAllSelected = true 
 }else { 
 this.allDatas.isAllSelected = false 
}}
 // 删 
 @action
 delect(name) { 
 this.allDatas.data = this.allDatas.data.filter (e => (e.name !== name ))
}
 // 总价格
 @computed get totalMoney() { 
 let money = 0;
 let arr = this.allDatas.data.filter(e => (e.isSelected === true))
 arr.forEach(e=> (money += e.price * e.count))
 return money
}}
Nach dem Login kopieren

所有修改商品状态的逻辑都在上面代码里面,其中,totalMoney是用了Mobx的@computed方法,totalMoney是依赖于CartStore的data数据,也就是商品数据,但data的值发生改变时,它会重新计算返回。如果了解vue的话,这个就相当于vue的计算属性。

4.结算商品

商品结算和清空购物车的逻辑都写在 CartCheckOut.js 里面,实现过程很简单,贴上代码吧:

// 付款
 pay() { 
 Alert.alert('您好',`总计:¥ ${this.props.mobx.CartStore.totalMoney}`, 
 {text: '确认支付', onPress: () => this.clear()},
 {text: '下次再买', onPress: () => null}],{ cancelable: false })}
 // 清空购物车 
 clear() { 
 this.setState({visible: !this.state.visible})
 setTimeout(()=>{ 
 this.setState({ loadText: '支付成功!欢迎下次光临!' }) 
 setTimeout(()=> { this.setState({ visible: false },
 ()=>{ this.props.mobx.CartStore.allDatas.data = []
 // 把所有商品count都变为0 
 this.props.mobx.NewGoodsStore.allDatas.data.forEach(e=> e.count = 0)
 this.props.mobx.categoryGoodsStore.allDatas.data.forEach( e => { 
 e.detail.forEach(value => { value.count = 0 }) 
 })
 })},1500)},2000)}
Nach dem Login kopieren

这里主要用了setTimeout和一些方法来模拟实现 支付中 => 支付完成 => 清空购物车 => 还原商品状态。

好了,这个流程就搞定了,哈哈。

5.遇到的小坑

1.我写了一个数组的乱序方法,里面有用到 Array.isArray() 这个方法来判断是否为数组,但是,我用这个乱序函数时,想用来搞乱store里面的数组时,发现一直没有执行,觉得很奇怪。然后我直接用 Array.isArray() 这个方法来判断store里面的数组,返回的一直都是false。。。于是我就懵了。。。后来,我去看了Mobx官方文档,终于找到了答案。原来,store里面存放的数组,并不是真正的数组,而是 obverableArray ,如果要让 Array.isArray() 判断为true,就要在取到store的数组时,加个. slice() 方法,或者 Array.from() 都可以。

2.同样,也是obverableArray的问题。在购物车页面时,我用了FlatList来渲染购物车的item,起初,当我增加商品到购物车,发现购物车页面并没有刷新。有了上面的踩坑经验,我认为是obverableArray引起的,因为FlatList的data接收的是real Array,于是,我用这样的方法:

@computed get dataSource() { 
 return this.props.rootStore.CartStore.allDatas.data.slice();
}
...
<flatlist></flatlist>
Nach dem Login kopieren

于是,购物车视图就可以自动地刷新了,在官方文档上也有写到。

3.还有一个就是自己粗心造成的。我写完这个项目后,和朋友出去玩时,顺便发给朋友看看,他在删除商品时发现,从上往下删删不了,从下往上删就可以。后来我用模拟器测试也是如此,于是就去看看删除商品的逻辑,发现没有问题,再去看store的数据,发现也是可以同步更新的,只是视图没有更新,很神奇,于是我又在FlatList去找原因,终于,原因找到了,主要是在keyExtractor里面,用index是不可以的,要用name来作为key,因为我删除商品方法其实是根据name来删的,而不是index,所以用index来作为FlatList的Item的key时是会出现bug的。

_keyExtractor = (item,index)=> { 
 // 千万别用index,不然在删购物车数据时,如果从第一个item开始删会产生节点渲染错乱的bug 
 return item.name
}
Nach dem Login kopieren

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Angular实现可添加删除与计算总金额效果插件

AngularJS实现猜数字小游戏

Das obige ist der detaillierte Inhalt vonReact-Native+Mobx implementiert Mall-APP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage