From 7b0c1c43c95e93ae13dc936962b47b5ce67ff103 Mon Sep 17 00:00:00 2001 From: alwayrun <minge23@live.cn> Date: Mon, 20 May 2024 20:42:37 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=20render/compone?= =?UTF-8?q?nts=20=E7=9B=AE=E5=BD=95=E4=B8=8B=E9=83=A8=E5=88=86=E7=BB=84?= =?UTF-8?q?=E4=BB=B6,=20=E4=BD=BF=E7=94=A8=20Vue3=20=E7=BB=84=E5=90=88?= =?UTF-8?q?=E5=BC=8F=20API=20=E5=86=99=E6=B3=95=20(#115)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/render/components/AlertDialog.vue | 48 ++++++------- web/src/render/components/ConfirmDialog.vue | 66 +++++++++--------- web/src/render/components/HeaderSetter.vue | 75 +++++++++++---------- web/src/render/components/LogoIcon.vue | 24 +++---- web/src/render/components/MainRenderer.vue | 39 ++++------- web/src/render/components/MainTitle.vue | 17 ++--- web/src/render/components/SubmitSetter.vue | 59 ++++++++-------- web/src/render/styles/icon.scss | 3 + 8 files changed, 153 insertions(+), 178 deletions(-) diff --git a/web/src/render/components/AlertDialog.vue b/web/src/render/components/AlertDialog.vue index 61e4bf15..7fa04e6e 100644 --- a/web/src/render/components/AlertDialog.vue +++ b/web/src/render/components/AlertDialog.vue @@ -2,33 +2,33 @@ <div class="mask" v-if="visible"> <div class="box"> <div class="title">{{ title }}</div> - <div class="btn" @click="onConfirm">{{ btnText }}</div> + <div class="btn" @click="handleConfirm">{{ btnText }}</div> </div> </div> </template> -<script> -export default { - name: 'AlertDialog', - props: { - visible: { - type: Boolean, - default: false - }, - btnText: { - type: String, - default: '我知道了' - }, - title: { - type: String, - default: '' - } - }, - methods: { - onConfirm() { - this.$emit('confirm') - this.$emit('close') - } - } +<script setup lang="ts"> +interface Props { + visible?: boolean + btnText?: string + title?: string +} + +interface Emit { + (ev: 'confirm'): void + (ev: 'close'): void +} + +const emit = defineEmits<Emit>() + +withDefaults(defineProps<Props>(), { + visible: false, + btnText: '我知道了', + title: '' +}) + +const handleConfirm = () => { + emit('confirm') + emit('close') } </script> <style lang="scss" scoped> diff --git a/web/src/render/components/ConfirmDialog.vue b/web/src/render/components/ConfirmDialog.vue index ca14ceae..82c0e40c 100644 --- a/web/src/render/components/ConfirmDialog.vue +++ b/web/src/render/components/ConfirmDialog.vue @@ -3,44 +3,42 @@ <div class="box"> <div class="title">{{ title }}</div> <div class="btn-box"> - <div class="btn cancel" @click="onCancel">{{ cancelBtnText }}</div> - <div class="btn confirm" @click="onConfirm">{{ confirmBtnText }}</div> + <div class="btn cancel" @click="handleCancel">{{ cancelBtnText }}</div> + <div class="btn confirm" @click="handleConfirm">{{ confirmBtnText }}</div> </div> </div> </div> </template> -<script> -export default { - name: 'ConfirmDialog', - props: { - visible: { - type: Boolean, - default: false - }, - cancelBtnText: { - type: String, - default: '取消' - }, - confirmBtnText: { - type: String, - default: '确定' - }, - title: { - type: String, - default: '' - } - }, - methods: { - onCancel() { - // this.$emit('cancel'); - this.$emit('close') - }, - onConfirm() { - this.$emit('confirm', () => { - this.$emit('close') - }) - } - } +<script setup lang="ts"> +interface Props { + visible?: boolean + cancelBtnText?: string + confirmBtnText?: string + title?: string +} + +interface Emit { + (ev: 'confirm', callback: () => void): void + (ev: 'close'): void +} + +const emit = defineEmits<Emit>() + +withDefaults(defineProps<Props>(), { + visible: false, + cancelBtnText: '取消', + confirmBtnText: '确定', + title: '' +}) + +const handleConfirm = () => { + emit('confirm', () => { + emit('close') + }) +} + +const handleCancel = () => { + emit('close') } </script> <style lang="scss" scoped> diff --git a/web/src/render/components/HeaderSetter.vue b/web/src/render/components/HeaderSetter.vue index b73eb844..7e4d508f 100755 --- a/web/src/render/components/HeaderSetter.vue +++ b/web/src/render/components/HeaderSetter.vue @@ -5,13 +5,13 @@ class="banner-img" :src="bannerConf.bannerConfig.bgImage" :class="{ pointer: bannerConf.bannerConfig.bgImageAllowJump }" - @click="onBannerClick" + @click="handleBannerClick" /> </div> <div class="banner" v-if="bannerConf.bannerConfig && bannerConf.bannerConfig.videoLink"> <div class="video"> <video - id="video" + ref="videoRef" controls style="margin: 0 auto; width: 100%; display: block" preload="auto" @@ -21,49 +21,50 @@ </video> <div class="video-modal" - :style="`background-image:url(${bannerConf.bannerConfig.postImg})`" + :style="{ + backgroundImage: + bannerConf.bannerConfig.postImg && `url(${bannerConf.bannerConfig.postImg})`, + display: displayModel + }" + ></div> + <div + class="iconfont icon-kaishi play-icon" + :style="{ display: displayModel }" + @click="handlePlay()" ></div> - <div class="iconfont icon-kaishi play-icon" @click="play()"></div> </div> </div> - <!-- <div - class="titlePanel" - v-if="bannerConf.titleConfig && bannerConf.titleConfig.mainTitle" - > - <div - class="mainTitle" - v-if="bannerConf.titleConfig.mainTitle" - v-safe-html="bannerConf.titleConfig.mainTitle" - ></div> - </div> --> </div> </template> -<script> +<script setup lang="ts"> +import { computed, ref } from 'vue' +import { useStore } from 'vuex' import { get as _get } from 'lodash-es' + import { formatLink } from '../utils/index.js' -export default { - name: 'HeaderSetter', - computed: { - bannerConf() { - return _get(this.$store, 'state.bannerConf', {}) - } - }, - methods: { - onBannerClick() { - const allow = _get(this.bannerConf, 'bannerConfig.bgImageAllowJump', false) - const jumpLink = _get(this.bannerConf, 'bannerConfig.bgImageJumpLink', '') - if (!allow || !jumpLink) { - return - } - window.open(formatLink(jumpLink)) - }, - play() { - const video = document.getElementById('video') - document.querySelector('.play-icon').style.display = 'none' - document.querySelector('.video-modal').style.display = 'none' - video.play() - } +const store = useStore() + +const bannerConf = computed<any>(() => _get(store, 'state.bannerConf', {})) + +const handleBannerClick = () => { + const allow = _get(bannerConf.value, 'bannerConfig.bgImageAllowJump', false) + const jumpLink = _get(bannerConf.value, 'bannerConfig.bgImageJumpLink', '') + + if (!allow || !jumpLink) { + return + } + + window.open(formatLink(jumpLink)) +} + +const videoRef = ref<HTMLVideoElement | null>(null) +const displayModel = ref('block') + +const handlePlay = () => { + if (bannerConf.value.bannerConfig && bannerConf.value.bannerConfig.videoLink) { + videoRef.value?.play() + displayModel.value = 'none' } } </script> diff --git a/web/src/render/components/LogoIcon.vue b/web/src/render/components/LogoIcon.vue index 39ef1678..d266cda0 100644 --- a/web/src/render/components/LogoIcon.vue +++ b/web/src/render/components/LogoIcon.vue @@ -5,21 +5,15 @@ </div> </div> </template> -<script> -export default { - name: 'LogoIcon', - computed: { - logoImage() { - return this.$store.state?.bottomConf?.logoImage - }, - logoImageWidth() { - return this.$store.state?.bottomConf?.logoImageWidth - }, - isMobile() { - return this.$store.state?.isMobile - } - } -} +<script setup lang="ts"> +import { computed } from 'vue' +import { useStore } from 'vuex' + +const store = useStore() + +const logoImage = computed(() => store.state?.bottomConf?.logoImage) +const logoImageWidth = computed(() => store.state?.bottomConf?.logoImageWidth) +const isMobile = computed(() => store.state?.isMobile) </script> <style lang="scss" scoped> .container { diff --git a/web/src/render/components/MainRenderer.vue b/web/src/render/components/MainRenderer.vue index 38895a07..da70b993 100644 --- a/web/src/render/components/MainRenderer.vue +++ b/web/src/render/components/MainRenderer.vue @@ -6,37 +6,24 @@ :render-data="item" :rules="rules" :formModel="formModel" - @formChange="changeData" + @formChange="handleChangeData" /> </template> </div> </template> +<script setup lang="ts"> +import { computed } from 'vue' +import { useStore } from 'vuex' -<script> -import { mapActions } from 'vuex' import MaterialGroup from './MaterialGroup.vue' -export default { - name: 'MainRenderer', - computed: { - questionData() { - return this.$store.state.questionData - }, - renderData() { - return this.$store.getters.renderData - }, - rules() { - return this.$store.state.rules - }, - formModel() { - return this.$store.getters.formModel - } - }, - mounted() {}, - components: { MaterialGroup }, - methods: { - ...mapActions(['changeData']) - } + +const store = useStore() + +const renderData = computed(() => store.getters?.renderData) +const rules = computed(() => store.state.rules) +const formModel = computed(() => store.getters.formModel) + +const handleChangeData = (data: any) => { + store.dispatch('changeData', data) } </script> - -<style scoped lang="scss"></style> diff --git a/web/src/render/components/MainTitle.vue b/web/src/render/components/MainTitle.vue index 23ee3c13..7fa6099d 100644 --- a/web/src/render/components/MainTitle.vue +++ b/web/src/render/components/MainTitle.vue @@ -9,18 +9,13 @@ </div> </div> </template> -<script> -import { get as _get } from 'lodash-es' -export default { - name: 'MainTitle', - computed: { - bannerConf() { - return _get(this.$store, 'state.bannerConf', {}) - } - } -} -</script> +<script setup lang="ts"> +import { computed } from 'vue' +import { useStore } from 'vuex' +const store = useStore() +const bannerConf = computed(() => store.state?.bannerConf || {}) +</script> <style lang="scss" scoped> @import '@/render/styles/variable.scss'; .question-header { diff --git a/web/src/render/components/SubmitSetter.vue b/web/src/render/components/SubmitSetter.vue index e3ac7806..fc0546ff 100644 --- a/web/src/render/components/SubmitSetter.vue +++ b/web/src/render/components/SubmitSetter.vue @@ -1,45 +1,42 @@ <template> <div class="question-submit_wrapper"> - <button class="question-submit-btn" @click="submit"> + <button class="question-submit-btn" @click="handleSubmit"> {{ submitConf.submitTitle }} </button> </div> </template> +<script setup lang="ts"> +import { computed } from 'vue' +import { useStore } from 'vuex' -<script> -export default { - name: 'SubmitSetter', - props: { - validate: Function, - renderData: Array - }, - data() { - return {} - }, - computed: { - submitConf() { - return this.$store.state?.submitConf || {} - }, - skinConf() { - return this.$store.state?.skinConf || {} - } - }, - methods: { - submit(e) { - const validate = this.validate - if (e) { - e.preventDefault() - validate((valid) => { - if (valid) { - this.$emit('submit') - } - }) +interface Props { + validate: (fn: (valid: boolean) => void) => void + renderData?: Array<any> +} + +interface Emit { + (ev: 'submit'): void +} + +const props = defineProps<Props>() +const emit = defineEmits<Emit>() + +const store = useStore() + +const submitConf = computed(() => store.state?.submitConf || {}) + +const handleSubmit = (e: Event) => { + const validate = props.validate + if (e) { + e.preventDefault() + validate((valid) => { + if (valid) { + emit('submit') } - } + }) } } </script> - <style lang="scss" scoped> @import '@/render/styles/variable.scss'; .question-submit_wrapper { diff --git a/web/src/render/styles/icon.scss b/web/src/render/styles/icon.scss index 6a01c53e..3b2f4edc 100644 --- a/web/src/render/styles/icon.scss +++ b/web/src/render/styles/icon.scss @@ -16,4 +16,7 @@ .icon-kaishi:before { content: '\e6ad'; + border-radius: 50%; + background-color: white; + cursor: pointer; }