框架
开发规范
文件组织结构
Mars 框架中 App、Page、Component 使用 vue 单文件组件规范,定义在 .vue
文件中,其中 <script>
区块需使用 ES module 模式导出(即 export default {}
)
目录结构如下,其中 app.vue
为 APP 入口文件(不支持其他文件名),入口文件无需包含 <template>
区块:
├── src 源码目录
| ├── components 组件目录
| ├── pages 页面目录
| | └── index index 页面目录
| | ├── banner index 页面私有组件或其他资源文件等
| | └── index.vue index 页面
| ├── common 公共资源目录
| ├── app.vue APP 入口文件
| └── project.swan.json 小程序 project 文件
├── package.json
└── mars.config.js 编译配置文件, 参考【编译配置】
App
App 是小程序的入口文件,约定其文件名为 app.vue
。可以在 App 上定义一些全局的配置,绑定 App 生命周期方法或定义自定义属性,以及定义全局样式。
Mars 中 App、Page、Component 的相关配置,需要配置到 Vue 文件 script 部分导出对象的 config
字段中。
build@0.2.52
起支持用单独的 <script type="config"></script>
区块配置 config
,且支持区块级条件编译,即:
<script type="config" target="h5">
{
config: {
pages: [
'pages/home/index'
]
}
}
</script>
<script type="config">
{
config: {
pages: [
'pages/home/index',
'pages/example/index'
]
}
}
</script>
App 示例代码: app.vue
<script>
export default {
// ...
config: {
pages: [
'pages/home/index',
'pages/example/index'
]
},
onLanuch() {},
onShow() {},
onHide() {},
globalData: {}
// ...
}
</script>
<style lang="less">
.page {
padding: 30px;
}
</style>
Page
Page 是一个定义为页面的 Vue 文件,在 App 的 config.pages
里声明后可以使用,Page 加载(onLoad
)的时候会创建一个对应的 Vue 根实例(Page 中 this
指向此 Vue 实例)。
Page 示例代码: pages/home/index.vue
<template>
<view class="page">
<c-hello :helloText="helloText">
<text>Mars!</text>
</c-hello>
</view>
</template>
<script>
// 注意:vue 文件中使用组件按照 vue 规范的 components 字段配置即可,无需在 config 中配置 usingComponents
import Hello from '../../components/Hello/Hello.vue';
export default {
// ...
config: {
navigationBarTitleText: 'Examples'
},
components: {
'c-hello': Hello
},
data() {
helloText: 'welcome!'
},
onLoad(options) {},
onReady() {},
onUnload() {},
onShow() {},
onHide() {},
onForceReLaunch() {},
onPullDownRefresh() {},
onReachBottom() {},
onShareAppMessage() {},
onPageScroll() {},
onTabItemTap() {},
// ...
}
</script>
<style lang="less">
</style>
build@0.2.52
起支持定义组件时使用 PascalCase 并支持 ES6 对象属性简写,在模板里需要用对应的 kebab-case 引用,即:
<template>
<my-hello :helloText="helloText">
<text>Mars!</text>
</my-hello>
</template>
<script type="config">
{
config: {
navigationBarTitleText: 'Examples'
}
}
</script>
<script>
import MyHello from '../../components/Hello/Hello.vue';
export default {
components: {
MyHello
}
};
</script>
<style lang="less">
</style>
Component
Component 是定义为组件的 Vue 文件,必须在其 config 中设置 component: true
。Component 被 Page 或 Component 引用并渲染后,会生成对应的 Vue 实例(Component 中 this
指向此 Vue 实例)。
Component 示例代码: components/Hello/Hello.vue
<template>
<view>
{{helloText}}: <slot />
</view>
</template>
<script>
// 注意:组件需在 config 中配置 component: true
export default {
// ...
config: {
component: true
},
props: {
helloText: {
type: String,
default: 'hello'
}
},
lifetimes: {
created() {},
attached() {},
ready() {},
detached() {}
},
pageLifetimes: {
show() {},
hide() {}
},
// ...
}
</script>
<style lang="less">
</style>
实例扩展 API
$mpUpdated( [callback, context] )
在 App、Page、Component 实例上新增扩展 $mpUpdated
API,来注册小程序数据更新视图渲染完成后的回调。
在下次小程序渲染结束之后执行延迟回调,在修改数据之后立即使用这个方法,可以获取数据修改到渲染结束的时间。
参数:
- {Function} [callback]
- {Object} [context]
用法:
// 在实例内使用
// 修改数据
this.msg = 'Hello';
// 小程序内容还没有更新
this.$mpUpdated(function () {
// 小程序视图更新完成
});
// 作为一个 Promise 使用
this.$mpUpdated()
.then(function () {
// DOM 更新了
});
// 在其他位置使用
const app = getApp();
app.$mpUpdated(...);
小程序特性支持
自定义组件特性
在组件导出对象上配置。
- 支持
externalClasses
(调用组件传入外部样式类属性时暂不支持动态绑定) - 支持
options
- 不支持 behaviors 和自定义扩展
获取小程序实例和 Page options
使用框架开发的页面和组件中,this
指向的是 Vue 实例,通过下面的方法可以获取到小程序实例。
- 在页面或组件实例中获取对应小程序实例:
this.$mp.scope
- 在页面实例中获取小程序 Page options:
this.$mp.options
框架会通过 Vue 运行时将数据更新同步到小程序,不能直接通过小程序实例调用 setData
,会导致数据不一致。
使用小程序组件和页面
支持在 mars 项目中使用小程序的组件和页面,具体方法为:
使用小程序组件
直接在 config 中配置 usingComponents 来使用,不需要加文件名后缀:
<script>
export default {
config: {
usingComponents: {
'a-comp': '../../path/to/components'
}
}
};
</script>
使用小程序页面
在 app.vue 中引入时,需要添加 .swan、.mp 后缀:
<script>
export default {
config: {
pages: [
'pages/home/index',
'pages/land/index',
'pages/swan/index.swan'
],
tabBar: {
list: [{
pagePath: 'pages/home/index',
text: 'TabA'
}, {
pagePath: 'pages/land/index',
text: 'TabB'
}, {
pagePath: 'pages/swan/index.swan',
text: 'Swan'
}]
}
}
};
</script>
当生成 H5 项目时,这些组件和页面会被忽略,需要自行在业务中进行处理。
生命周期和事件方法
Mars 支持完整的 Vue 生命周期和小程序生命周期及事件方法(部分在 H5 暂未支持)详见 多端适配 - 生命周期。
生命周期图示及顺序
如图示,Vue 生命周期与 swan 生命周期触发顺序为:
- [lifetimes Vue:Page] created
- [lifetimes swan:Page] onLoad
- [lifetimes Vue:Page] mounted
- [lifetimes swan:Page] onShow
- [lifetimes swan:Page] onReady
注意:swan 的视图在 Page onReady 时或 Component (lifetimes) ready 时才创建完成,使用视图相关 API 时要注意。
小程序内置组件
框架的组件规范使用百度智能小程序和微信小程序组件规范,使用时按照小程序的组件名、属性名和事件名使用,属性和事件绑定使用 vue 语法,如:<input :value="value" @input="onInput" />
小程序内置 API
Mars 的 API 规范使用百度智能小程序和微信小程序 API 规范,为了实现多端兼容,框架会在 App 实例及 Page/Component 实例上通过 $api
字段来挂载原生 API,即可以在实例上通过 this.$api
或者在其他 js 文件中通过 app.$api
(app = getApp()
) 来访问小程序 API。
另外,为了开发方便,通过上述方式调用 API 时框架会自动将原生的异步 API 转换为 Promise API,可以直接用 Promise 方式使用,如
// 在组件或页面实例中
this.$api.request({
url: 'https://m.baidu.com/',
data: {
from: 'mars'
}
}).then(res => {
console.log(res.data);
}).catch(err => {
console.log('错误码:' + err.errCode);
console.log('错误信息:' + err.errMsg);
});
// 在其他 js 文件中
const app = getApp();
app.$api.request().then();
@marsjs/core
运行时可以从 @marsjs/core
引入以下模块
Vue
运行时使用的 Vue,用于使用 vuex
或定义全局过滤器等。
config
Since:@marsjs/core@0.3.0
运行时配置接口
config.router.base
设置 H5 router 的 base 选项。
config.router.mode
Type: enum('history', 'hash')
设置 H5 router 的 mode 选项,优先级高于 mars.config.js
中的配置。
← 0.3.x 迁移指南 Vue 特性 →