ソースを参照

docs: 添加培训资料

carver 1 年間 前
コミット
f795d8a4a1
2 ファイル変更551 行追加0 行削除
  1. 292 0
      前端培训资料-公众号.md
  2. 259 0
      前端培训资料-小程序.md

+ 292 - 0
前端培训资料-公众号.md

@@ -0,0 +1,292 @@
+# 前端培训资料 - 公众号
+
+## 前期准备
+
+1.node 环境配置在 14 及以上,可以使用 nvm 进行 node 环境管理
+
+2.下载微信开发者工具
+
+3.同步项目仓库
+
+## 启动
+
+1.命令行运行 `npm install` 或 `yarn` 安装依赖
+
+2.运行 `npm run start` 或 `yarn start` 启动项目
+
+3.微信开发者工具打开启动项目后的链接,即可预览项目
+
+## 上传
+
+开发完成之后,同步代码到远程仓库,Jenkins 上面手动点击构建,即可发布新版本
+
+太和公众号:
+
+- QA 环境 [Jenkins](https://jenkins.ywtinfo.com/view/qa/job/qa-fe-nfthwe/)
+
+- 生产环境 [Jenkins](https://jenkins.ywtinfo.com/view/product/job/product-fe-nfthwe-%E5%A4%AA%E5%92%8C%E5%85%AC%E4%BC%97%E5%8F%B7/)
+
+南方医务通公众号:
+
+- QA 环境 [Jenkins](https://jenkins.ywtinfo.com/view/qa/job/qa-fe-nfywtwe/)
+
+- 生产环境 [Jenkins](https://jenkins.ywtinfo.com/view/product/job/product-fe-nfywtwe%E5%8D%97%E6%96%B9%E5%8C%BB%E5%8A%A1%E9%80%9A/)
+
+### 项目结构
+
+```javascript
+.
+├── .babelrc        // babel配置
+├── .editorconfig   // 编辑器配置
+├── .eslintignore
+├── .eslintrc.js    // eslint配置
+├── .gitignore
+├── .gitmodules     // git submodule配置
+├── .postcssrc.js
+├── .prettierrc
+├── README.md
+├── build             // 构建配置目录
+│   ├── build-qa.js   // qa环境变量配置
+│   ├── build.js      // prod环境变量配置
+│   ├── check-versions.js
+│   ├── dev-client.js
+│   ├── dev-server.js  // dev环境express启动
+│   ├── mock.js        // mock数据
+│   ├── utils.js       // 样式相关构建工具库
+│   ├── webpack.base.conf.js  // webpack基本构建配置
+│   ├── webpack.dev.conf.js   // webpack dev环境构建配置
+│   ├── webpack.prod.conf.js  // webpack prod环境构建配置
+│   └── webpack.qa.conf.js    // webpack qa环境构建配置
+├── config
+│   ├── dev.env.js            // mobile端项目配置
+│   ├── index.js              // 项目配置汇总
+│   ├── prod.env.js           // mobile端prod项目配置
+│   ├── qa.env.js             // mobile端qa项目配置
+│   └── test.env.js           // 测试项目配置
+├── dist
+├── index.ejs                 // html模板
+├── node_modules
+├── package-lock.json
+├── package.json
+├── src
+│   ├── assets                // 项目资源
+│   ├── components            // 公共封装组件
+|   │   ├── Agreement         // 文本公告弹窗
+|   │   ├── AlertTitle        // 提示标语
+|   │   ├── App               // APP总容器
+|   │   ├── ChatItem          // 咨询聊天组件
+|   │   ├── DoctorInfoItem    // 医生信息
+|   │   ├── FilterModal       // 信息过滤组件
+|   │   ├── GHNotice          // 富文本公告弹窗
+|   │   ├── HomePages         // 首页公告
+|   │   ├── HospitalInfoItem  // 医院信息
+|   │   ├── MySegmentedControl  // 列表展示
+|   │   ├── MySwitch          // switch组件
+│   |   └── SexSelect         // 性别选择组件
+│   ├── const                 // 常量配置
+│   ├── containers            // 不同业务页面
+|   │   ├── App               // 项目入口/首页
+|   │   ├── CheckResult       // 检验检查模块
+|   │   ├── Consult           // 咨询模块
+|   │   ├── DoctorTeam        // 医生团队模块
+|   │   ├── DrugNews          // 快讯模块
+|   │   ├── Fl_up             // 随访模块
+|   │   ├── Global            // 医生信息
+|   │   ├── Guide             // 引导模块
+|   │   ├── Home
+|   │   ├── Me                // 个人中心
+|   │   ├── MedicalRecord     // 诊疗卡中心
+|   │   ├── NoMatch           // 404页面
+|   │   ├── OnlineOrder       // 线上订单
+|   │   ├── OrderCenter       // 订单中心
+|   │   ├── Pay               // 支付页面
+|   │   ├── PrivateDoctor     // 专职医生介绍页面
+|   │   ├── Report            // 远程会诊专家报告
+|   │   ├── Tools             // 签名模块
+|   │   ├── YuYueGuaHao       // 预约挂号-南方医科大学南方医院
+│   |   └── YuYueGuaHao-TaiHe // 预约挂号-太和
+│   ├── entry.js              // 项目入口
+│   ├── hoc                   // 高阶函数
+│   ├── reducers              // redux-reducer
+│   ├── routers               // 路由配置
+│   ├── saga                  // redux-saga
+│   ├── server                // 接口相关api
+│   ├── ui_module_components  // git submodule
+│   └── utils                 // 工具类
+└── static                    // 静态文件夹
+    ├── .gitkeep
+    ├── images
+    └── pdfjs-dist
+```
+
+### 生命周期
+
+react 所有生命周期都适用,项目中最常用的有以下两种:
+
+```js
+class App extends Component {
+  // 可以使用所有的 React 生命周期方法,一般在此阶段请求接口获取数据
+  componentDidMount() {}
+
+  // 页面状态或者变量更新时的生命周期
+  componentDidUpdate() {}
+
+  render() {
+    return <div></div>;
+  }
+}
+```
+
+---
+
+### 全局状态管理
+
+公众号使用 redux 相关套件进行全局状态管理
+
+以获取/修改用户信息为例:
+
+#### 设置 reduce 和 state
+
+在 `src/reduce/user.js` 中,创建 reduce,用于同步更改 state
+
+```js
+import { combineReducers } from "redux";
+
+const initState = {
+  name: ""
+};
+
+function userInfo(state = initState, action) {
+  switch (action.type) {
+    case "SAVE":
+      return Object.assign({}, state, action.info.user);
+    default:
+      return state;
+  }
+}
+
+export default combineReducers({
+  userInfo
+});
+```
+
+#### 设置 action
+
+在 `src/saga/user.js` 文件中,我们将创建一个 Saga 来监听所有的 INIT action,并触发一个 API 调用获取用户数据:
+
+```js
+import { call, put, takeEvery, takeLatest } from "redux-saga/effects";
+import Api from "...";
+
+// worker Saga : 将在 INIT action 被 dispatch 时调用
+function* fetchUser(action) {
+  const user = yield call(Api.fetchUser);
+  yield put({ type: "SAVE", info: { user } });
+}
+
+/*
+  在每个 `INIT` action 被 dispatch 时调用 fetchUser
+  允许并发(译注:即同时处理多个相同的 action)
+*/
+function* mySaga() {
+  yield takeEvery("INIT", fetchUser);
+}
+
+/*
+  也可以使用 takeLatest
+
+  不允许并发,dispatch 一个 `INIT` action 时,
+  如果在这之前已经有一个 `INIT` action 在处理中,
+  那么处理中的 action 会被取消,只会执行当前的
+*/
+function* mySaga() {
+  yield takeLatest("INIT", fetchUser);
+}
+
+export default mySaga;
+```
+
+#### 连接 Redux Store
+
+为了能跑起 Saga,我们需要使用 redux-saga 中间件将 Saga 与 Redux Store 建立连接。
+
+在项目的入口文件 `src/entry.js` 中建立连接:
+
+```js
+import { createStore, applyMiddleware } from "redux";
+import createSagaMiddleware from "redux-saga";
+
+import mySaga from "./sagas/user.js";
+import reducer from "./reduce/user.js";
+
+// create the saga middleware
+const sagaMiddleware = createSagaMiddleware();
+// mount it on the Store
+const store = createStore(reducer, applyMiddleware(sagaMiddleware));
+
+// then run the saga
+sagaMiddleware.run(mySaga);
+```
+
+#### 页面或者组件接入
+
+```js
+import React, { Component } from "react";
+import { withRouter } from "react-router-dom";
+import { connect } from "react-redux";
+
+class App extends Component {
+  state = {
+    nickName: ""
+  };
+
+  componentDidMount() {
+    this.props.onInitUserInfo(); // 调用 props 中的方法获取全局数据
+
+    this.getNickName(); // 直接调用接口获取数据
+  }
+
+  async getNickName() {
+    const result = await getNickNameApi();
+    this.setState({
+      nickName: result.nickName
+    });
+  }
+
+  render() {
+    const { userInfo } = this.props; // 从 props 中获取数据
+    return (
+      <div onClick={() => this.props.onChangeUserInfo({ name: "xxx" })}>
+        {userInfo.name}
+      </div>
+    );
+  }
+}
+
+const mapStateToProps = state => {
+  // 设置所要监听/获取的数据
+  return {
+    userInfo: state.userInfo
+  };
+};
+
+const mapDispatchToProps = dispatch => {
+  // 设置函数,触发 dispatch,获取/修改用户数据
+  return {
+    onInitUserInfo() {
+      // 初始化数据
+      dispatch({ type: "INIT" });
+    },
+    onChangeUserInfo(user) {
+      // 修改数据
+      dispatch({
+        type: "SAVE",
+        info: user
+      });
+    }
+  };
+};
+
+// 通过 redux 提供的 connect 方法,给 APP 组件的 props 中连接所需要的属性和方法
+export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));
+```

+ 259 - 0
前端培训资料-小程序.md

@@ -0,0 +1,259 @@
+# 前端培训资料 - 小程序
+
+## 前期准备
+
+1.node 环境配置在 14 及以上,可以使用 nvm 进行 node 环境管理
+
+2.下载微信开发者工具
+
+3.同步项目仓库
+
+## 启动
+
+1.命令行运行 `npm install` 或 `yarn` 安装依赖
+
+2.因为患者端小程序里面包含多个项目,所以一定要使用 `yarn replace:by` 命令,把项目配置切换到白云(其他项目同理,具体命令看 `package.json`)
+
+3.命令行运行 `npm run dev:weapp-by` 或 `yarn dev:weapp-by` 运行项目(其他项目同理,具体命令看 `package.json`)
+
+4.运行后,在项目根目录 `dist_by/weapp` 下会生成打包产物(其他项目同理,打包产物以 `dist_` 开头,加以特殊的项目名称后缀)
+
+5.微信开发者工具导入打包产物 `dist_by/weapp`,即可预览项目
+
+## 上传
+
+1.1.使用 `yarn build-qa:weapp-by` 打包编译白云小程序 QA 环境(其他项目同理,具体命令看 `package.json`)
+
+1.2.使用 `yarn build:weapp-by` 打包编译白云小程序生产环境(其他项目同理,具体命令看 `package.json`)
+
+2.打包后,在项目根目录 `dist_by/weapp` 下会生成打包产物(其他项目同理,打包产物以 `dist_` 开头,加以特殊的项目名称后缀)
+
+3.点击微信开发者工具右上方上传按钮,填写新版本好和基本信息,即可把打包产物上传到体验版(需微信后台管理员设置上传权限)
+
+## react 项目与 taro
+
+### 项目结构
+
+```js
+├── dist                        编译结果目录
+|
+├── config                      项目编译配置目录
+|   ├── index.js                默认配置
+|   ├── dev.js                  开发环境配置
+|   └── prod.js                 生产环境配置
+|
+├── src                         源码目录
+|   ├── pages                   页面文件目录
+|   |   └── index               index 页面目录
+|   |       ├── index.js        index 页面逻辑
+|   |       ├── index.css       index 页面样式
+|   |       └── index.config.js index 页面配置
+|   |
+|   ├── app.js                  项目入口文件
+|   ├── app.css                 项目总通用样式
+|   └── app.config.js           项目入口配置
+|
+├── project.config.json         微信小程序项目配置 project.config.json
+|
+├── babel.config.js             Babel 配置
+├── tsconfig.json               TypeScript 配置
+├── .eslintrc                   ESLint 配置
+|
+└── package.json
+```
+
+### 生命周期
+
+入口组件生命周期,项目入口使用,针对全局的请求或设置可在此阶段运行
+
+```js
+class App extends Component {
+  // 可以使用所有的 React 生命周期方法
+  componentDidMount() {}
+
+  // 对应 onLaunch
+  // 在小程序环境中对应 app 的 onLaunch
+  // 在此生命周期中通过访问 options 参数或调用 getCurrentInstance().router,可以访问到程序初始化参数
+  onLaunch() {}
+
+  // 对应 onShow,程序启动,或切前台时触发。
+  componentDidShow() {}
+
+  // 对应 onHide
+  // 程序切后台时触发。
+  componentDidHide() {}
+
+  render() {
+    // 在入口组件不会渲染任何内容,但我们可以在这里做类似于状态管理的事情
+    return (
+      <Provider store={store}>
+        {/* this.props.children 是将要被渲染的页面 */}
+        {this.props.children}
+      </Provider>
+    );
+  }
+}
+```
+
+页面组件生命周期,页面中使用
+
+```js
+class Index extends Component {
+  // 可以使用所有的 React 生命周期方法
+  componentDidMount() {} // 一般接口请求会放在此阶段进行
+
+  // onLoad
+  onLoad() {}
+
+  // onReady
+  onReady() {}
+
+  // 对应 onShow
+  componentDidShow() {}
+
+  // 对应 onHide
+  componentDidHide() {}
+
+  render() {
+    return <View className="index" />;
+  }
+}
+```
+
+---
+
+### 全局状态管理
+
+小程序使用 mobx 进行全局状态管理(如个人信息,授权信息等),以下以简化后的个人信息为例:
+
+#### 设置初始值
+
+在项目目录 `src/store/index.js` 中,设置初始值
+
+```JS
+import { observable } from "mobx";
+
+const userInfo = observable({ // 此对象就是可以监听的对象
+  nickname: "",
+  initData(res) { // 初始化时调用
+    this.nickname = res.nickname;
+  },
+  bindUser(res) { // 变更状态时调用
+    this.nickname = res.nickname;
+  }
+});
+export default userInfo;
+```
+
+#### 全局设置
+
+必须在项目目录入口文件 `src/app.js` 中设置全局 store
+
+```JS
+import userInfo from "./store/index.js";
+import { Provider } from "mobx-react";
+
+const store = {
+  userInfo,
+};
+
+class App extends Component {
+
+  render() {
+    return <Provider {...store}>{this.props.children}</Provider>;
+  }
+}
+```
+
+#### 局部监听
+
+在需要监听的页面或者组件中,将 Provider 中设置的 store 提取到组件的 props 中,下面以白云小程序个人中心页面为例:
+
+在 `src/pages/users/userPage` 中:
+
+```js
+import { observer, inject } from "mobx-react";
+
+@inject("userInfo")
+@observer
+class ByUser extends Component {
+  render() {
+    const { nickname } = this.props.userInfo || {};
+    return <View>{nickname}</View>;
+  }
+}
+```
+
+#### 更新状态
+
+在 `src/pages/users/userPage` 中,使用已经经过初始化的 `bindUser` 函数进行状态变更,重新渲染页面
+
+```js
+import { observer, inject } from "mobx-react";
+
+@inject("userInfo")
+@observer
+class ByUser extends Component {
+  handleChangeName = () => {
+    const userInfo = this.props.userInfo || {};
+    userInfo.bindUser({ nickname: "xxx" });
+  };
+
+  render() {
+    const { nickname } = this.props.userInfo || {};
+    return <View onClick={() => handleChangeName()}>{nickname}</View>;
+  }
+}
+```
+
+### 标准页面结构
+
+```js
+import { observer, inject } from "mobx-react";
+
+@inject("userInfo") // 注入需要监听的全局状态
+@observer
+class ByUser extends Component {
+
+  //初始化页面所需的变量
+  state = {
+    name: ''
+  }
+
+  // 在此生命周期中获取接口数据,设置初始值
+  componentDidMount(){
+    this.initData()
+  }
+
+  initData = async () => {
+    const result = await getName()
+    this.setState({
+      name: result.name
+    })
+  }
+
+  // 修改state
+  handleChangeNickName = () => {
+    this.setState({
+      name: 'yyy'
+    })
+  }
+
+  // 修改全局状态
+  handleChangeName = () => {
+    const userInfo = this.props.userInfo || {};
+    userInfo.bindUser({ nickname: "xxx" });
+  };
+
+  render() {
+    const { nickname } = this.props.userInfo || {};
+    const { name } = this.state
+    return (
+      <View>
+        <View onClick={() => handleChangeNickName()}>{nickname}</View>
+        <View onClick={() => handleChangeName()}>{name}</View>
+      </View>;
+    )
+  }
+}
+```