弃用uniapp尝试使用mpx框架开发微信小程序(二): 框架熟悉与项目工程搭建

82 阅读5分钟

mpx 是一个增强型的跨端的小程序框架。综合了微信小程序的语法和 vue 语法风格的框架。

与其它市面上流行的静态编译型框架(uniapp,taro2)不同的是,mpx 框架是以小程序本身 DSL 为基础的,而其它框架是将 react 和 vue 框架的源码转换成小程序源码来实现跨平台的。所以在开发时不能照搬 vue 代码,可能这也是为什么这个框架不火的原因吧,毕竟 vue 代码不能直接用就劝退了很多人了。但是我个人感觉这个框架很容易上手的,毕竟和 vue 语法很类似。

边搭建项目边熟悉框架

创建工程。

先安装脚手架

npm i -g @mpxjs/cli

然后使用命令创建项目。

mpx create makeexcel

1.jpg 开发微信小程序,所以要选择第一个。

2.jpg 只开发微信小程序,所以选 n

3.jpg 这个框架还可以输出为 react-native,非常不错,但我们不需要,选 n

选项太多了,直接贴出最后选项。

4.jpg typescript 是必须的,很不喜欢弱类型的语言,写 js 自动补全相当不准,项目迭代和维护时候也很难受。 原子类(Tailwindcss、Windicss 和 Unocss 等)也是必须的,本人不喜欢单独写 css 单独命名,麻烦。

项目创建完后是这样

5.jpg

如果需要修改小程序的 appid,可以打开这个文件修改这里。

6.jpg


调试项目执行`npm run serve`命令,打包执行`npm run build`命令

安装 vscode 插件

使用官网的 vscode 插件开发的时候体验更好

7.jpg 只安装图中红圈的就可以了,其它的是以前的旧版本。

项目入口文件 app.mpx

<!-- app.mpx -->
<script lang="ts">
import mpx, { createApp } from "@mpxjs/core";
import apiProxy from "@mpxjs/api-proxy";

mpx.use(apiProxy, { usePromise: true });
createApp({
  onLaunch() {},
});
</script>

<style></style>

<script type="application/json">
{
  "pages": ["./pages/index"]
}
</script>

这个文件类似于 vue 的 app.vue,同时所有的页面必须要先在这里添加注册。

页面开发

先安装 ui 库 ui 库有两个,一个是vant/weapp,一个是官方开发的mpx-ui,这两个都还不错,我用的是vant 安装直接执行npm install @vant/weapp即可,直接使用 npm 安装依赖包,非常的方便。

一个简单的例子:

<!-- index.mpx -->
<template>
  <view class="h-screen flex flex-col justify-center items-center">
    <van-button type="primary" plain size="normal" bindtap="onClick">
      {{ msg }}{{ doubleCount }}
    </van-button>
  </view>
</template>

<script lang="ts">
import mpx, { createPage } from '@mpxjs/core'
import { computed, ref, watch } from 'vue'

createPage({
  setup() {
    const msg = ref("hello world")
    const count = ref(0)
    const doubleCount = computed(() => {
      return count.value * 2;
    })

    watch(count, (oldCount, newCount) => {
      console.log("old = " + oldCount)
      console.log("new = " + newCount)
    })
    const onClick = () => {
      count.value += 1
    }
    return { onClick, msg, doubleCount };
  }
})
</script>

<script type="application/json">
  {
    "usingComponents": {
      "vant-button": "@vant/weapp/dist/button/index"
    }
  }
</script>

  • 单文件开发 mpx 受 vue 单文件的启发,将小程序中组成的页面四个文件 wxml/js/wxss/json 合并为一个,这样就极大方便开发和维护了(话说为啥微信小程序当初没想到了)。
<!--对应wxml文件-->
<template></template>
<!--对应js文件-->
<script lang="ts"></script>
<!--对应wxss文件-->
<style lang="stylus"></style>
<!--对应json文件-->
<script type="application/json">
{
  "usingComponents": {
    "vant-button": "@vant/weapp/dist/button/index"
  }
}
</script>
  • 数据响应和事件绑定 数据响应概念和 vue 一样, 也是响应数据赋值、watch 观察数据和 computed 计算属性。事件绑定的语法与微信小程序一样使用bindtap,和 vue 是不一样的,这里要注意。
<template>
  <view class="h-screen flex flex-col justify-center items-center">
    <van-button type="primary" plain size="normal" bindtap="onClick">
      {{ msg }}{{ doubleCount }}
    </van-button>
  </view>
</template>

<script lang="ts">
...
createPage({
  setup() {
    const msg = ref("hello world");
    const count = ref(0);
    const doubleCount = computed(() => {
      return count.value * 2;
    });

    watch(count, (oldCount, newCount) => {
      console.log("old = " + oldCount);
      console.log("new = " + newCount);
    });
    const onClick = () => {
      count.value += 1;
    };
    return { onClick, msg, doubleCount };
  },
});
</script>
...
  • 组合式 API mpx 不仅支持响应式 API 也支持组合式 API,这里只讲下组合式 API。 mpx 的组合式 api 的设计参考 vue3,写法上有两种 一种是如下所示的写法
...
createPage({
  setup() { return {}},
})
...

还一种是setup式的写法

<script lang="ts" setup>
...
defineExpose({})
...
</script>

本人更倾向使用第一种,createPage 能与后面的 createComponent 区分,代码上更直观点。

  • 原子类 mpx 框架内置了基于 unocss 的原子类支持,让小程序开发也能使用原子类。不用再写各种 css 代码,也不用再为 css 命名发愁了。
...
<view class="h-screen flex flex-col justify-center items-center">
  ...
  </view>
...

当然了由于小程序本身的差异性,也决定了内置的 unocss 有很特性是不支持的,比如

  1. 不支持子项:Font Variant Numeric Tab Size
  2. 小程序不支持 svg 标签
  3. 不支持子项:Child Selectors,因为小程序不支持*选择器 ......等等若干

状态管理

Mpx 框架参考 Pinia 设计实现了一套外部状态逻辑管理系统(pinia),允许跨页面/组件共享状态,其中的概念与 api 与 Pinia 保持一致,同时支持在 Mpx 组合式 API(Composition API)和选项式 API(Options API)模式下使用。 使用示例:

  • 创建 pinia
//  app.mpx
import mpx from "@mpxjs/core";
import { createPinia } from "@mpxjs/pinia";

const pinia = createPinia();
  • 创建 store
// sample.ts
import { defineStore } from "@mpxjs/pinia";
import { ref, computed } from "@mpxjs/core";

export const useSampleStore = defineStore("sample", () => {
  const count = ref(0);
  const name = ref("pinia");
  const myName = computed(() => {
    return name.value;
  });
  function increment() {
    count.value++;
  }
  return { count, name, myName, increment };
});

在 store 中:

  • ref()就是state属性

  • computed()就是getters

  • function()就是actions

  • 使用 store

import { useSampleStore } from "xxx/sample";
import { storeToRefs, mapState, mapActions } from "@mpxjs/pinia";

createPage({
  setup(props, context) {
    const sampleStore = useSampleStore();
    sampleStore.count = 2;
    // 作为 store 的一个属性,我们可以直接访问任何 getter(与 state )
    sampleStore.myName; // pinia

    function onIncrementClick() {
      // 调用 action 方法
      sampleStore.increment();
      console.log("New Count:", sampleStore.count);
    }
    return {
      onIncrementClick,
      ...storeToRefs(sampleStore),
    };
  },
});

自定义组件

Mpx 框架中的自定义组件与 Vue 中的类似,可以在每个组件内封装自定义内容和逻辑。但语法上默认以微信小程序为基准。

  • 创建和使用组件 组件创建
<!--组件 components/list.mpx-->
<template>
  <view class="list">
    <view wx:for="{{ listData }}" wx:key="*this">{{ item }}</view>
  </view>
</template>

<script lang="ts">
import { createComponent, ref } from "@mpxjs/core";

createComponent({
  properties: {},
  setup() {
    const listData = ref(["手机", "电视", "电脑"]);
    return {};
  },
});
</script>

<script type="application/json">
{
  "component": true
}
</script>

页面中使用

<!--页面 index.mpx-->
<template>
  <view>
    <list></list>
  </view>
</template>
<script>
import { createPage } from "@mpxjs/core";
createPage({});
</script>
<script type="application/json">
{
  "usingComponents": {
    "list": "components/list"
  }
}
</script>
  • 组件属性 组件的 properties,data,computed,watch,methods,生命周期,还有组件实例方法比如:setData,triggerEvent 等等都和微信小程序中的语法一样,这里就不做详细介绍了。

更多详细内容可以参数官网文档mpxjs.cn/guide/basic…