refactor: 重构 render/components 目录下部分组件, 使用 Vue3 组合式 API 写法 (#115)

This commit is contained in:
alwayrun 2024-05-20 20:42:37 +08:00 committed by sudoooooo
parent eed15cd23c
commit 5e50a3a733
8 changed files with 153 additions and 178 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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" @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"
class="iconfont icon-kaishi play-icon"
:style="{ display: displayModel }"
@click="handlePlay()"
></div>
</div> -->
</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', '')
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))
},
play() {
const video = document.getElementById('video')
document.querySelector('.play-icon').style.display = 'none'
document.querySelector('.video-modal').style.display = 'none'
video.play()
}
}
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>

View File

@ -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 {

View File

@ -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>

View File

@ -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 {

View File

@ -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
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) {
this.$emit('submit')
emit('submit')
}
})
}
}
}
}
</script>
<style lang="scss" scoped>
@import '@/render/styles/variable.scss';
.question-submit_wrapper {

View File

@ -16,4 +16,7 @@
.icon-kaishi:before {
content: '\e6ad';
border-radius: 50%;
background-color: white;
cursor: pointer;
}