阅读 53

Vue3电影中后台开发纪实(三):数据展示

@拿到热映数据

  • 使用POSTMAN提前向后台插入电影数据

配置全局代理

vite.config.js

  // 配置前端服务地址和端口   server: {     host: "0.0.0.0",     port: 5173,     // 是否开启 https     https: false,     // 让开发服务器帮我们做代理     proxy: {       // http://localhost:5173/api       "/api": {         target: "http://localhost:8173", //API服务地址         changeOrigin: true, //开启跨域         rewrite: (path) => path.replace(/^\/api/, ""),       },     },   }, 复制代码

配置网络应用层

src/api/movieApi.js

import axios from "axios"; import { doGet } from "./service/crud"; /* 获取正在热映列表 */ export async function getPlayings() {   // localhost:5173/api/film/0 => vite会将该地址代理到localhost:8173/film/0   const {arr:films} = await doGet(`/film/0`);   return films; } 复制代码

组件挂载时获取数据

src/views/film/Playing.vue

import { getPlayings } from "@api/movieApi"; /* 组件挂载完毕后发起AJAX请求 */ onMounted(async () => {   const films = await getPlayings();   console.log("films=", films); }); 复制代码

@表格展示数据

分页加载

src/views/film/Playing.vue

/* 完整电影列表 */ const tableData = ref([]); /* 要显示的分页数据 */ const currentPage = ref(1); const computedData = computed(() =>   tableData.value.slice((currentPage.value - 1) * 10, currentPage.value * 10) ); /* 组件挂载完毕后发起AJAX请求 */ onMounted(async () => {   const films = await getPlayings();   console.log("films=", films);   tableData.value = films; }); 复制代码

表格列展示数据

<el-table   :data="computedData"   stripe   style="width: 100%"   :default-sort="{ prop: 'date', order: 'ascending' }"   @selection-change="handleSelectionChange" >   <!-- 多选显示栏 -->   <el-table-column type="selection" width="40" />   <!-- fixed固定 sortable字段可排序 label=当前列标题 width当前列像素宽度 -->   <el-table-column sortable fixed prop="filmId" label="id" width="100" />   <!-- 片名 -->   <el-table-column sortable prop="name" label="片名" width="180" />   <!-- 海报 -->   <el-table-column prop="poster" label="海报" width="60" >     <template #default="{row:{poster}}">       <div style="display: flex; align-items: center">         <el-image :src="poster" />       </div>     </template>   </el-table-column>   <!-- 主演 -->   <el-table-column     sortable     prop="actors"     label="主演"     :formatter="formatActors"     width="200"   />   <!-- 国家 -->   <el-table-column sortable prop="nation" label="国家" width="150" />   <!-- 类型 -->   <el-table-column sortable prop="category" label="类型" width="150" />   <!-- 片长 -->   <el-table-column sortable prop="runtime" label="片长" width="100" />   <!-- 评分 -->   <el-table-column sortable prop="grade" label="评分" width="100" />   <!-- 首映日期 -->   <el-table-column     sortable     prop="premiereAt"     label="首映日期"     :formatter="formatPremierAt"     width="150"   />   <!-- fixed="right"右侧固定 -->   <el-table-column fixed="right" label="操作" width="90">     <!-- 覆盖为小号圆形的编辑按钮与删除按钮 -->     <template #default>       <el-button type="primary" :icon="Edit" circle size="small" />       <el-button type="danger" :icon="Delete" circle size="small" />     </template>   </el-table-column> </el-table> 复制代码

数据格式化

/* 数据格式化函数 */ const formatPremierAt = (row, column, cellValue, index) => {   // console.log("row", row);//当前行数据   // console.log("column", column);//当前列信息   // console.log("cellValue", cellValue);//当前要格式化的单元格数据   // console.log("index", index);//当前行行号   return new Date(cellValue * 1000).toLocaleDateString().replaceAll("/", "-"); }; const formatActors = (row, column, cellValue, index) => {   return (     cellValue       .map((actor) => actor.name)       .slice(0, 3)       .join(",") + "等"   ); }; 复制代码

展示电影海报

  <!-- 海报 -->   <el-table-column prop="poster" label="海报" width="60" >     <!-- <template #default="scope"> -->     <template #default="{row:{poster}}">       <div style="display: flex; align-items: center">         <!-- 这里我们通过一个简单的测试发现scope.row.poster即要显示的海报数据 -->         <!-- <el-image :src="showScope(scope)" /> -->         <el-image :src="poster" />       </div>     </template>   </el-table-column> 复制代码

@跳转详情页

定义详情页路由

src/router/index.js

{   // 规定电影id为24个数字或小写字母   path: "/film/:id(\\d+)",   name: "detail",   meta: { hideTabbar: true },   component: () => import("../views/DetailView.vue"), }, 复制代码

跳转详情页

src/views/Playing.vue

  <!-- 右侧固定的操作按钮区 -->   <el-table-column fixed="right" label="操作" width="90">     <!-- action按钮区作用域插槽提供的数据中含有当前行信息row -->     <!-- <template #default="scope"> -->     <!-- 可以通过简单的测试查看一下作用域插槽中携带的数据 -->     <!-- <el-button @click="showScope(scrope)"/> -->     <!-- 从作用域插槽数据中解构出当前行id -->     <template #default="{ row: { _id } }">       <!-- 点击Edit按钮 携带id跳转详情页 -->       <el-button @click="$router.push(`/film/${_id}`)" type="primary" :icon="Edit" circle size="small" />       <el-button type="danger" :icon="Delete" circle size="small" />     </template>   </el-table-column> 复制代码

@详情页数据展示

获取详情数据

src/views/Detail.vue

import { onMounted } from "vue"; import { useRoute } from "vue-router"; import { getDetail } from "@api/movieApi"; /* 获取影片详情 */ onMounted(async () => {   const detail = await getDetail(route.params.id);   console.log("detail=", detail); }); 复制代码

添加Loading效果

<template>   <el-card v-loading="loading">       正文内容...   </el-card> </template> 复制代码

/* 获取影片详情 */ onMounted(async () => {   loading.value = true;   const detail = await getDetail(route.params.id);   console.log("detail=", detail);      /* 将detail中的数据同步到form中 表单中自动同步数据 */   // ...   setTimeout(() => {     loading.value = false;   }, 500); }); 复制代码

定义表格数据

const form = reactive({}); /* 获取影片详情 */ onMounted(async () => {   loading.value = true;   const detail = await getDetail(route.params.id);   console.log("detail=", detail);   /* 将detail中的数据同步到form中 表单中自动同步数据 */   Object.assign(form, detail, {     premiereAt: detail.premiereAt * 1000,     // 影片类型 表单复选 应双向绑定一个数组     category: detail.category.split("|"),     // 重构actcors数据     actors: detail.actors.map(({ name, role, avatarAddress }) => ({       name: `${name}-${role}`,       url: avatarAddress,     })),   });   setTimeout(() => {     loading.value = false;   }, 500); }); 复制代码

表格展示数据

<template>   <el-card v-loading="loading">     <template #header>       <div class="card-header">         <span>影片详情</span>         <!-- <el-button text>Operation button</el-button> -->       </div>     </template>     <!-- 详情表单 -->     <!-- form没有数据时不渲染form -->     <el-form v-if="form[`name`]" :model="form" label-width="120px">       <!-- 片名关联form.name -->       <el-form-item label="片名">         <el-input v-model="form.name" />       </el-form-item>       <!-- 片长关联form.runtime -->       <el-form-item label="片长">         <el-col :span="7">           <el-input v-model="form.runtime" type="number" />         </el-col>       </el-form-item>       <!-- 评分关联form.grade -->       <el-form-item label="评分">         <el-col :span="7">           <el-input v-model="form.grade" />         </el-col>       </el-form-item>       <!-- 影片类型关联form.filmType.name -->       <!-- filmType?.name 如果filmType不为null/undeined 就继续读取filmType?.name 否则直接返回null/undeined -->       <el-form-item label="影片类型">         <el-select           v-model="form.filmType.name"           placeholder="please select your zone"         >           <el-option label="2D" value="2D" />           <el-option label="3D" value="3D" />           <el-option label="4D" value="4D" />         </el-select>       </el-form-item>       <!-- 影片类型关联form.premiereAt -->       <el-form-item label="首映日期">         <el-col :span="8">           <el-date-picker             v-model="form.premiereAt"             type="date"             placeholder="Pick a date"             style="width: 100%"           />         </el-col>       </el-form-item>       <!-- 在映关联form.isPresale -->       <el-form-item label="在映">         <el-switch v-model="form.isPresale" />       </el-form-item>       <!-- 影片类型关联form.category -->       <el-form-item label="影片类型">         <el-checkbox-group v-model="form.category">           <el-checkbox label="爱情" name="category" />           <el-checkbox label="动作" name="category" />           <el-checkbox label="科幻" name="category" />           <el-checkbox label="历史" name="category" />           <el-checkbox label="悬疑" name="category" />           <el-checkbox label="喜剧" name="category" />           <el-checkbox label="战争" name="category" />           <el-checkbox label="剧情" name="category" />           <el-checkbox label="犯罪" name="category" />           <el-checkbox label="纪录片" name="category" />         </el-checkbox-group>       </el-form-item>       <!-- 国家关联form.nation -->       <el-form-item label="国家">         <el-radio-group v-model="form.nation">           <el-radio label="中国大陆" />           <el-radio label="欧美" />           <el-radio label="日韩" />           <el-radio label="其它" />         </el-radio-group>       </el-form-item>       <!-- 演职人员关联form.actors -->       <!--        :on-preview="handlePreview"       :on-remove="handleRemove"        -->       <el-form-item label="演职人员">         <el-upload           v-model:file-list="form.actors"           class="upload-demo"           list-type="picture-card"           action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"         >           <el-icon><Plus /></el-icon>         </el-upload>       </el-form-item>       <!-- 海报关联form.poster -->       <el-form-item label="海报">         <el-upload           v-model:file-list="form.poster"           action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"           list-type="picture-card"         >           <el-icon><Plus /></el-icon>         </el-upload>       </el-form-item>       <!-- 剧情摘要form.synopsis -->       <el-form-item label="剧情摘要">         <el-input v-model="form.synopsis" autosize type="textarea" />       </el-form-item>       <!-- 提交与重置 -->       <el-form-item>         <el-button class="opBtn" type="primary" @click="onSubmit">更新</el-button>         <el-button class="opBtn">重置</el-button>       </el-form-item>     </el-form>   </el-card> </template>


作者:搬砖的乔布梭
链接:https://juejin.cn/post/7169131209983787039


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐