refactor: Vue3 组合式 API 写法重构 (#165)

This commit is contained in:
hiStephen 2024-05-24 20:28:43 +08:00 committed by GitHub
parent 0095e3b7e0
commit 2b683b0923
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 109 additions and 129 deletions

View File

@ -5,26 +5,15 @@
</div>
</template>
<script>
<script setup lang="ts">
import { ref } from 'vue'
import TypeList from './components/TypeList.vue'
import CreateForm from './components/CreateForm.vue'
export default {
name: 'CreatePage',
components: {
TypeList,
CreateForm
},
data() {
return {
selectType: 'normal'
}
},
methods: {
onSelectTypeChange(selectType) {
this.selectType = selectType
}
}
const selectType = ref<string>('normal')
const onSelectTypeChange = (type: string) => {
selectType.value = type
}
</script>

View File

@ -35,7 +35,9 @@
</div>
</template>
<script>
<script setup lang="ts">
import { ref, reactive, computed, toRefs } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss'
@ -43,70 +45,67 @@ import { createSurvey } from '@/management/api/survey'
import { SURVEY_TYPE_LIST } from '../types'
export default {
name: 'CreateForm',
props: {
selectType: {
type: String,
default: 'normal'
}
},
data() {
return {
rules: {
title: [{ required: true, message: '请输入问卷标题', trigger: 'blur' }]
},
canSubmit: true,
form: {
title: '问卷调研',
remark: '问卷调研'
}
}
},
computed: {
SURVEY_TYPE_LIST() {
return SURVEY_TYPE_LIST
},
title() {
return this.SURVEY_TYPE_LIST.find((item) => item.type === this.selectType)?.title
}
},
methods: {
checkForm(fn) {
this.$refs.ruleForm.validate((valid) => {
valid && typeof fn === 'function' && fn()
})
},
submit() {
if (!this.canSubmit) {
return
}
this.checkForm(async () => {
const { selectType } = this
if (!this.canSubmit) {
return
}
this.canSubmit = false
const res = await createSurvey({
surveyType: selectType,
...this.form
})
if (res.code === 200 && res?.data?.id) {
const id = res.data.id
this.$router.push({
name: 'QuestionEditIndex',
params: {
id
}
})
} else {
ElMessage.error(res.errmsg || '创建失败')
}
interface Props {
selectType?: string
}
this.canSubmit = true
})
}
const props = withDefaults(defineProps<Props>(), {
selectType: 'normal'
})
const ruleForm = ref<any>(null)
const state = reactive({
rules: {
title: [{ required: true, message: '请输入问卷标题', trigger: 'blur' }]
},
canSubmit: true,
form: {
title: '问卷调研',
remark: '问卷调研'
}
})
const { rules, canSubmit, form } = toRefs(state)
const title = computed(() => {
return SURVEY_TYPE_LIST.find((item) => item.type === props.selectType)?.title
})
const checkForm = (fn: Function) => {
ruleForm.value?.validate?.((valid: boolean) => {
valid && typeof fn === 'function' && fn()
})
}
const router = useRouter()
const submit = () => {
if (!state.canSubmit) {
return
}
checkForm(async () => {
const { selectType } = props
if (!state.canSubmit) {
return
}
state.canSubmit = false
const res:any = await createSurvey({
surveyType: selectType,
...state.form
})
if (res?.code === 200 && res?.data?.id) {
const id = res.data.id
router.push({
name: 'QuestionEditIndex',
params: {
id
}
})
} else {
ElMessage.error(res?.errmsg || '创建失败')
}
state.canSubmit = true
})
}
</script>

View File

@ -2,37 +2,36 @@
<div :class="['nav-header', `${boxShadow ? 'box-shadow' : null}`]">
<div class="left">
<div class="logo">
<img class="logoImg" :src="img" alt @click="toHomePage" />
<img class="logoImg" :src="img" @click="toHomePage" />
</div>
<div class="return no-logo-return icon-fanhui" @click="onBack">返回</div>
</div>
</div>
</template>
<script>
export default {
props: {
boxShadow: {
type: Boolean,
default: true
}
},
name: 'NavHeader',
data() {
return {
img: '/imgs/s-logo.webp'
}
},
methods: {
toHomePage() {
this.$router.replace({
name: 'survey'
})
},
onBack() {
this.$router.go(-1)
}
}
<script setup lang="ts">
import { useRouter } from 'vue-router'
interface Props {
boxShadow?: boolean
}
withDefaults(defineProps<Props>(), {
boxShadow: true
})
const img = '/imgs/s-logo.webp'
const router = useRouter()
const onBack = () => {
router.go(-1)
}
const toHomePage = () => {
router.push({
name: 'Home'
})
}
</script>

View File

@ -8,7 +8,7 @@
v-for="item in renderData"
class="list-item"
:key="item.type"
@click="handleSelectType('selectType', item)"
@click="handleSelectType(item.type)"
>
<div class="selected-border" v-if="selectType === item.type" />
<img class="img" :src="item.img" alt="类别图片" />
@ -24,34 +24,27 @@
</div>
</template>
<script>
<script setup lang="ts">
import NavHeader from './NavHeader.vue'
import { SURVEY_TYPE_LIST } from '../types'
import { computed } from 'vue'
export default {
name: 'LeftSide',
components: {
NavHeader
},
props: {
selectType: {
type: String,
default: ''
}
},
computed: {
renderData() {
return SURVEY_TYPE_LIST
}
},
methods: {
handleSelectType(key, value) {
const { type } = value
this.$emit('selectTypeChange', type)
}
}
interface Props {
selectType?: string
}
withDefaults(defineProps<Props>(), {
selectType: ''
})
const emit = defineEmits(['selectTypeChange'])
const handleSelectType = (selectType: string) => {
emit('selectTypeChange', selectType)
}
const renderData = computed(() => SURVEY_TYPE_LIST)
</script>
<style lang="scss" scoped>