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

View File

@ -35,7 +35,9 @@
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import { ref, reactive, computed, toRefs } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss' import 'element-plus/theme-chalk/src/message.scss'
@ -43,70 +45,67 @@ import { createSurvey } from '@/management/api/survey'
import { SURVEY_TYPE_LIST } from '../types' import { SURVEY_TYPE_LIST } from '../types'
export default { interface Props {
name: 'CreateForm', selectType?: string
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 || '创建失败')
}
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> </script>

View File

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

View File

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