├── src
├── app.scss
├── pages
│ ├── class
│ │ ├── index.scss
│ │ ├── store.ts
│ │ └── index.tsx
│ ├── home
│ │ ├── index.scss
│ │ └── index.tsx
│ ├── useLocalStore
│ │ ├── index.scss
│ │ └── index.tsx
│ ├── useAsObservableSource
│ │ ├── index.scss
│ │ ├── index.tsx
│ │ └── multiplier.tsx
│ └── useContext
│ │ ├── index.scss
│ │ └── index.tsx
├── app.config.ts
├── store
│ ├── counter.ts
│ └── todo.ts
├── app.tsx
└── index.html
├── README.md
├── .eslintrc.js
├── .gitignore
├── config
├── dev.js
├── prod.js
└── index.js
├── .editorconfig
├── babel.config.js
├── project.config.json
├── global.d.ts
├── tsconfig.json
└── package.json
/src/app.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/pages/class/index.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/pages/home/index.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/pages/useLocalStore/index.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/pages/useAsObservableSource/index.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # taro-mobx-sample
2 | Taro mobx sample
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'extends': ['taro/react']
3 | }
4 |
--------------------------------------------------------------------------------
/src/pages/useContext/index.scss:
--------------------------------------------------------------------------------
1 | .completed {
2 | text-decoration: line-through;
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | deploy_versions/
3 | .temp/
4 | .rn_temp/
5 | node_modules/
6 | .DS_Store
7 |
--------------------------------------------------------------------------------
/config/dev.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | NODE_ENV: '"development"'
4 | },
5 | defineConstants: {
6 | },
7 | mini: {},
8 | h5: {}
9 | }
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | // babel-preset-taro 更多选项和默认值:
2 | // https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md
3 | module.exports = {
4 | presets: [
5 | ['taro', {
6 | framework: 'react',
7 | ts: true
8 | }]
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "miniprogramRoot": "dist/",
3 | "projectname": "taro-mobx-sample",
4 | "description": "",
5 | "appid": "touristappid",
6 | "setting": {
7 | "urlCheck": true,
8 | "es6": false,
9 | "postcss": false,
10 | "minified": false
11 | },
12 | "compileType": "miniprogram",
13 | "simulatorType": "wechat",
14 | "simulatorPluginLibVersion": {},
15 | "condition": {}
16 | }
--------------------------------------------------------------------------------
/src/app.config.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | pages: [
3 | 'pages/home/index',
4 | 'pages/class/index',
5 | 'pages/useContext/index',
6 | 'pages/useLocalStore/index',
7 | 'pages/useAsObservableSource/index'
8 | ],
9 | window: {
10 | backgroundTextStyle: 'light',
11 | navigationBarBackgroundColor: '#fff',
12 | navigationBarTitleText: 'WeChat',
13 | navigationBarTextStyle: 'black'
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/pages/class/store.ts:
--------------------------------------------------------------------------------
1 | import { observable, action } from 'mobx'
2 |
3 | class CounterStore {
4 | @observable counter = 0
5 |
6 | @action.bound
7 | increment() {
8 | this.counter++
9 | }
10 |
11 | @action.bound
12 | decrement() {
13 | this.counter--
14 | }
15 |
16 | @action.bound
17 | incrementAsync() {
18 | setTimeout(() => this.counter++, 1000)
19 | }
20 | }
21 |
22 | export default new CounterStore()
--------------------------------------------------------------------------------
/src/store/counter.ts:
--------------------------------------------------------------------------------
1 | import { observable, action } from 'mobx'
2 |
3 | class CounterStore {
4 | @observable counter = 0
5 |
6 | @action.bound
7 | increment() {
8 | this.counter++
9 | }
10 |
11 | @action.bound
12 | decrement() {
13 | this.counter--
14 | }
15 |
16 | @action.bound
17 | incrementAsync() {
18 | setTimeout(() => this.counter++, 1000)
19 | }
20 | }
21 |
22 | export default new CounterStore()
--------------------------------------------------------------------------------
/config/prod.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | NODE_ENV: '"production"'
4 | },
5 | defineConstants: {
6 | },
7 | mini: {},
8 | h5: {
9 | /**
10 | * 如果h5端编译后体积过大,可以使用webpack-bundle-analyzer插件对打包体积进行分析。
11 | * 参考代码如下:
12 | * webpackChain (chain) {
13 | * chain.plugin('analyzer')
14 | * .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [])
15 | * }
16 | */
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/pages/useAsObservableSource/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react'
2 | import { View, Button } from '@tarojs/components'
3 | import Multiplier from './multiplier'
4 |
5 | import './index.scss'
6 |
7 | function Index() {
8 | const [multiplier, setMultiplier] = useState(0)
9 | return (
10 |
11 |
12 |
13 |
14 | )
15 | }
16 |
17 | export default Index
--------------------------------------------------------------------------------
/src/app.tsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Provider } from 'mobx-react'
3 |
4 | import counterStore from './store/counter'
5 |
6 | import './app.scss'
7 |
8 | class App extends Component {
9 | componentDidMount () {}
10 |
11 | componentDidShow () {}
12 |
13 | componentDidHide () {}
14 |
15 | componentDidCatchError () {}
16 |
17 | // this.props.children 就是要渲染的页面
18 | render () {
19 | return (
20 |
21 | {this.props.children}
22 |
23 | )
24 | }
25 | }
26 |
27 | export default App
28 |
--------------------------------------------------------------------------------
/src/pages/class/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { View, Button, Text } from '@tarojs/components'
3 | import { inject, observer } from 'mobx-react'
4 |
5 | @inject('counterStore')
6 | @observer
7 | export default class Index extends Component {
8 | render() {
9 | return (
10 |
11 |
12 |
13 |
14 | {this.props.counterStore.counter}
15 |
16 | )
17 | }
18 | }
--------------------------------------------------------------------------------
/global.d.ts:
--------------------------------------------------------------------------------
1 | declare module "*.png";
2 | declare module "*.gif";
3 | declare module "*.jpg";
4 | declare module "*.jpeg";
5 | declare module "*.svg";
6 | declare module "*.css";
7 | declare module "*.less";
8 | declare module "*.scss";
9 | declare module "*.sass";
10 | declare module "*.styl";
11 |
12 | declare namespace JSX {
13 | interface IntrinsicElements {
14 | 'import': React.DetailedHTMLProps, HTMLEmbedElement>
15 | }
16 | }
17 |
18 | // @ts-ignore
19 | declare const process: {
20 | env: {
21 | TARO_ENV: 'weapp' | 'swan' | 'alipay' | 'h5' | 'rn' | 'tt' | 'quickapp' | 'qq' | 'jd';
22 | [key: string]: any;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/pages/home/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Taro from '@tarojs/taro'
3 | import { Button, View } from '@tarojs/components'
4 |
5 | function Index() {
6 | const goPage = (page) => {
7 | Taro.navigateTo({
8 | url: `/pages/${page}/index`
9 | })
10 | }
11 |
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 | )
20 | }
21 |
22 | export default Index;
--------------------------------------------------------------------------------
/src/store/todo.ts:
--------------------------------------------------------------------------------
1 | import { observable, computed, action } from 'mobx'
2 | import { createContext } from 'react';
3 |
4 | interface Todo {
5 | id: number;
6 | title: string;
7 | completed: boolean;
8 | }
9 |
10 | class TodoStore {
11 | @observable todos: Todo[] = []
12 |
13 | @computed get total() {
14 | return this.todos.length
15 | }
16 |
17 | @computed get completedCount() {
18 | return this.todos.filter(item => item.completed).length
19 | }
20 |
21 | @action.bound
22 | add() {
23 | const id = this.todos.length + 1;
24 | this.todos.push({
25 | id,
26 | title: `Item ${id}`,
27 | completed: false
28 | })
29 | }
30 |
31 | @action.bound
32 | toggle(index) {
33 | this.todos[index].completed = !this.todos[index].completed
34 | }
35 | }
36 |
37 | export default createContext(new TodoStore())
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "module": "commonjs",
5 | "removeComments": false,
6 | "preserveConstEnums": true,
7 | "moduleResolution": "node",
8 | "experimentalDecorators": true,
9 | "noImplicitAny": false,
10 | "allowSyntheticDefaultImports": true,
11 | "outDir": "lib",
12 | "noUnusedLocals": true,
13 | "noUnusedParameters": true,
14 | "strictNullChecks": true,
15 | "sourceMap": true,
16 | "baseUrl": ".",
17 | "rootDir": ".",
18 | "jsx": "react",
19 | "jsxFactory": "React.createElement",
20 | "allowJs": true,
21 | "resolveJsonModule": true,
22 | "typeRoots": [
23 | "node_modules/@types",
24 | "global.d.ts"
25 | ]
26 | },
27 | "exclude": [
28 | "node_modules",
29 | "dist"
30 | ],
31 | "compileOnSave": false
32 | }
33 |
--------------------------------------------------------------------------------
/src/pages/useAsObservableSource/multiplier.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Button, Text } from '@tarojs/components'
3 | import { useAsObservableSource, useLocalStore, observer } from 'mobx-react'
4 |
5 | function Multiplier(props) {
6 | const observableProps = useAsObservableSource(props)
7 | const store = useLocalStore(() => ({
8 | counter: 1,
9 | get multiplied() {
10 | return observableProps.multiplier * store.counter
11 | },
12 | increment() {
13 | store.counter += 1
14 | }
15 | }))
16 |
17 | const { multiplier } = observableProps
18 | const { multiplied, counter, increment } = store
19 | return (
20 |
21 | multiplier({multiplier}) * counter({counter}) = {multiplied}
22 |
23 |
24 | )
25 | }
26 |
27 | export default observer(Multiplier)
--------------------------------------------------------------------------------
/src/pages/useContext/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from 'react'
2 | import { View, Text, Button } from '@tarojs/components'
3 | import { observer } from 'mobx-react'
4 | import Store from '../../store/todo'
5 | import './index.scss'
6 |
7 | function Index() {
8 | const { todos, toggle, add, completedCount, total } = useContext(Store) as any
9 | const list = todos.map((todo, index) => {
10 | const { title, id, completed } = todo
11 | return (
12 | toggle(index)}
15 | className={completed ? 'completed' : 'un-completed' }
16 | >
17 | {title}
18 |
19 | )
20 | })
21 | return (
22 |
23 | {list}
24 | 已完成:{ completedCount } / {total}
25 |
26 |
27 | )
28 | }
29 |
30 | export default observer(Index);
--------------------------------------------------------------------------------
/src/pages/useLocalStore/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { View, Text, Button } from '@tarojs/components'
3 | import { useLocalStore, observer } from 'mobx-react'
4 | import 'mobx-react-lite/batchingForReactDom'
5 |
6 | import './index.scss'
7 |
8 | function Index() {
9 | const store = useLocalStore(() => ({
10 | counter: 0,
11 | increment() {
12 | store.counter++
13 | },
14 | decrement() {
15 | store.counter--
16 | },
17 | incrementAsync() {
18 | setTimeout(() => store.counter++, 1000)
19 | }
20 | }))
21 |
22 | const { counter, increment, decrement, incrementAsync } = store;
23 | return (
24 |
25 |
26 |
27 |
28 | {counter}
29 |
30 | )
31 | }
32 |
33 | export default observer(Index)
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | projectName: 'taro-mobx-sample',
3 | date: '2020-7-3',
4 | designWidth: 750,
5 | deviceRatio: {
6 | 640: 2.34 / 2,
7 | 750: 1,
8 | 828: 1.81 / 2
9 | },
10 | sourceRoot: 'src',
11 | outputRoot: 'dist',
12 | plugins: [],
13 | defineConstants: {
14 | },
15 | copy: {
16 | patterns: [
17 | ],
18 | options: {
19 | }
20 | },
21 | framework: 'react',
22 | mini: {
23 | postcss: {
24 | pxtransform: {
25 | enable: true,
26 | config: {
27 |
28 | }
29 | },
30 | url: {
31 | enable: true,
32 | config: {
33 | limit: 1024 // 设定转换尺寸上限
34 | }
35 | },
36 | cssModules: {
37 | enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
38 | config: {
39 | namingPattern: 'module', // 转换模式,取值为 global/module
40 | generateScopedName: '[name]__[local]___[hash:base64:5]'
41 | }
42 | }
43 | }
44 | },
45 | h5: {
46 | publicPath: '/',
47 | staticDirectory: 'static',
48 | postcss: {
49 | autoprefixer: {
50 | enable: true,
51 | config: {
52 | }
53 | },
54 | cssModules: {
55 | enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
56 | config: {
57 | namingPattern: 'module', // 转换模式,取值为 global/module
58 | generateScopedName: '[name]__[local]___[hash:base64:5]'
59 | }
60 | }
61 | }
62 | }
63 | }
64 |
65 | module.exports = function (merge) {
66 | if (process.env.NODE_ENV === 'development') {
67 | return merge({}, config, require('./dev'))
68 | }
69 | return merge({}, config, require('./prod'))
70 | }
71 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "taro-mobx-sample",
3 | "version": "1.0.0",
4 | "private": true,
5 | "description": "",
6 | "templateInfo": {
7 | "name": "mobx",
8 | "typescript": true,
9 | "css": "sass"
10 | },
11 | "scripts": {
12 | "build:weapp": "taro build --type weapp",
13 | "build:swan": "taro build --type swan",
14 | "build:alipay": "taro build --type alipay",
15 | "build:tt": "taro build --type tt",
16 | "build:h5": "taro build --type h5",
17 | "build:rn": "taro build --type rn",
18 | "build:qq": "taro build --type qq",
19 | "build:quickapp": "taro build --type quickapp",
20 | "dev:weapp": "npm run build:weapp -- --watch",
21 | "dev:swan": "npm run build:swan -- --watch",
22 | "dev:alipay": "npm run build:alipay -- --watch",
23 | "dev:tt": "npm run build:tt -- --watch",
24 | "dev:h5": "npm run build:h5 -- --watch",
25 | "dev:rn": "npm run build:rn -- --watch",
26 | "dev:qq": "npm run build:qq -- --watch",
27 | "dev:quickapp": "npm run build:quickapp -- --watch"
28 | },
29 | "browserslist": [
30 | "last 3 versions",
31 | "Android >= 4.1",
32 | "ios >= 8"
33 | ],
34 | "author": "",
35 | "license": "MIT",
36 | "dependencies": {
37 | "@babel/runtime": "^7.7.7",
38 | "@tarojs/runtime": "3.0.2",
39 | "@tarojs/taro": "3.0.2",
40 | "@tarojs/components": "3.0.2",
41 | "mobx": "^4.8.0",
42 | "mobx-react": "^6.1.4",
43 | "react-dom": "^16.10.0",
44 | "@tarojs/react": "3.0.2",
45 | "react": "^16.10.0"
46 | },
47 | "devDependencies": {
48 | "@types/webpack-env": "^1.13.6",
49 | "@types/react": "^16.0.0",
50 | "@tarojs/mini-runner": "3.0.2",
51 | "@babel/core": "^7.8.0",
52 | "@tarojs/webpack-runner": "3.0.2",
53 | "babel-preset-taro": "3.0.2",
54 | "eslint-config-taro": "3.0.2",
55 | "eslint": "^6.8.0",
56 | "eslint-plugin-react": "^7.8.2",
57 | "eslint-plugin-import": "^2.12.0",
58 | "eslint-plugin-react-hooks": "^1.6.1",
59 | "stylelint": "9.3.0",
60 | "@typescript-eslint/parser": "^2.x",
61 | "@typescript-eslint/eslint-plugin": "^2.x",
62 | "typescript": "^3.7.0"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------