# 列表详情
## 前言
我们使用 `M8.4移动前端框架` 进行下拉刷新列表、详情页面的开发
已根据 教程 章节了解 `M8` 开发的思路
## 新建模块
模块代码统一放在 `src/pages` 下,每个模块应用对应一个文件夹。
我们在此路径下新建文件夹,例如 `m8demo`。
### 路由配置
在 `m8demo` 文件夹下新建 `router.ts` 文件,如下:
`src/pages/m8demo/router.ts` :
```js
/**
* router.js无需import组件,需要path路径与vue组件名称保持匹配。
* routers数组下有效参数只有path与style。
* 构建时会自动将模块下的路由配置合并到pages.json内。
*/
// 定义路由规则,url匹配path时,加载component组件页面
const routes = [
{
path: 'pages/m8demo/list',
style: {
navigationBarTitleText: '列表页面'
}
}
];
// 导出路由文件
export default routes;
```
### Mock数据配置
在 `m8demo` 文件夹下新建 `mock.ts` 文件,定义列表请求模拟数据,如下:
```js
import Mock from '@mock';
const resultData = [
{
// 接口地址
methodUrl: '/rest/mock/list',
// 入参
input: {
keyword: '',
currentpageindex: '',
pagesize: ''
},
// 出参
output: Mock.mock({
'infolist|10-20': [
{
title: () => Mock.Random.csentence(10),
date: ()=> Mock.Random.date(),
id: ()=> Mock.Random.guid(),
content: '来源:综合',
photo: () => Mock.Random.image('114x83', '#00405d', '#FFF', 'Mock.js')
}
]
})
}
];
export default resultData;
```
mock 文件定义请求本地 `/rest/mock/list` 时响应 `output` 数据。
### 列表页面
接下来我们在 `m8demo` 下新建 `list.vue` 组件页面
`list.vue` :
基础结构:
```html
<!-- template部分 -->
<template>
<view class="container"></view>
</template>
<!-- script部分 -->
<script lang="ts" setup></script>
<!-- css部分 -->
<style scoped lang="scss"></style>
```
`M8`的 `easycom` 机制,将 M8-UI 组件引用进一步优化,开发者可以直接在 `template` 中使用,无需在 `script` 里额外导入和注册。
根据 下拉刷新 组件 `em-minirefresh` 进行列表数据渲染。补充:
```html
<template>
<view class="container">
<em-minirefresh
ref="scrollPull"
:initPageIndex="initPageIndex"
:page-size="pageSize"
:url="url"
:request-data="dataRequest"
:change-data="dataChange"
>
<template v-slot:default="{ listData }">
<!-- 此处template内为列表list元素,listData为dataChange处理后的接口返回数据 -->
<em-cell v-for="(item, index) in listData" :key="index" :title="item.title" @click="itemClick(item)" />
</template>
</em-minirefresh>
</view>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const url = `${Config.serverUrl}rest/mock/list`;
const initPageIndex = 0;
const pageSize = 10;
const dataRequest = (_currPage, _pageSize) => {
const data = {
// 当前搜索的第几页,数字类型
currentpageindex: _currPage,
// 每页显示记录条数,数字类型
pagesize: _pageSize
};
const requestData = {
params: JSON.stringify(data)
};
return requestData;
};
const dataChange = (res) => {
let data;
if (res && res.status && res.status.code && res.status.code === 1) {
data = res.custom.infolist;
} else {
console.error('接口返回参数错误');
}
return data;
};
const itemClick = (item) => {
ejs.page.open({
pageUrl: './detail',
data: {
id: item.id
}
});
};
</script>
<!-- css部分 -->
<style lang="scss" scoped>
.container {
height: 100vh;
}
</style>
```
## 详情页面
### 页面路由配置
在 `m8demo` 文件夹下的 `router.ts` 文件中补充 `detail` 页面路由配置:
```js
/**
* router.js无需import组件,需要path路径与vue组件名称保持匹配。
* routers数组下有效参数只有path与style。
* 构建时会自动将模块下的路由配置合并到pages.json内。
*/
// 定义路由规则,url匹配path时,加载component组件页面
const routes = [
{
// ...
},
{
path: 'pages/m8demo/detail',
style: {
navigationBarTitleText: '详情页面'
}
}
];
// 导出路由文件
export default routes;
```
### mock数据配置
在 `m8demo` 文件夹中的 `mock.ts` 文件中补充 `detail` 页面的 mock 数据:
```js
import Mock from '@mock';
const resultData = [
{
// ...
},
{
// 接口地址
methodUrl: '/rest/mock/detail',
// 入参
input: {
guid: ''
},
// 出参
output: Mock.mock({
info: {
title: Mock.Random.csentence(5, 10), // 随机生成一段中文文本。
data: Mock.Random.csentence(25, 30)
}
})
}
];
export default resultData;
```
接下来我们在 `m8demo` 下新建 `detail.vue` 组件页面
`detail.vue` :
```js
<template>
<div class="container">
<h1>{{ title }}</h1>
<div v-html="content"></div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
const title = ref('');
const content = ref('');
const getDetail = (id) => {
Util.ajax({
url: `${Config.serverUrl}rest/mock/detail`,
data: {
params: JSON.stringify({
guid: id
})
}
})
.then((result) => {
if (result && result.status && result.status.code === 1) {
title.value = result.custom.info.title;
content.value = result.custom.info.data;
}
})
.catch((err) => {
console.error(err);
});
};
onLoad(({ id }) => {
getDetail(id);
});
</script>
```
一个简单的列表详情页面就完成了