前端项目开发流程与前后端联调


在这里插入图片描述

想学习架构师构建流程请跳转:Java架构师系统架构设计

1 前端项目开发流程

1.1 项目开发流程

在这里插入图片描述

1.1.1定义路由模块

src/router/index.js

配置讲师管理相关路由

1.1.2 定义api模块

创建文件 src/api/teacher.js

前端请求接口定义,只是定义接口,不是实际调用,实际调用在,.vue文件中

// @ 符号在build/webpack.base.conf.js 中配置 表示 'src' 路径
import request from '@/utils/request'
export default {
  list() {
    return request({
      url: '/admin/edu/teacher/list',
      method: 'get'
    })
  }
}

1.1.3 定义页面组件脚本

src/views/teacher/list.vue

调用api获得数据

<script>
import teacherApi from '@/api/teacher'
export default {
  // 定义数据模型
  data() {
    return {
      list: [] // 讲师列表
    }
  },
  // 页面渲染成功后获取数据
  created() {
    this.fetchData()
  },
  // 定义方法
  methods: {
    fetchData() {
      // 调用api
      teacherApi.list().then(response => {
        this.list = response.data.items
      })
    }
  }
}
</script>

1.1.4 定义页面组件模板

数据做了一个:data="list"绑定,之后数据自动渲染到页面

<!-- 表格 -->
<el-table :data="list" border stripe>
    <el-table-column type="index" width="50"/>
    <el-table-column prop="name" label="名称" width="80" />
    <el-table-column label="头衔" width="90">
        <template slot-scope="scope">
          <el-tag v-if="scope.row.level === 1" type="success" size="mini">高级讲师</el-tag>
          <el-tag v-if="scope.row.level === 2" size="mini">首席讲师</el-tag>
        </template>
    </el-table-column>
    <el-table-column prop="intro" label="简介" />
    <el-table-column prop="sort" label="排序" width="60" />
    <el-table-column prop="joinDate" label="入驻时间" width="160" />
</el-table>

1.2项目执行流程

1.2.1 页面加载流程

在这里插入图片描述

1.2.2 页面渲染流程

在这里插入图片描述

2 分页列表组件

2.1 分页查询

2.1.1 定义api模块

src/api/teacher.js

get请求用 params传参,是键值对的形式,拼接到字符串后面

pageList(page, limit, searchObj) {
    return request({
        url: `/admin/edu/teacher/list/${page}/${limit}`,
        method: 'get',
        params: searchObj
    })
}

2.1.2、定义页面组件脚本

src/views/teacher/list.vue,完善data定义,之后将完整参数发送请求,最后回显数据

data() {// 定义数据
    return {
        list: null, // 数据列表
        total: 0, // 总记录数
        page: 1, // 页码
        limit: 10, // 每页记录数
        searchObj: {}// 查询条件
    }
}

修改fetchData方法

fetchData() {
    // 调用api
    teacherApi.pageList(this.page, this.limit, this.searchObj).then(response => {
        this.list = response.data.rows
        this.total = response.data.total
    })
}

2.1.3、定义页面组件模板

在table组件下面添加分页组件

<!-- 分页组件 -->
<el-pagination
  :current-page="page"
  :total="total"
  :page-size="limit"
  :page-sizes="[5, 10, 20, 30, 40, 50, 100]"
  style="padding: 30px 0; text-align: center;"
  layout="total, sizes, prev, pager, next, jumper"
/>

2.1.4、改变每页条数

为组件注册事件
在这里插入图片描述

当注册时间有回调参数时不必要自己传入,也就是绑定的方法@size-change会自动注入一个参数,比如当前页,之后绑定方法的名字changePageSize可以不用传参,只需到时候调用随便给个参数名字之后就可以获得参数值,changePageSize(size),得到参数.这就好比回调函数的then中的response=>也不是自己创建的,到时候框架会自动获得.如果传入带()就成了方法调用,而不是方法引用框架就不会为我们获得参数,只是引用其中的方法.你传的东西啥事儿都干不了!

@size-change="changePageSize"

定义事件脚本

// 每页记录数改变,size:回调参数,表示当前选中的“每页条数”
changePageSize(size) {
    this.limit = size
    this.fetchData()
}

2.1.5 翻页

为组件注册事件

@current-change="changeCurrentPage"

定义事件脚本

// 改变页码,page:回调参数,表示当前选中的“页码”
changeCurrentPage(page) {
    this.page = page
    this.fetchData()
},  

2.1.6 序号列

这里是防止到了第二页显示还是 1 2 3 4 这样的序号,然后会变为5 6 7 8

<el-table-column
  label="#"
  width="50">
  <template slot-scope="scope">
    {{ (page - 1) * limit + scope.$index + 1 }}
  </template>
</el-table-column>

2.1.7 查询表单

在table组件上面添加查询表单

<!--查询表单-->
<el-form :inline="true">
    <el-form-item>
        <el-input v-model="searchObj.name" placeholder="讲师"/>
    </el-form-item>
    <el-form-item>
        <el-select v-model="searchObj.level" clearable placeholder="头衔">
            <el-option value="1" label="高级讲师"/>
            <el-option value="2" label="首席讲师"/>
        </el-select>
    </el-form-item>
    <el-form-item label="入驻时间">
        <el-date-picker
                        v-model="searchObj.joinDateBegin"
                        placeholder="开始时间"
                        value-format="yyyy-MM-dd" />
    </el-form-item>
    <el-form-item label="-">
        <el-date-picker
                        v-model="searchObj.joinDateEnd"
                        placeholder="结束时间"
                        value-format="yyyy-MM-dd" />
    </el-form-item>
    <el-form-item>
        <el-button type="primary" icon="el-icon-search" @click="fetchData()">查询</el-button>
        <el-button type="default" @click="resetData()">清空</el-button>
    </el-form-item>
</el-form>

重置表单脚本

// 重置表单
resetData() {
    this.searchObj = {}
    this.fetchData()
}

2.2 数据删除

2.2.1、定义api模块

src/api/teacher.js

removeById(id) {
    return request({
        url: `/admin/edu/teacher/remove/${id}`,
        method: 'delete'
    })
}

2.2.2、定义页面组件模板

在table组件中添加删除列

<el-table-column label="操作" width="200" align="center">
    <template slot-scope="scope">
        <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeById(scope.row.id)">删除</el-button>
    </template>
</el-table-column>

2.2.3 定义页面组件脚本

// 根据id删除数据
removeById(id) {
    this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
    }).then(() => {
        return teacherApi.removeById(id)
    }).then((response) => {
        this.fetchData()
        this.$message.success(response.message)
    }).catch(error => {
        console.log('error', error)
        // 当取消时会进入catch语句:error = 'cancel'
        // 当后端服务抛出异常时:error = 'error'
        if (error === 'cancel') {
            this.$message.info('取消删除')
        }
    })
}

2.3 axios响应拦截器

2.3.1、关于code===20000

code!==20000的响应会被拦截,并转到 error=>{} 处理

if (res.code !== 20000) {
    return Promise.reject('error')
}

2.3.2、关于response

code===20000时放行,前端页面接收到response.data的值,而不是response

if (res.code !== 20000) {
    return Promise.reject('error')
} else {
    return response.data
}

2.3.3、关于error

统一处理错误结果,显示错误消息

3 表单组件

3.1 新增讲师

3.1.1、定义api模块

如果是get请求传递键值对的话是param进行传参,如果后台需要json数据的话用data进行传参

src/api/teacher.js

save(teacher) {
    return request({
        url: '/admin/edu/teacher/save',
        method: 'post',
        data: teacher
    })
}

3.1.2 定义页面组件脚本

src/views/teacher/form.vue,完善data定义

<script>
export default {
  data() {
    return {
      // 初始化讲师默认数据
      teacher: {
        sort: 0,
        level: 1
      },
      saveBtnDisabled: false // 保存按钮是否禁用,防止表单重复提交
    }
  }
}
</script>

3.1.3 定义页面组件模板

src/views/teacher/form.vue

<!-- 输入表单 -->
<el-form label-width="120px">
    <el-form-item label="讲师名称">
        <el-input v-model="teacher.name" />
    </el-form-item>
    <el-form-item label="入驻时间">
        <el-date-picker v-model="teacher.joinDate" value-format="yyyy-MM-dd" />
    </el-form-item>
    <el-form-item label="讲师排序">
        <el-input-number v-model="teacher.sort" :min="0"/>
    </el-form-item>
    <el-form-item label="讲师头衔">
        <el-select v-model="teacher.level">
            <!--
            数据类型一定要和取出的json中的一致,否则没法回填
            因此,这里value使用动态绑定的值,保证其数据类型是number
            -->
            <el-option :value="1" label="高级讲师"/>
            <el-option :value="2" label="首席讲师"/>
        </el-select>
    </el-form-item>
    <el-form-item label="讲师简介">
        <el-input v-model="teacher.intro"/>
    </el-form-item>
    <el-form-item label="讲师资历">
       <el-input v-model="teacher.career" :rows="10" type="textarea"/>
    </el-form-item>
    <!-- 讲师头像:TODO -->
    <el-form-item>
        <el-button :disabled="saveBtnDisabled" type="primary" @click="saveOrUpdate()">保存</el-button>
    </el-form-item>
</el-form>

3.1.4 实现新增功能

src/views/teacher/form.vue,引入teacher api模块:

import teacherApi from '@/api/teacher'

定义保存方法

methods: {
  saveOrUpdate() {
    // 禁用保存按钮
    this.saveBtnDisabled = true
    this.saveData()
  },
  // 新增讲师
  saveData() {
    // debugger
    teacherApi.save(this.teacher).then(response => {
      this.$message({
        type: 'success',
        message: response.message
      })
      this.$router.push({ path: '/teacher' })
    })
  }
}

3.2 显示讲师信息

3.2.1 定义api模块

src/api/teacher.js

getById(id) {
    return request({
        url: `/admin/edu/teacher/get/${id}`,
        method: 'get'
    })
}

3.2.2 定义页面组件脚本

src/views/teacher/form.vue,methods中定义回显方法

// 根据id查询记录
fetchDataById(id) {
    teacherApi.getById(id).then(response => {
        this.teacher = response.data.item
    })
}

页面渲染成功后获取数据

因为已在路由中定义如下内容:path: ‘edit/:id’,因此可以使用 this.$route.params.id 获取路由中的id

//页面渲染成功
created() {
    if (this.$route.params.id) {
        this.fetchDataById(this.$route.params.id)
    }
}

3.2.3、定义页面组件模板

src/views/teacher/list.vue,表格“操作”列中增加“修改”按钮

<router-link :to="'/teacher/edit/'+scope.row.id">
    <el-button type="primary" size="mini" icon="el-icon-edit">修改</el-button>
</router-link>

3.3 更新讲师

3.3.1 定义api模块

src/api/teacher.js

updateById(teacher) {
    return request({
        url: '/admin/edu/teacher/update',
        method: 'put',
        data: teacher
    })
}

3.3.2、定义页面组件脚本

src/views/teacher/form.vue,methods中定义updateData

// 根据id更新记录
updateData() {
  // teacher数据的获取
  teacherApi.updateById(this.teacher).then(response => {
      this.$message({
        type: 'success',
        message: response.message
      })
      this.$router.push({ path: '/teacher' })
  })
},

完善saveOrUpdate方法

saveOrUpdate() {
    // 禁用保存按钮
    this.saveBtnDisabled = true
    if (!this.teacher.id) {
        this.saveData()
    } else {
        this.updateData()
    }
}

3.4 组件重用问题

**问题:**vue-router导航切换 时,如果两个路由都渲染同个组件,

组件的生命周期方法(created或者mounted)不会再被调用, 组件会被重用,显示上一个路由渲染出来的自建

**解决方案:**可以简单的在 router-view上加上一个唯一的key,来保证路由切换时都会重新触发生命周期方法,确保组件被重新初始化。

修改 src/views/layout/components/AppMain.vue 文件如下:

<router-view :key="key"></router-view>
computed: {
    key() {
        return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date()
    }
 }

4 关于计算属性

解决:组件重用问题 每使用一次数学都会重新计算,而方法会从本地上次计算好的重新取出来.

在这里插入图片描述

创建 08-计算属性.html

例1:模板中使用js表达式

new Vue({
    el: '#app',
    data: {
        message: 'hello'
    }
})

模板表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会难以维护。

<p>原始值: {{ message }}</p>
<!-- 1、插值数据绑定中使用表达式 -->
<p>反转消息: {{ message.split('').reverse().join('') }}</p>

所以,对于任何复杂逻辑,你都应当使用计算属性

例2:使用计算属性

computed: {
    reversedMessage () {
        console.log('计算属性执行')
        return this.message.split('').reverse().join('')
    }
}
<!-- 2、使用计算属性 -->
<p>反转消息: {{ reversedMessage }}</p>

例3:使用方法

methods:{
    reversed () {
        console.log('方法执行')
        return this.message.split('').reverse().join('')
    }
}
<!-- 3、使用方法 -->
<p>反转消息: {{ reversed() }}</p>

计算属性缓存 vs 方法
(https://cn.vuejs.org/v2/guide/computed.html#计算属性缓存-vs-方法)

看起来计算属性和方法能完成相同的功能,那么他们有什么区别呢?

  • **计算属性基于缓存:**在相关依赖发生改变时它们才会重新求值。
  • 方法将总会再次执行
<!-- 2、使用计算属性 -->
<p>反转消息: {{ reversedMessage }}</p>
<!-- 调用两次只执行一次属性的计算 -->
<p>反转消息: {{ reversedMessage }}</p>
<!-- 3、使用方法 -->
<p>反转消息: {{ reversed() }}</p>
<!-- 调用两次执行了两次属性的计算 -->
<p>反转消息: {{ reversed() }}</p>

5 关于Vue组件

5.1 什么是组件

组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用界面都可以抽象为一个组件树:

在这里插入图片描述

5.2 前端项目组件分析

5.2.1、三要素

  • 入口js:src/main.js
  • 入口页面:src/App.vue
  • 路由:src/router/index.js

main.js 中引入了App.vue和 router/index.js,根据路由配置,App.vue中会显示相应的页面内容

5.2.2、入口文件

src/main.js

在这里插入图片描述

5.2.3、主页面模块

src/App.vue

在这里插入图片描述

5.2.4、路由模块

src/router/index.js

在这里插入图片描述

5.2.5、登录页面组件

在这里插入图片描述

5.3 前端项目布局分析

5.3.1、路由模块

src/router/index.js

在这里插入图片描述

5.3.2、布局模块

src/views/layout/Layout.vue

在这里插入图片描述

5.3.3、核心内容区域

src/views/layout/components/AppMain.vue

在这里插入图片描述

5.3.4、讲师列表页面组件

在这里插入图片描述

  • 12
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
前后端联调是指前端和后端在开发过程中需要进行数据交互和接口调试的过程。一般来说,前后端联调可以分为以下几个步骤: 1. 确定接口文档:前后端需要共同确定接口文档,包括接口的请求参数、响应参数、返回码等内容。 2. 前端调用接口:前端根据接口文档编写相应的代码,调用后端提供的接口,并将请求参数发送给后端。 3. 后端处理请求:后端接收到前端发送的请求后,根据请求参数进行相应的处理,并返回响应数据。 4. 前端处理响应数据:前端接收到后端返回的响应数据后,根据响应参数进行相应的处理,例如展示数据、更新页面等。 5. 调试接口:在前后端联调过程中,需要不断地调试接口,确保接口的正确性和稳定性。 6. 修复问题:如果在联调过程中发现问题,需要及时修复并重新调试接口。 除了以上步骤,前后端联调还需要注意以下几点: 1. 接口命名规范:前后端需要遵守一定的接口命名规范,以避免出现混淆和错误调用的情况。 2. 参数校验:前后端需要对接口的请求参数进行校验,以确保参数的正确性和安全性。 3. 接口安全:前后端需要对接口进行安全性验证,避免恶意攻击和非法调用。 总之,前后端联调是一个需要前后端密切配合、不断调试的过程,通过良好的沟通和协作,可以让项目顺利进行并保证接口的正确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵广陆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值