笔记来源:拉勾教育 - 大前端就业集训营
文章内容:学习过程中的笔记、感悟、和经验
学习、课程详情、课时视频
学习功能
布局处理
使用公共底部导航栏
使用Vant的顶部导航栏组件
src/views/study/index.vue 添加顶部和底部导航栏
<template>
<div class="study">
<!-- 顶部标题栏 -->
<van-nav-bar title="已购课程"/>
<!-- 底部导航栏 -->
<footBar></footBar>
</div>
</template>
<script>
// 引入公共底部导航栏
import footBar from '@/common/foot-bar'
export default {
name: 'study',
// 注册组件
components: {
footBar
}
}
</script>
公共组件处理
课程列表和选课功能是相同的,可以共用同一个组件,封装为公共组件
学习功能使用组件,调整部分样式
把选课下面的课程列表组件移动到公共组件牡蛎common中
src/views/course/index.vue 修改课程列表饮用地址
// 引入课程列表组件
import courseList from '@/common/course-list'
src/views/study/index.vue 学习页面使用移动后的课程列表组件,并调整样式
..............
<script>
..............
// 引入课程列表组件
import courseList from '@/common/course-list'
..............
</script>
<style lang="scss" scoped>
// 调整课程列表整体
.van-pull-refresh {
top: 46px;
bottom: 50px;
}
</style>
接口抽离
使用父组件向子组件传值的方式将接口传递给子组件,子组件使用即可
// src/api/course.js 封装获取已购课程接口
// 获取已购课程
export const getPurchaseCourse = () => {
return axios({
method: 'get',
url: '/front/course/getPurchaseCourse'
})
}
src/views/study/index.vue 学习界面引入接口并把接口传递给子组件
<template>
<div class="study">
..........
<!-- 创建课程列表组件实例 -->
<courseList :getData="getData" />
..........
</div>
</template>
<script>
// 引入接口:获取已购课程
import { getPurchaseCourse } from '@/api/course'
............
src/views/course/index.vue 选课界面同样把接口传递给子组件
<!-- 创建课程列表组件实例,使用参数传递的方法将要使用的接口传递给子组件 -->
<courseList :getData="getData" />
// 引入接口:获取广告位及对应广告 , 分页查询课程
import { getAllAds, getQueryCourses } from '@/api/course'
src/common/course-list.vue 课程列表组件拿到接口之后使用接口获取数据,注意不同接口返回数据名称不同,并且已购课程不分页,需要考虑到
<template>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<!-- 列表组件 -->
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<!-- 列表项,使用for循环 -->
<van-cell v-for="item in listData" :key="item.id">
<!-- 左侧图片,因为两个接口返回数据名字不同,使用||判断取值 -->
<img :src="item.courseImgUrl || item.image" alt="">
<!-- 右侧信息 -->
<div class="r">
<h3>{{item.courseName || item.name}}</h3>
<p class="FirstField">{{item.previewFirstField}}</p>
<!-- 已购课程不返回也不需要展示价格,判断是否有价格字段即可 -->
<p v-if="item.price">
<span class="discounts">¥{{item.discounts}}</span>
<!-- 直接使用删除线 -->
<s>¥{{item.price}}</s>
</p>
</div>
</van-cell>
</van-list>
</van-pull-refresh>
</template>
<script>
export default {
name: 'courseList',
// 接收参数
props: {
// 接收父组件传递过来的接口
getData: {
type: Function, // 类型为函数
required: true // 必须
}
},
data () {
return {
// 信号值 - 标记是否列表加载完毕
finished: false,
// 信号值 - 标记列表是否处于刷新状态
loading: false,
// 列表数据
listData: [],
// 课程查询页码
currentPage: 1,
// 信号值 - 下拉刷新
refreshing: false
}
},
methods: {
// 下拉刷新函数
async onRefresh () {
// 重置页码为 1
this.currentPage = 1
// 判断接口名字,如果已购课程接口,列表依旧触底(否则如果数据较少会导致自动触发onLoad)
this.finished = this.getData.name === 'getPurchaseCourse'
// 调用父组件传递过来的接口获取数据
const { data } = await this.getData({
currentPage: this.currentPage,
pageSize: 10,
status: 1
})
// 根据请求结果判断当前显示的页面
if (data.code === '000000' && data.data.records !== 0) {
// 获取全部课程成功执行
// 直接替换数据
this.listData = data.data.records
// 页数 +1
this.currentPage++
// 修改下拉刷新信号值
this.refreshing = false
// 弹出提示
this.$toast('刷新成功')
} else if (data.content) {
// 获取已购课程成功
// 直接替换数据
this.listData = data.content
// 页数 +1
this.currentPage++
// 修改下拉刷新信号值
this.refreshing = false
// 弹出提示
this.$toast('刷新成功')
}
},
// 列表触底刷新事件,第一次加载的时候就会默认执行一次
async onLoad () {
// 调用父组件传递过来的接口获取数据
const { data } = await this.getData({
currentPage: this.currentPage,
pageSize: 10,
status: 1
})
// 根据请求结果判断当前显示的页面
if (data.code === '000000' && data.data.records !== 0) {
// 获取课程列表成功
// 向列表添加数据
this.listData.push(...data.data.records)
// 页数 +1
this.currentPage++
if (this.listData.length >= data.data.total) {
// 如果列表长度大于等于总条数,设置触底
this.finished = true
}
} else if (data.content) {
// 获取已购课程成功
// 向列表添加数据(其实也可以直接替换,因为这个接口返回的数据不分页)
this.listData.push(...data.content)
// 页数 +1
this.currentPage++
// 直接设置触底
this.finished = true
}
// 无论如何都要设置加载状态结束
this.loading = false
}
}
}
</script>
<style lang="scss" scoped>
// 列表整体定位
.van-pull-refresh {
position: fixed;
left: 0;
right: 0;
overflow-y: auto; // 开启Y轴滚动条
// 单个课程
.van-cell .van-cell__value {
display: flex;
// 清除默认效果
h3, p {
margin: 0;
}
img {
height: 100px;
width: 75px;
border-radius: 5px;
}
.r {
display: flex;
flex-direction: column;
margin-left: 10px;
.FirstField {
flex-grow: 1;
}
p .discounts {
margin-right: 10px;
color: #ff7452;
}
p s {
color: #ccc;
}
}
}
}
</style>
封装接口与数据绑定
使用获取已购课程接口
绑定数据即可,但接口返回数据名字不同
使用数据时进行||判断,分情况获取不同数据,价格不需要加载了,使用v-if判断是否有价格数据
上面已经搞定了
课程详情
选课页面和学习页面都支持跳转详情页
组件准备
课程详情为单独组件,不需要登录即可访问
课程详情需要根据课程id不同展示不同内容,需要使用动态路由参数和路径传参
点击列表项的时候跳转到详情页面,并带着课程id - params
// src/router/index.js 添加新路由 - 课程详情
{ // 课程详情
name: 'course-info',
path: '/course-info/:courseId',
component: () => import(/* webpackChunkName: 'course-info' */'@/views/course-info'),
// 设置路径参数
props: true
}
src/common/course-list.vue 课程列表设置点击事件,跳转到课程详情页,并且带着课程id
<!-- 列表项,使用for循环 ,添加点击事件跳转到课程详情页-->
<van-cell v-for="item in listData" :key="item.id" @click="$router.push(`/course-info/${item.id}`)">
src/views/course-info/index.vue 新建课程详情目录和文件
<template>
<div>{{ courseId }}</div>
</template>
<script>
export default {
name: 'course-info',
// 接收参数
props: {
// 路径参数
courseId: {
type: [Number, String],
required: true
}
}
}
</script>
接口封装
使用获取课程详情接口,在页面初始化的时候获取数据
将获取到的数据存储起来以便后面使用
// src/api/course.js 封装获取课程详情接口
// 获取课程详情
export const getCourseById = courseId => {
return axios({
method: 'get',
url: '/front/course/getCourseById',
params: {
courseId
}
})
}
src/views/course-info/index.vue 初始化的时候利用路径参数获取课程详情
<template>
<div>{{ courseId }}</div>
</template>
<script>
// 引入接口:获取课程详情
import { getCourseById } from '@/api/course'
export default {
name: 'course-info',
// 接收参数
props: {
// 路径参数
courseId: {
type: [Number, String],
required: true
}
},
data () {
return {
// 课程详情
info: {}
}
},
// 钩子函数
created () {
// 调用函数
this.getCourseInfo()
},
methods: {
// 初始化获取课程详情
async getCourseInfo () {
const { data } = await getCourseById(this.courseId)
console.log(data)
}
}
}
</script>
主题内容区域 - 顶部
可以使用之前用过的Vant单元格组件
添加结构绑定数据,进行样式处理
src/views/course-info/index.vue 设定顶部图片,中间文字信息,调整样式
<template>
<!-- 单元格,所有内容全部分布在一个个单元格中 -->
<van-cell-group>
<!-- 顶部图片展示区,绑定数据 -->
<van-cell class="course-image">
<van-image
width="375px"
height="280px"
fit="fill"
:src="info.courseImgUrl"
/>
</van-cell>
<!-- 课程文字信息 -->
<van-cell class="info-text">
<h2>{{info.courseName}}</h2>
<p>{{info.previewFirstField}}</p>
<p class="info-text-buy">
<span class="l">
<i class="discounts">¥{{info.discounts}}</i>
<i class="price">¥{{info.price}}</i>
</span>
<span class="r">
<i>{{info.sales}}人已购</i>
<i>每周三、周五更新</i>
</span>
</p>
</van-cell>
</van-cell-group>
</template>
<script>
// 引入接口:获取课程详情
import { getCourseById } from '@/api/course'
export default {
name: 'course-info',
// 接收参数
props: {
// 路径参数
courseId: {
type: [Number, String],
required: true
}
},
data () {
return {
// 课程详情
info: {}
}
},
// 钩子函数
created () {
// 调用函数
this.getCourseInfo()
},
methods: {
// 初始化获取课程详情
async getCourseInfo () {
const { data } = await getCourseById(this.courseId)
console.log(data)
// 把获取到的课程详情数据交给data
this.info = data.content
}
}
}
</script>
<style lang="scss" scoped>
// 去掉默认的伪造元素
.van-hairline--top-bottom::after,
.van-cell::after {
display: none;
}
// 清除单元格组件默认padding
.van-cell {
padding: 0;
}
// 顶部图片
.course-image {
height: 280px;
}
// 中间文字信息
.info-text {
padding: 10px 20px;
.info-text-buy {
display: flex;
justify-content: space-between;
}
.discounts {
margin-right: 5px;
font-size: 24px;
color: #ff7452;
font-weight: 700;
}
.r {
line-height: 28px;
font-size: 12px;
color: #666;
i {
padding: 7px 8px;
border-radius: 5px;
margin-left: 10px;
background: #f8f9fa;
font-weight: 700;
}
}
}
</style>
选项卡处理
使用Vant的标签页组件,开启粘性布局会在切换后自动吸附到顶部,使用滚动导航属性
添加结构绑定数据,处理样式
课程详情信息后台是通过富文本编辑器保存的,所以直接使用v-html设置即可
src/views/course-info/index.vue 添加课程详情和内容,先设置课程详情
<!-- 底部课程详情、内容 -->
<van-cell class="tabs">
<!-- tab标签,开启粘性布局、滚动 -->
<van-tabs scrollspy sticky>
<!-- 详情 -->
<van-tab title="详情">
<!-- 绑定数据 -->
<div v-html="info.courseDescription"></div>
</van-tab>
<!-- 内容 -->
<van-tab title="内容">123</van-tab>
</van-tabs>
</van-cell>
</van-cell-group>
章节组件封装
使用获取课程章节接口
单独封装一个章节展示组件,单独章节封装为一个组件,包括章节名、课时
组件内部使用v-for创建结构
下面一起写
章节组件布局
使用数据搭建结构
根据课时是否锁定添加不同的图标
进行样式处理
// src/api/course.js 封装获取课程章节接口
// 获取课程章节
export const getSectionAndLesson = courseId => {
return axios({
method: 'get',
url: '/front/course/session/getSectionAndLesson',
params: {
courseId
}
})
}
src/views/course-info/index.vue 课程内容使用单独封装的课程章节组件,使用v-for遍历全部章节,创建多个章节组件
<template>
<!-- 单元格,所有内容全部分布在一个个单元格中 -->
<van-cell-group>
<!-- 顶部图片展示区,绑定数据 -->
<van-cell class="course-image">
<van-image
width="375px"
height="280px"
fit="fill"
:src="info.courseImgUrl"
/>
</van-cell>
<!-- 课程文字信息 -->
<van-cell class="info-text">
<h2>{{info.courseName}}</h2>
<p>{{info.previewFirstField}}</p>
<p class="info-text-buy">
<span class="l">
<i class="discounts">¥{{info.discounts}}</i>
<i class="price">¥{{info.price}}</i>
</span>
<span class="r">
<i>{{info.sales}}人已购</i>
<i>每周三、周五更新</i>
</span>
</p>
</van-cell>
<!-- 底部课程详情、内容 -->
<van-cell class="tabs">
<!-- tab标签,开启粘性布局、滚动 -->
<van-tabs scrollspy sticky>
<!-- 详情 -->
<van-tab title="详情">
<!-- 绑定数据 -->
<div v-html="info.courseDescription"></div>
</van-tab>
<!-- 内容 -->
<van-tab class="tab-content" title="内容">
<!-- 遍历课程章节 -->
<div v-for="section in SectionAndLesson" :key="section.id">
<!-- 创建章节组件实例,把章节内容 传递给子组件 -->
<lesson :section="section"></lesson>
</div>
</van-tab>
</van-tabs>
</van-cell>
</van-cell-group>
</template>
<script>
// 引入章节组件
import lesson from './son/lesson'
// 引入接口:获取课程详情,获取课程章节
import { getCourseById, getSectionAndLesson } from '@/api/course'
export default {
name: 'course-info',
// 接收参数
props: {
// 路径参数
courseId: {
type: [Number, String],
required: true
}
},
data () {
return {
// 课程详情
info: {},
// 课程章节信息数据
SectionAndLesson: {}
}
},
// 钩子函数
created () {
// 调用函数
this.getCourseInfo()
},
methods: {
// 初始化获取课程详情
async getCourseInfo () {
// 获取课程详情
const { data } = await getCourseById(this.courseId)
// 获取课程章节
const { data: data2 } = await getSectionAndLesson(this.courseId)
// 把获取到的课程详情数据交给data
this.info = data.content
this.SectionAndLesson = data2.content.courseSectionList
}
},
// 注册组件
components: {
lesson
}
}
</script>
<style lang="scss" scoped>
// 去掉默认的伪造元素
// .van-hairline--top-bottom::after,
// .van-cell::after {
// display: none;
// }
// 清除单元格组件默认padding
.van-cell {
padding: 0;
}
// 顶部图片
.course-image {
height: 280px;
}
// 中间文字信息
.info-text {
padding: 10px 20px;
.info-text-buy {
display: flex;
justify-content: space-between;
}
.discounts {
margin-right: 5px;
font-size: 24px;
color: #ff7452;
font-weight: 700;
}
.r {
line-height: 28px;
font-size: 12px;
color: #666;
i {
padding: 7px 8px;
border-radius: 5px;
margin-left: 10px;
background: #f8f9fa;
font-weight: 700;
}
}
}
// 课程内容
.tab-content {
padding: 0 20px;
}
</style>
src/views/course-info/son/lesson.vue 单独封装一个课程章节子组件
<template>
<div class="lesson">
<!-- 章节标题 -->
<h2>{{section.sectionName}}</h2>
<!-- 使用v-for遍历章节课时 -->
<p class="lesson-item" v-for="item in section.courseLessons" :key="item.id">
<span>{{item.theme}}</span>
<!-- 根据是都开放添加不同的图标 -->
<van-icon v-if="item.canPlay" size="20" name="play-circle" />
<van-icon v-else size="20" name="lock" />
</p>
</div>
</template>
<script>
export default {
name: 'lesson',
// 获取参数
props: {
section: {
type: Object,
required: true
}
}
}
</script>
<style lang="scss" scoped>
// 单个课程左右布局
.lesson .lesson-item {
display: flex;
justify-content: space-between;
line-height: 20px;
}
</style>
底部支付处理
底部支付功能在未购买的课程中才会展示,已购买不展示
使用Vant标签栏组件,只借用基本结构,内部内容自己书写
直接书写内容绑定数据即可
最后进行样式处理,注意遮挡问题,转换盒模型
src/views/course-info/index.vue 添加底部标签栏,调整样式
<template>
<div class="course-info">
<!-- 单元格,所有内容全部分布在一个个单元格中 -->
<!-- 样式绑定,实现购买和不购买不同样式 -->
<van-cell-group :style="style">
<!-- 顶部图片展示区,绑定数据 -->
<van-cell class="course-image">
<van-image
width="375px"
height="280px"
fit="fill"
:src="info.courseImgUrl"
/>
</van-cell>
<!-- 课程文字信息 -->
<van-cell class="info-text">
<h2>{{info.courseName}}</h2>
<p>{{info.previewFirstField}}</p>
<p class="info-text-buy">
<span class="l">
<i class="discounts">¥{{info.discounts}}</i>
<i class="price">¥{{info.price}}</i>
</span>
<span class="r">
<i>{{info.sales}}人已购</i>
<i>每周三、周五更新</i>
</span>
</p>
</van-cell>
<!-- 底部课程详情、内容 -->
<van-cell class="tabs">
<!-- tab标签,开启粘性布局、滚动 -->
<van-tabs scrollspy sticky>
<!-- 详情 -->
<van-tab title="详情">
<!-- 绑定数据 -->
<div v-html="info.courseDescription"></div>
</van-tab>
<!-- 内容 -->
<van-tab class="tab-content" title="内容">
<!-- 遍历课程章节 -->
<div v-for="section in SectionAndLesson" :key="section.id">
<!-- 创建章节组件实例,把章节内容 传递给子组件 -->
<lesson :section="section"></lesson>
</div>
</van-tab>
</van-tabs>
</van-cell>
</van-cell-group>
<!-- 底部标签栏 -->
<van-tabbar v-if="!info.isBuy">
<span class="l">
<i>{{info.discountsTag}}</i>
<i class="discounts">¥{{info.discounts}}</i>
<i class="price">¥{{info.price}}</i>
</span>
<van-button type="primary">立即购买</van-button>
</van-tabbar>
</div>
</template>
<script>
// 引入章节组件
import lesson from './son/lesson'
// 引入接口:获取课程详情,获取课程章节
import { getCourseById, getSectionAndLesson } from '@/api/course'
export default {
name: 'course-info',
// 接收参数
props: {
// 路径参数
courseId: {
type: [Number, String],
required: true
}
},
data () {
return {
// 课程详情
info: {},
// 课程章节信息数据
SectionAndLesson: {},
// 样式绑定,购买设置定位为0
style: {
bottom: 0
}
}
},
// 钩子函数
created () {
// 调用函数
this.getCourseInfo()
},
methods: {
// 初始化获取课程详情
async getCourseInfo () {
// 获取课程详情
const { data } = await getCourseById(this.courseId)
// 如果没有购买,将绑定样式清空
if (!data.content.isBuy) this.style = null
console.log(data)
// 获取课程章节
const { data: data2 } = await getSectionAndLesson(this.courseId)
// 把获取到的课程详情数据交给data
this.info = data.content
this.SectionAndLesson = data2.content.courseSectionList
}
},
// 注册组件
components: {
lesson
}
}
</script>
<style lang="scss" scoped>
// 内容区定位
.van-cell-group {
position: fixed;
top: 0;
bottom: 50px;
overflow-y: auto;
}
// 清除单元格组件默认padding
.van-cell {
padding: 0;
}
// 顶部图片
.course-image {
height: 280px;
}
// 中间文字信息
.info-text {
padding: 10px 20px;
.info-text-buy {
display: flex;
justify-content: space-between;
}
.discounts {
margin-right: 5px;
font-size: 24px;
color: #ff7452;
font-weight: 700;
}
.r {
line-height: 28px;
font-size: 12px;
color: #666;
i {
padding: 7px 8px;
border-radius: 5px;
margin-left: 10px;
background: #f8f9fa;
font-weight: 700;
}
}
}
// 课程内容
.tab-content {
padding: 0 20px;
}
// 底部标签栏
.van-tabbar {
display: flex;
box-sizing: border-box;
padding: 0 20px;
justify-content: space-between;
align-items: center;
font-size: 14px;
.l .discounts {
margin: 0 5px;
font-size: 24px;
color: #ff7452;
font-weight: 700;
}
.van-button {
height: 80%;
width: 50%;
}
}
</style>
课时视频
组件准备
单独封装一个组件
设置路由,使用动态路由
在点击课时的时候跳转视频播放页,带上课时id(前提是当前解锁的课程),老师把跳转视频写在了整个课时上
// src/router/index.js 添加课时视频路由
{ // 课时视频
name: 'lesson-video',
path: '/lesson-video/:lessonId',
component: () => import(/* webpackChunkName: 'lesson-video' */'@/views/course-info/lesson-video'),
// 设置路径参数
props: true
},
src/views/course-info/son/lesson.vue 给每一个课时添加点击事件
<!-- 使用v-for遍历章节课时,并给每一个课时添加点击事件-->
<p class="lesson-item" v-for="item in section.courseLessons" :key="item.id" @click="toVideo(item.canPlay, item.id)">
.........................
methods: {
// 课时点击事件,参数分别为 - canPlay:是否解锁,lessonId:课时Id
toVideo (canPlay, lessonId) {
// 如果解锁直接带着课时Id跳转
if (canPlay) return this.$router.push(`/lesson-video/${lessonId}`)
// 未解锁弹出提示
return this.$toast('该课时课程未解锁')
}
}
src/views/course-info/lesson-video.vue 新建课时视频组件
<template>
<div class="lesson-video">
{{lessonId}}
</div>
</template>
<script>
export default {
name: 'lesson-video',
// 获取参数
props: {
// 路径参数
lessonId: {
type: [Number, String],
required: true
}
}
}
</script>
组件结构
顶部使用导航栏组件即可,返回上一页功能保留
使用根据id获取阿里云视频播放信息接口,封装接口
接口可以返回阿里云视频id和授权
// src/api/course.js 封装获取视频播放信息接口
// 获取阿里云视频播放信息
export const videoPlayInfo = lessonId => {
return axios({
method: 'get',
url: '/front/course/media/videoPlayInfo',
params: {
lessonId
}
})
}
src/views/course-info/lesson-video.vue 添加导航栏在初始化后获得视频播放信息
<template>
<div class="lesson-video">
<!-- 顶部导航栏,添加点击返回事件 -->
<van-nav-bar
title="视频"
left-text="返回"
left-arrow
@click-left="$router.go(-1)"
/>
</div>
</template>
<script>
// 引入接口:获取视频播放信息
import { videoPlayInfo } from '@/api/course'
export default {
name: 'lesson-video',
// 获取参数
props: {
// 路径参数
lessonId: {
type: [Number, String],
required: true
}
},
// 钩子函数
created () {
// 获取视频播放信息
this.getVideoInfo()
},
methods: {
// 获取视频播放信息
async getVideoInfo () {
// 调用接口
const { data } = await videoPlayInfo(this.lessonId)
console.log(data)
}
}
}
</script>
阿里云视频播放
使用h5播放器
使用视频点播通过播放凭证播放playauth
推荐使用在线配置功能获取结构(更直观),当然也可以使用它提供的
然后使用生成的代码
最后调整样式
public/index.html 添加阿里云视频播放需要的链接
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 阿里云H5播放css文件 -->
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.9.3/skins/default/aliplayer-min.css" />
<!-- 阿里云bofangjs文件 -->
<script type="text/javascript" charset="utf-8" src="https://g.alicdn.com/de/prismplayer/2.9.3/aliplayer-min.js"></script>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
src/views/course-info/lesson-video.vue 添加阿里云播放器
<template>
<div class="lesson-video">
<!-- 顶部导航栏,添加点击返回事件 -->
<van-nav-bar
title="视频"
left-text="返回"
left-arrow
@click-left="$router.go(-1)"
/>
<!-- 视频播放容器,设置id -->
<div class="prism-player" id="player"></div>
</div>
</template>
<script>
// 禁止eslint检查下面代码,不设置可能会报错,我就报错了
/* eslint-disable*/
// 引入接口:获取视频播放信息
import { videoPlayInfo } from '@/api/course'
export default {
name: 'lesson-video',
// 获取参数
props: {
// 路径参数
lessonId: {
type: [Number, String],
required: true
}
},
// 钩子函数
created () {
// 获取视频播放信息
this.getVideoInfo()
},
methods: {
// 获取视频播放信息
async getVideoInfo () {
// 调用接口
const { data } = await videoPlayInfo(this.lessonId)
// 设置阿里云视频播放器,新建一个实例
const player = new Aliplayer({
// 容器ID
id: 'player',
// 下面两个属性是上面接口返回的视频信息
vid: data.content.fileId,
playauth: data.content.playAuth,
qualitySort: 'asc',
format: 'mp4',
mediaType: 'video',
width: '100%',
height: '500px',
autoplay: true,
isLive: false,
rePlay: false,
playsinline: true,
preload: true,
controlBarVisibility: 'hover',
useH5Prism: true
}, function (player) {
console.log('The player is created')
})
}
}
}
</script>
通过手机查看项目
前提:手机和电脑在一个无线局域网内
获取电脑的无线网ip地址
手机访问电脑IP地址:端口即可访问