公司前段时间有了个小程序的需求,几年没写了有些生疏。对小程序框架的记忆还停留在mpvue,一看已经停止更新了,还是找个新框架吧。
调研了一圈:
uni-app支持H5、App等多种平台,不太需要,只会有小程序的需求;
WePY只支持微信小程序,拓展性不足;
最终选择了taro,支持vue3,也能跨平台生成小程序,开搞~
安装
安装就简单点说,装脚手架-创建初始项目-装包-运行,一条龙,懂得都懂~
js
npm install -g @tarojs/cli
taro init myApp
npm install
npm run dev:weapp
然后打开 微信开发者工具,taro运行启的是一个本地服务,加载小程序会有一点延迟,等一会就好了。
现在环境搭建工作就完成了~
开发准备
首先熟悉下 目录结构
lua
├── 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
├── project.tt.json 抖音小程序项目配置 project.tt.json
├── project.swan.json 百度小程序项目配置 project.swan.json
├── project.qq.json QQ 小程序项目配置 project.qq.json
|
├── babel.config.js Babel 配置
├── tsconfig.json TypeScript 配置
├── .eslintrc ESLint 配置
|
└── package.json
然后依次添加几个目录:
/api
vbscript
├── api 接口请求相关目录
| ├── request.js 接口通用配置 RESTful
| ├── index.js 接口列表
| ...
顾名思义 /api 目录是做请求通用配置和接口配置的
具体配置就是依赖Taro提供的原生方法 Taro.request,采用restful规则,就不细讲了,搜索一下很多例子。
/stores
erlang
├── stores 全局状态共享目录
| ├── index.js 全局状态配置
| ├── webSocket.js webSocket配置,根据需求自选
| ...
有全局状态共享的需求,就需要配置stores;有webSocket的需求就要配置webSocket。
想了解详细配置代码,可浏览这里 -> Taro-Vue小程序stores和webSocket配置详解
components
组件目录、assets
资源目录、utils
函数工具方法目录就不详细说了,根据需求自己添加,后面会把一些常用的组件和方法分享出来~
开始写一个HelloWorld页面
taro支持jsx,如果你习惯了react编码风格,在vue项目里你可以用jsx
所有实例都采用vue3写法
HelloWorld.jsx
jsx
import { defineComponent, ref, onMounted, onUnmounted, computed, watch } from "vue";
export default defineComponent({
name: "HelloWorld",
components: {},
setup(props, { emit }) {
function clickEvent() {}
return () => (
<view onTap={clickEvent}>
<text>HelloWorld</text>
</view>
);
}
});
HelloWorld.vue
html
<template>
<view @tap={clickEvent}>
<text>HelloWorld</text>
</view>
</template>
<script>
import { defineComponent, ref, onMounted, onUnmounted, computed, watch } from "vue";
export default defineComponent({
name: "HelloWorld",
components: {},
setup(props, { emit }) {
function clickEvent() {}
return {
clickEvent
}
}
});
</script>
taro的点击事件名为tap,vue里用 @tap ,jsx里用 onTap。
还有一个小tips,如果要处理事件冒泡
的话, 因为taro在原生事件上封装了一层,所以在setup里是触发不了e.stopPropagation()
的,应该这么写:
html
<view @tap="(e) => { e.stopPropagation(); clickEvent(e) }"><view>
开发一个通用组件
既然开发项目就少不了要写很多通用组件,就以modal窗组件为例:
html
<template>
<view v-show="visible" class="black-modal" @tap="onClick">
<view class="black-modal-wrap">
<view v-if="type === 'loading'" class="black-modal-loading">
<image src="loading.png'"/>
<view class="black-modal-loading-desc">
{{ loadText }}
</view>
</view>
<slot v-else></slot>
</view>
</view>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Modal",
props: {
visible: {
type: Boolean,
default: false
},
closeOnClickOverlay: {
type: Boolean,
default: true
},
type: {
type: String,
default: ''
},
loadText: {
type: String,
default: ''
}
},
emits: ['click', 'close', 'update:visible'],
setup(props, { emit }) {
const onClick = (e) => {
emit('click', e);
if (props.closeOnClickOverlay) {
emit('update:visible', false);
emit('close');
}
};
return { onClick, style };
}
})
</script>
html
<Modal
v-model:visible={show.value}
closeOnClickOverlay={false}
>
<view class={`confirmModal`}>
<view class={`modalHeader`}>标题</view>
<view class={`modalContent`}> 内容 </view>
<view class={`modalFooter`}>
<view class={`modalButton`} onTap={() => (show.value = false)}>取消</view>
<view class={`modalButton`} onTap={() => (show.value = false)}>确认</view>
</view>
</view>
</Modal>
小程序的modal和网页的不太一样,网页可以随意往元素内插入dom,可以运用vue.component创建弹窗,但小程序是没办法往page里插入元素也没办法实时生成的,所以需要把modal当组件引入,弹窗里的内容通过通用样式来控制。
小程序分包
项目大了自然要分包,taro的分包和原生小程序区别不大。
在app.config.js里配置下subpackages即可:
json
export default {
subpackages: [
root: "packageA", // 分包文件夹名称
pages: [
"home/index",
"page1/index",
]
]
}
以上配置路由访问地址为:packageA/home/index
、packageA/page1/index
其他
还有一些小程序的工具函数,后面会慢慢总结
Taro-Vue小程序stores和webSocket配置详解
结语
很多项目从0到1其实不难,有很多文档可以参考。难的是项目中会遇到各种问题,兼容问题呀、技术难点呀等等,往往要花很多时间去解决,所以总结就显得尤为重要,共勉~