hookehuyr

✨ feat(视频组件): 结构vue3,api请求模块化改造

1 +import axios from '@/utils/axios';
2 +import { fn } from '@/api/fn';
3 +
4 +const Api = {
5 + PROD_ACTION: '/srv/?a=prod_action',
6 + PROD_INFO: '/srv/?a=prod_info',
7 +}
8 +
9 +/**
10 + * @description: 操作作品动作
11 + * @param {String} type 动作类型:like, favor, play
12 + * @param {String} prod_id 作品 ID
13 + * @returns
14 + */
15 +export const prodActionAPI = (params) => fn(axios.post(Api.PROD_ACTION, params))
16 +
17 +/**
18 + * @description: 查询作品详情
19 + * @param {String} type 动作类型:like, favor, play
20 + * @param {String} prod_id 作品 ID
21 + * @returns
22 + */
23 +export const prodInfoAPI = (params) => fn(axios.get(Api.PROD_INFO, { params }))
...@@ -9,7 +9,7 @@ export const fn = (api) => { ...@@ -9,7 +9,7 @@ export const fn = (api) => {
9 return api 9 return api
10 .then(res => { 10 .then(res => {
11 if (res.data.code === 1) { 11 if (res.data.code === 1) {
12 - return res.data.data || true; 12 + return res.data || true;
13 } else { 13 } else {
14 console.warn(res); 14 console.warn(res);
15 if (!res.data.show) return false; 15 if (!res.data.show) return false;
......
1 <template> 1 <template>
2 <div class="video-wrapper"> 2 <div class="video-wrapper">
3 <div class="video-div" :id="'mui-player-' + item.id"></div> 3 <div class="video-div" :id="'mui-player-' + item.id"></div>
4 - <div v-if="mp" class="normal-module"> 4 + <div class="normal-module">
5 <div class="video-bar"> 5 <div class="video-bar">
6 <van-row> 6 <van-row>
7 <van-col span="12" @click="goTo"> 7 <van-col span="12" @click="goTo">
...@@ -38,48 +38,54 @@ ...@@ -38,48 +38,54 @@
38 /** 38 /**
39 * 视频组件通用模块 39 * 视频组件通用模块
40 */ 40 */
41 -import icon_dianzan1 from '@images/icon-dianzan01@2x.png' 41 +import { icon_dianzan1, icon_dianzan2, icon_liuyan, icon_avatar } from '@/utils/generateIcons.js'
42 -import icon_dianzan2 from '@images/icon-dianzan02@2x.png'
43 -import icon_liuyan from '@images/icon-liuyan@2x.png'
44 -import icon_avatar from '@images/que-touxiang@2x.png'
45 -
46 import { ref, reactive, onMounted } from 'vue' 42 import { ref, reactive, onMounted } from 'vue'
43 +import { _, Toast } from '@/utils/generatePackage.js'
44 +import { useRoute, useRouter } from 'vue-router'
47 import 'mui-player/dist/mui-player.min.css' 45 import 'mui-player/dist/mui-player.min.css'
48 import MuiPlayer from 'mui-player' 46 import MuiPlayer from 'mui-player'
49 -import _ from 'lodash'; 47 +import { prodActionAPI, prodInfoAPI } from '@/api/C/prod.js'
50 -import axios from 'axios';
51 -import { Toast } from 'vant';
52 48
53 -import { useRoute, useRouter } from 'vue-router'
54 const $route = useRoute(); 49 const $route = useRoute();
55 const $router = useRouter(); 50 const $router = useRouter();
56 51
57 -onMounted(() => { 52 +const props = defineProps({
53 + item: Object
58 }) 54 })
59 55
60 -</script> 56 +// 作品用户操作
57 +async function handleAction(action_type, prod_id) {
58 + const { msg } = await prodActionAPI({ action_type, prod_id });
59 + if (msg === `${action_type}-add-OK`) { // 动作操作成功
60 + if (action_type === 'favor') {
61 + Toast('收藏成功');
62 + }
63 + if (action_type === 'like') {
64 + Toast('点赞成功');
65 + }
66 + } else { // 取消操作
67 + if (action_type !== 'play') {
68 + Toast('取消成功');
69 + }
70 + }
71 + getProductDetail(action_type, prod_id); // 更新信息
72 +}
73 +// 查询作品详情
74 +async function getProductDetail(action_type, prod_id) {
75 + const { data } = await prodInfoAPI({ prod_id });
76 + // 更新详情显示
77 + detail.value[`is_${action_type}`] = data[`is_${action_type}`];
78 + detail.value[`${action_type}_num`] = data[`${action_type}_num`];
79 +}
61 80
62 -<script> 81 +let detail = ref({});
63 -// FIXME: VUE2写法
64 -import mixin from 'common/mixin';
65 82
66 -export default { 83 +onMounted(() => {
67 - mixins: [mixin.likeFn], 84 + const mp = new MuiPlayer({
68 - props: ['item'], 85 + container: '#mui-player-' + props.item.id,
69 - data() { 86 + title: props.item.title,
70 - return { 87 + src: props.item.video,
71 - detail: {}, 88 + poster: props.item.cover,
72 - mp: ''
73 - }
74 - },
75 - created() {
76 - },
77 - mounted() {
78 - var mp = new MuiPlayer({
79 - container: '#mui-player-' + this.item.id,
80 - title: this.item.title,
81 - src: this.item.video,
82 - poster: this.item.cover,
83 autoFit: false, 89 autoFit: false,
84 videoAttribute: [ // 声明启用同层播放, 不让会自动全屏播放 90 videoAttribute: [ // 声明启用同层播放, 不让会自动全屏播放
85 { attrKey: 'webkit-playsinline', attrValue: 'webkit-playsinline' }, 91 { attrKey: 'webkit-playsinline', attrValue: 'webkit-playsinline' },
...@@ -87,37 +93,35 @@ export default { ...@@ -87,37 +93,35 @@ export default {
87 { attrKey: 'x5-video-player-type', attrValue: 'h5-page' }, 93 { attrKey: 'x5-video-player-type', attrValue: 'h5-page' },
88 ] 94 ]
89 }) 95 })
90 - this.mp = mp; 96 + detail.value = _.cloneDeep(props.item);
91 - this.detail = _.cloneDeep(this.item); 97 + const video = mp.video();
92 - var video = mp.video();
93 // 监听原生video事件 98 // 监听原生video事件
94 - var _this = this;
95 video && video.addEventListener('play', function (event) { 99 video && video.addEventListener('play', function (event) {
96 - _this.handleAction('play', _this.item.id) 100 + handleAction('play', props.item.id)
97 }); 101 });
98 - }, 102 +});
99 - methods: { 103 +
100 - goTo () { // 跳转作品详情页 104 +const goTo = () => { // 跳转作品详情页
101 - this.$router.push({ 105 + $router.push({
102 path: '/client/videoDetail', 106 path: '/client/videoDetail',
103 query: { 107 query: {
104 - prod_id: this.item.id, 108 + prod_id: props.item.id,
105 - book_id: this.item.book_id, 109 + book_id: props.item.book_id,
106 - type: this.item.type // 特殊标识,判断入口 为keepAlive使用 110 + type: props.item.type // 特殊标识,判断入口 为keepAlive使用
107 } 111 }
108 }); 112 });
109 - }, 113 +}
110 - setComment() { 114 +
111 - this.$router.push({ 115 +const setComment = () => {
116 + $router.push({
112 path: '/client/videoDetail/comment', 117 path: '/client/videoDetail/comment',
113 query: { 118 query: {
114 - prod_id: this.item.id, 119 + prod_id: props.item.id,
115 - book_id: this.item.book_id 120 + book_id: props.item.book_id
116 } 121 }
117 }); 122 });
118 - }
119 - }
120 } 123 }
124 +
121 </script> 125 </script>
122 126
123 <style lang="less" scoped> 127 <style lang="less" scoped>
......
...@@ -5,6 +5,9 @@ import icon_subscribed from '@images/icon-dingyue01@2x.png' ...@@ -5,6 +5,9 @@ import icon_subscribed from '@images/icon-dingyue01@2x.png'
5 import icon_unsubscribe from '@images/icon-dingyue02@2x.png' 5 import icon_unsubscribe from '@images/icon-dingyue02@2x.png'
6 import no_image from '@images/que-shuju@2x.png' 6 import no_image from '@images/que-shuju@2x.png'
7 import icon_avatar from '@images/que-logo@2x.png' 7 import icon_avatar from '@images/que-logo@2x.png'
8 +import icon_dianzan1 from '@images/icon-dianzan01@2x.png'
9 +import icon_dianzan2 from '@images/icon-dianzan02@2x.png'
10 +import icon_liuyan from '@images/icon-liuyan@2x.png'
8 11
9 export { 12 export {
10 icon_video, 13 icon_video,
...@@ -13,5 +16,8 @@ export { ...@@ -13,5 +16,8 @@ export {
13 icon_subscribed, 16 icon_subscribed,
14 icon_unsubscribe, 17 icon_unsubscribe,
15 no_image, 18 no_image,
16 - icon_avatar 19 + icon_avatar,
20 + icon_dianzan1,
21 + icon_dianzan2,
22 + icon_liuyan,
17 } 23 }
......