如何一人五天开发完复杂小程序前端必看

随着业务需求的不断累加、小程序追求快速产出。

在人手不足且开发周期较短的情况下,我们需要找到一个最大化开发效率的方法。

而高效率的开发离不开规范化、工程化、组件化。

为此整理写下总结,细数小程序中的坑与实践。

介绍我们对小程序高效率开发的思考与探索。

  • 布局方案

    • 导航栏

    • TabBar

    • BasicPage

  • 用户系统

    • 登录方案

    • 初始化登录

    • 鉴权

  • 优化及 Bug 追踪

    • 日志收集

    • 数据分析

  • 常用优化方案

    • preLoad

    • 独立分包加载

布局方案

我们首先思考的是,在小程序中如何快速且高还原产出页面。

为此我们封装了一套页面组件。

导航栏

目前小程序有如下两种导航栏:常规、自定义导航栏

自定义导航栏布局下,我们可以完全控制导航栏样式,赋予导航栏更多交互及 UI 设计上的可能。如上图所示,Readhub 在导航栏中加入了设置按钮,喜茶在个人页中标题渐隐及沉浸式导航栏效果。常规布局下,顶部导航栏部分直接使用小程序提供导航栏。

可根据具体业务选择具体布局方案,在我们小程序中,我们选择了全部使用自定义导航栏的方式并对其进行了一定封装。

在确定使用自定义导航栏方案后,我们对导航栏进行了拆解

拆解后,我们发现可以将自定义导航栏分为两个部分:StatusBar 及 NavigationBar 。

通过查阅微信 API ,我们分别通过 wx.getSystemInfoSyncwx.getMenuButtonBoundingClientRect 获取到 StatusBarHeight 及 MenuButton 的布局信息。

由拆解图可知

1 NavigationBarPaddingTop = MenuButtonTop - StatusBarHeight
3 NavigationBarPaddingBottom = NavigationBarPaddingTop
5 NavigationBar = StatusBarHeight + NavigationBarPaddingTop + NavigationBarPaddingBottom + MenuButtonHeight复制代码

得到上述数据后,结果简单封装, 我们得到如下方案

StatusBar 部分, 我们使用 PaddingTop 填充。

可在此基础上可再进一步封装一些通用 NavigationBar 组件。

我们封装了一些常用 NavigationBar 组件, 如下所示:

沉浸式导航栏

自定义 TabBar

目前小程序 TabBar 中也存在两种方案。

常规 TabBar :微信提供方案,可修改 icon 、 文字及其对应选中状态。

自定义 TabBar :小程序基础库 2.5.0 开始支持。可通过其实现异形 TabBar 或各种自定义样式。


在我们小程序中,我们选择全部使用自定义 TabBar 来实现业务。

由于小程序基础库 2.5.0 之后官方才开始支持自定义 TabBar 。我们此处不直接选择使用 custom-tab-bar 方案。选择结合 custom-tab-bar 、 自定义组件及 wx.hideTabBar 的方案实现。

具体方案为放置空节点 custom-tab-bar 文件。在页面中按需引入自定义 TabBar 组件。在页面初始化完成后调用 wx.hideTabBar 隐藏原 TabBar 。

这样做的好处在于,在基础库 2.5.0 及更高版本时正常显示,在低版本时以最小代价兼容。

在 iPhone X 系列下的底部安全区兼容方案如下

 1@mixin media-style() { 2  .tab { 3    padding-bottom: 84px; 4  } 5} 6// 适配iPhone X系列下巴 7@media screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) { 8    @include media-style(); 9}1011@media only screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio:3) {12    @include media-style();13}1415@media only screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio:2) {16    @include media-style();17}18// 下面代码只为适配iPhone X在微信调试模拟器中为724px19@media screen and (device-width: 375px) and (device-height: 724px) and (-webkit-device-pixel-ratio: 3) {20    @include media-style();21}复制代码

推荐如无特殊需求,建议直接使用微信提供方案,在自定义 TabBar 方案中 安卓手机下拉刷新时, TabBar 会被拉出可视区域。需自定义下拉刷新组件解决

方案整合 BasicPage

以上方案在线上运行一段时间后稳定后。对自定义导航栏及自定义 TabBar 方案进行了整合。封装了 BasicPage 组件。

以我们线上典型页面为例,我们可以将页面分为两大类。


基于以上分析结合线上需求,我们对此基础组件进行封装。

Taro 框架伪代码,可根据各自使用框架进行封装,思路一致

 1class BasicPage extends Taro.Component { 2 3  state = { 4    menuButtonHeight: 32,5    menuButtonTop: 48,6    statusBarHeight: 44,7  }; 8 9  componentDidMount() {10        // ...获取并设置 menuButtonHeight 、 menuButtonTop 、 statusBarHeight11  }1213  render() {14    return (15      <View className='basic-page'>16        {17          this.props.header && <View className={`basic-page-header${this.props.fixed ? ' fixed' : ''}`} style={{18            paddingTop: `${this.state.statusBarHeight}px`,19            height: `${(this.state.menuButtonTop - this.state.statusBarHeight) * 2 + this.state.menuButtonHeight}px`,20          }}21          >22            {this.props.renderHeader}23          </View>24        }25        <View className={`basic-page-body${this.props.tab ? ' tab' : ''}`}>26          {this.props.renderBody}27        </View>28        {this.props.tab && <TabBar active={this.props.tabActive} />}29      </View>30    );31  }32}3334BasicPage.defaultProps = {35  fixed: false,// header 是否浮动36  tab: false,37  header: false,38  tabActive: 'template',39};40复制代码

使用中会经常用到 自定义 TabBar 、 自定义 NavigationBar 布局数据。再封装一个工具类获取。

 1import Taro from "@tarojs/taro"; 2 3function rpx2px(rpx,windowWidth) { 4  return rpx / 750 * windowWidth; 5} 6 7export default class customConfig { 8 9  static fetchAllConfig() {10    const menuButton = Taro.getMenuButtonBoundingClientRect();11    const systemInfo = Taro.getSystemInfoSync();1213    const statusBarHeight = systemInfo.statusBarHeight;14    const headerHeight = (menuButton.top - systemInfo.statusBarHeight) * 2 + menuButton.height;15    const footerHeight = systemInfo.model.indexOf('iPhone X') === -116      ?17      rpx2px(100,systemInfo.windowWidth)18      :19      rpx2px(168,systemInfo.windowWidth);  // 50  8420    const bodyHeight = systemInfo.windowHeight - statusBarHeight - headerHeight - footerHeight;21    const noTabBodyHeight = systemInfo.windowHeight - statusBarHeight - headerHeight;2223    let data = {24      source: {25        menu: menuButton,26        system: systemInfo,27      },28      height: {29        statusBar: statusBarHeight,30        header: headerHeight,31        body: bodyHeight,32        noTabBody: noTabBodyHeight,33        footer: footerHeight,34      },35    };36    Taro.setStorageSync('customConfig',data);37    return data;38  }3940  static get config() {41    let storageInfoSync = Taro.getStorageSync('customConfig');42    if(!storageInfoSync) {43      storageInfoSync = this.fetchAllConfig();44    }45    return storageInfoSync;46  }47}复制代码

到此,我们完成对基础页面组件的封装。目前线上运行小程序所有页面都基于该组件进行开发。

开发新页面时只需要引用该组件即可。

1<BasicPage header tab tabActive='index' 2        renderHeader={ 3          <View 4            className='my-index-header' 5          > 6            <Text>Title</Text> 7          </View> 8        } 9        renderBody={10          <View className='my-index-header'>11            Body12          </View>13        }14/>复制代码

用户系统

在一个应用中,用户系统是至关重要的。我们通过数个小程序的开发,整理了一套我们目前正在使用的用户系统实践。

登录、获取用户信息


如上图所示,我们将小程序登录及获取用户信息拆分为两部分。

主要有如下考虑:

  1. 降低用户使用门槛,可先让用户体验部分功能。后续分享或互动时提示授权完善用户信息

  2. 保证始终持有用户登录态,方便程序处理。如把用户登录及完善用户信息放置一起,在未授权时无法获取自定义登录态。判断变得复杂且无法提前收集 formId

  3. 同一开发者账号下,多小程序互通时,如有一小程序用户授权过,可通过返回 unionid 直接同步信息,无需再授权,提升用户体验。

处理注意点

授权获取用户信息时,如果服务端未记录用户 sessionKey ,在 Button type = getUserInfo 回调事件中使用 wx.login 方法获取 code 的话,会导致 sessionKey 变化。从而导致 getUserInfo 时使用 sessionKey 与新 sessionKey 不匹配。从而导致解密用户信息失败。

解决方案有如下两种:

  • Button type = getUserInfo 回调事件中使用 wx.login 方法后,再次调用 wx.getUserInfo 方法重新获取加密用户信息。

  • 服务端记录 sessionKey ,Button type = getUserInfo 回调后无需调用 wx.login ,直接提交供服务端处理。

第一种方案适合简单改造旧项目、快速开发,但强烈建议使用服务端处理方式解决。

完善用户信息时,解密用户信息部分请查看官方文档,这里不叙述具体流程https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html

unionid 机制

另外,在登录流程中服务端向微信换取 sessionKey 过程中,如果满足一定条件,会直接返回 unionid 。同开发者账号下多个小程序时可用 unionid 做用户信息同步,无需再授权。提升用户体验。

unionid 机制: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html

小程序初始化及页面初始化处理

在日常开发中,我们通常会把登录获取 token 操作放置在小程序初始化中即 app.js 定义的 onLaunch 中。而该生命周期与页面初始化生命周期为同步进行。

此时,如果在页面初始化中,需要携带用户登录态请求接口获取信息时,可能出现如下情况

因为小程序初始化及页面初始化是同步进行的。若页面初始化时,小程序初始化中登录请求仍未完成。会导致未携带 token 或其他鉴权信息,鉴权失败。

最开始我们通过在组件中挂载一个特殊事件 componentDidInit ,待小程序初始化登录请求后获取当前页面实例进行调用。但该方案对代码侵入性太强,最终我们选择维护一个登录请求队列。

用上队列的原因在于,在产品需求上经常会有先跳入首页,再从首页跳入二级页的需求,这样能让用户回退一次后,仍然能回到首页。但会导致在不同页面中近乎同时调用 login 方法。

在第一种方案中,解决该问题需要获得所有页面实例进行调用。而引入队列后只需要轮询消费队列中函数执行即可。上述流程可解决此问题。伪代码如下:

代码仅供理解思路

 1let loginDoing = false; 2const loginEvent = []; 3 4const userProfile = observable({ 5  user: { 6    avatar: '',7    isCompleted: false,8    nickname: '',9    uid: 0,10    token: '',11  },12  async loginProcess() {13    if(this.user.token) {14      return this.user;15    }16    loginDoing = true;17    let code;18    try {19      const codeResult = await Taro.login();20      if(codeResult.errMsg !== 'login:ok') {21        throw new Error('Taro.login 失败');22      }23      code = codeResult.code;24    } catch (e) {25      loginDoing = false;26      throw e;27    }28    const result = await post(URL().user.login,{29      code,30    });31    let user = {32      ...result.user,33      token: result.token,34    };35    this.user = user;36    loginDoing = false;37    setTimeout(() => {38      let length = loginEvent.length;39      for(let i = 0; i < length; i++) {40        loginEvent.pop()(user);41      }42    });43    return user;44  },45  login() {46    if(loginDoing) {47      return new Promise((resolve) => {48        loginEvent.push(resolve);49      });50    } else {51      return this.loginProcess()52    }53  },54});复制代码

鉴权

业务需求中,通常存在某些操作需要 【 用户授权完善信息 】 后才能继续进行,早期项目中都是各自页面中写鉴权代码。因而会涉及大量重复代码,也不利于快速开发。为此我们封装了一套鉴权方案。

BasePage

通过所有页面基础一个基类 BasePage 。在 BasePage 中写入鉴权逻辑来实现。配合在主页面中使用 AuthorizationModal 组件实现鉴权。

代码仅供理解思路

1 export default class BasePage extends Component { 2 3    state = { 4        // 鉴权相关 5        showAuthorizationModal: false,6    }; 7 8    /** 9     * 鉴权相关10     */11    // 授权成功事件12    authSuccessEvent() {13    }1415    // 取消授权事件16    authFailEvent() {17    }1819    async checkAuthorization() {20        // 当前是否有已验证21        let globalData = getGlobalData(STORAGE_KEY.VERIFY);22        if(globalData) {23            return {24                isNew: false,25            };26        } else {27            Taro.showLoading({28                title: '检查授权中...',29                mask: true,30                showTicketModal: false,31            });32            // 如果本地不存在时,先请求接口33            // 未登录过,或新机器34            // 请求token及授权状态35            let res;36            try {37                res = await Taro.login();38            } catch() {39                Toast.fail('登录失败~');40                Taro.hideLoading();41                throw new Error('Taro.login 失败');42            }43            // 请求授权接口44            const result = {};45            if(result.errno === 0) {46                resolve({47                    isNew: false,48                });49            } else {50                // 未授权过51                // 弹窗提示授权52                this.setState({53                    showAuthorizationModal: true,54                });55                this.authSuccessEvent = () => {56                    this.setState({57                        showAuthorizationModal: false,58                    });59                    resolve({60                        isNew: true,61                    });62                };63                this.authFailEvent = () => {64                    this.setState({65                        showAuthorizationModal: false,66                    });67                    reject();68                };69            }70        }71    }72}复制代码

页面继承该基类

1 class LaunchIndex extends BasePage {}复制代码

在页面中置入组件

1 {this.state.showAuthorizationModal &&2 <AuthorizationModal onSuccess={this.authSuccessEvent} onFail={this.authFailEvent}/>}3复制代码

AuthorizationModal 组件

接下来,我们只需要在需要鉴权的操作中如下使用即可

1this.checkAuthorization()2  .then((res) => {3   // 授权成功逻辑4       console.log('是否新用户',res.isNew);5   })6   .catch(() => {7    // 授权失败逻辑8    })复制代码

该方案好处在于,授权由状态驱动,只需在代码中调用 checkAuthorization 方法即可。

AuthorizationView

后来,由于第一种方案过于重,对页面代码侵入性较强。为此我们又封装了一套较轻的组件。

大部分逻辑中,需要用户主动点击时才进行鉴权,我们基于此思路封装了 AuthorizationView 。对外暴露 onAgree 、 onDeny 方法实现对部分区域的点击鉴权操作。

代码仅供理解思路

1 class AuthorizationView extends Taro.Component { 2 3  state = { 4    showLoginPanel: false,5  }; 6 7  /** 8   * 登录 9   */10  click() {11    const { userProfile: { user,},} = this.props;12    if(user.isCompleted) {13      this.props.onAgree(user);14    } else {15      // 显示登录框16      this.setState({17        showLoginPanel: true,18      });19    }20  }2122  /**23   * 授权登录24   * @param e25   */26  async bindGetUserInfo(e) {27    if(e.detail.errMsg === 'getUserInfo:ok') {28      const { userProfile,} = this.props;29      const userResult = await userProfile.login(true);30      this.setState({31        showLoginPanel: false,32      });33      this.props.onAgree(userResult);34    } else {35      this.props.onDeny();36    }37  }3839  cancel() {40    this.setState({41      showLoginPanel: false,42    });43  }4445  render() {46    return (47      <Block>48        <View onClick={this.click}>{this.props.children}</View>49        {50          this.state.showLoginPanel && <View className='login-panel'>51            <View className='login-panel-main'>52              <View className='login-panel-main-title'>您还未登录</View>53              <View className='login-panel-main-subtitle'>请先登录再进行操作</View>54              <Image className='login-panel-main-image' src='https://p0.ssl.qhimg.com/t01a1e495cc2be1e651.png' />55              <View className='login-panel-main-footer'>56                <View className='login-panel-main-footer-button cancel' onClick={this.cancel.bind(this)}>暂不登录</View>57                <Button className='btn-reset' openType='getUserInfo' onGetUserInfo={this.bindGetUserInfo}>58                  <View className='login-panel-main-footer-button confirm'>立即登录</View>59                </Button>60              </View>61            </View>62          </View>63        }64      </Block>65    );66  }67}6869AuthorizationView.defaultProps = {70  onAgree: () => {71  },72  onDeny: () => {73  },74};7576export default AuthorizationView;77复制代码

代码中只需要使用该组件包裹子组件即可使用

1 <AuthorizationView onAgree={this.onAgree.bind(this)} onDeny={this.onDeny.bind(this)}>2  <View>生成海报</View>3</AuthorizationView>4复制代码

以上两种方案都有在线上业务中使用,具体选型看业务决定

优化及Bug追踪

在维护阶段,我们会更加关注于用户反馈 bug 时如何复现场景及数据分析。

日志收集

在小程序基础库版本 2.1.0 后,微信提供了一套日志相关接口:LogManager 。

在用户反馈时,通过该接口记录的日志会同步上传至微信后台,可下载查看追踪 Bug。

我们通过简单的对其封装,实现一套日志收集机制。

1 const _logger = Taro.getLogManager({ level: 0,}); 2 3const Logger = { 4  debug(...args) { 5    _logger.debug(`${dayjs().format('YYYY-MM-DD HH:mm:ss')}  

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


概述 消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验。 订阅消息推送位置:服务通知 订阅消息下发条件:用户自主订阅 订阅消息卡片跳转能力:点击查看详情可提爱转至该小程序的页面 消息类型 一次性订阅消息 一次性订阅消息用于解决用户使用小程序后,后续服务
判断H5页面环境在微信中还是小程序中 用小程序提供的wx.miniProgram.getEnv可以获取环境参数 &lt;script type=&quot;text/javascript&quot; src=&quot;https://res.wx.qq.com/open/js/jweixin-1.
wx.reLaunch和wx.navigateTo,wx.navigateTo的区别 2019-03-23 11:18:05 wx.navigateTo 用于保留当前页面、跳转到应用内的某个页面,使用 wx.navigateBack可以返回到原页面。对于页面不是特别多的小程序,通常推荐使用 wx.n
微信小程序如何从数组里取值_微信小程序 传值取值的几种方法总结 小程序里常见的取值有以下几种,一个完整的项目写下来,用到的概率几乎是100%。 列表index下标取值 页面传值 form表单取值 1. 列表index下标取值 实现方式是:data-index=&quot;{{index}}&quot
H5项目接入微信授权登录,通过 UA 区分微信还是普通浏览器: let&#160;ua&#160;=&#160;navigator.userAgent.toLowerCase(); let&#160;isWeixin&#160;=&#160;ua.indexOf(&#39;micromessenge
微信小程序获取data-xx=&quot;&quot;属性的值,自定义属性设置和获取(data-) 微信小程序&lt;view class=&quot;details-btn&quot; data-taskId=&quot;111&quot; bindtap=&#39;taskdetails&#39
小程序报错:TypeError: Cannot read property ‘addEventListener‘ of undefined 解决办法 将调试基础库由2.16.0(或者当前的) -&gt; 2.14.1 解决问题
H5跳转微信小程序-成功案例(VUE)(踩坑无数) TuoMei 已于 2022-07-29 09:52:22 修改 准备工作 根据官方提供的资料需准备以下几点: 1、已认证的服务号 2、绑定JS接口安全域名 (在微信公众平台设置) 3、IP白名单 (在微信公众平台设置) 4、将小程序和H5公众号进
微信小程序 页面跳转和数据传递实例详解 这篇文章主要介绍了微信小程序 页面跳转和数据传递实例详解的相关资料,这里附有实例代码帮助到家学习理解,需要的朋友可以参考下 微信小程序 页面跳转和数据传递 1.先导 在Android中,我们Activity和Fragment都有栈的概念在里面,微信小程序页面也
情景1.拉取公司代码演示: 因为github有墙,这里我们以gitee(码云)为例作为演示 (其实就是国产github,也非常好用~) 步骤一:打开Git界面 先在一个空文件夹右击Git Bash Here,打开git界面 步骤二:输入克隆远程仓库指令 别人复制的链接在这里获取 拿到别人赋值的链接自
如何开发微信小程序? 作为一名10多年一直从事互联网平台开发的从业者,我来回答下这个问题吧。 微信小程序开发流程总体可以归纳为4个步骤, 老张带您捋一捋整个环节,小白用户可以收藏了。 好了废话不多说,开始! 一、开发前小程序需要准备的资料 我们在开发微信小程序前,需要准备下相关资料。这个资料主要是后
原生小程序开发优化方案 为了更好的制定优化方案,我们 有必要先了解下小程序的底层架构、以及与普通网页开发的差异 小程序最终渲染载体与当下一些热门的技术 Flutter、React Native等不同,依然是浏览器内核,而不是原生客户端。 而对于传统的网页来说,UI 渲染和 JS 脚本是在同一个线程中
1,不要下两倍尺寸的图片, 小程序本身自己就会对元素缩小两倍,设计图片的一杯就已经很清晰了。 2,图片压缩,(主要是压缩静态资源,ps 可以压缩,然后有一些在线压缩工具,保持600-800kb 的静态) 3,通用的代码组件化 4,是在工程量太大可以分包,分包现在最大支持20m(一般都不会去分包的)
文章浏览阅读189次。人工智能研究实验室OpenAI在2022年11月30日发布了自然语言生成模型ChatGPT,上线两个月就已经超过一亿用户,成为了人工智能界当之无愧的超级大网红。ChatGPT凭借着自身强大的拟人化及时应答能力迅速破圈,引起了各行各业的热烈讨论。简单来说ChatGPT就是可以基于用户文本输入自动生成回答的人工智能聊天机器人。那肯定会有人说这不就是Siri嘛,虽然都是交互机器人但是两者的差别可老大了。那么ChatGPT在人机交互时为什么会有这么出色的表现?它到底会不会取代搜索引擎?90%的人真的会因为ChatG
文章浏览阅读193次。8. 导航和路由管理:掌握小程序的导航方式,如使用wx.navigateTo跳转页面、使用wx.redirect重定向页面等,学会实现页面之间的跳转和传参。1. 小程序的基本概念和架构:了解小程序的定义、特点以及与传统APP的区别,掌握小程序的运行环境、组件和API等基本概念。10. 支付功能:学习小程序的支付方式,如微信支付、支付宝支付等,了解支付流程和注意事项,学会实现小程序的支付功能。9. 用户授权和登录:了解小程序的用户授权机制,如获取用户信息、调用微信API等,学会实现用户的登录和注册功能。_微信小程序开发知识点总结
文章浏览阅读4.8k次,点赞7次,收藏18次。一、准备工作1. 安装微信开发者工具,并登录微信小程序账号;2. 准备斗地主游戏的图片资源;3. 准备斗地主游戏的音效资源;二、创建小程序1. 打开微信开发者工具,点击“新建小程序”,输入小程序名称,选择小程序的项目目录,点击“创建”;2. 在小程序的项目目录中,新建文件夹“images”,将准备好的斗地主游戏的图片资源放入“images”文件夹中;3. 在小程序的项目目录中,新建文件夹“sounds”,将准备好的斗地主游戏的音效资源放入“sounds”文件夹中;三、编写代码1. 在小程_扑克牌微信小程序代码
文章浏览阅读3.9k次,点赞3次,收藏7次。一、准备工作:1. 安装微信开发者工具,创建小程序项目;2. 准备游戏角色图片;3. 准备游戏背景音乐;二、实现步骤:1. 创建游戏页面,添加游戏角色图片,添加游戏背景音乐;2. 创建游戏角色类,定义游戏角色属性,如角色名称、角色图片、角色能力等;3. 创建游戏类,定义游戏属性,如游戏人数、游戏角色、游戏规则等;4. 创建游戏控制类,定义游戏流程,如游戏开始、游戏结束、游戏角色分配等;5. 创建游戏界面,实现游戏流程,如游戏开始、游戏结束、游戏角色分配等;6. 创建游戏结果页面,显示游戏_微信小程序游戏代码
文章浏览阅读1.7k次。1. 创建小程序项目:使用微信开发者工具创建一个小程序项目,并在项目中添加一个页面,用于模拟聊天。 2. 定义数据结构:定义一个数据结构,用于存储聊天记录,包括发送者、接收者、消息内容等信息。 3. 实现聊天功能:实现聊天功能,包括发送消息、接收消息、显示消息等功能。 4. 实现界面:使用微信小程序的界面框架,实现聊天界面,包括聊天记录列表、输入框等。代码示例:// 定义数据结构var chatData = { sender: '', receiver: '', message: '' };_制作聊天对话小程序代码
文章浏览阅读2.1k次。1、创建小程序项目:使用微信开发者工具,新建一个小程序项目,输入项目名称,选择项目目录,点击“创建”按钮,即可创建小程序项目。2、添加页面:在小程序项目中,可以添加多个页面,每个页面都有自己的页面文件,比如首页、分类页、购物车页、我的页面等。3、添加组件:在小程序项目中,可以添加多个组件,比如商品列表组件、购物车组件、订单组件等,用于在页面中显示商品信息、购物车信息、订单信息等。4、添加接口:在小程序项目中,可以添加多个接口,用于获取商品信息、购物车信息、订单信息等,以便在页面中显示。5、_微信开发者工具做一个我的商城