【vue】展示组件设计
wenking 9/14/2024 vue
对于我们后端开发的同学,总会接触到一些管理系统前端开发任务,当开发表单页面时,通常会将业务和表单控制相关的界面逻辑混合在一起,导致维护困难。
# 展示组件
顾明思议,展示组件只是用来展示数据的,组件内不会涉及一些业务操作,只涉及业务流程控制,并且在双向绑定时业务确保数据流是单向流通的。
# 展示组件 TestComponent
<script setup>
import {watch} from "vue";
const props = defineProps({
domain: {
type: Object,
default: () => ({
username: '',
gender: 1,
tags: [],
other: {
school: [],
work: {
exp1: '',
exp2: '',
}
},
})
}
})
// 深度监控数据变化,提交修改事件
watch(() => props.domain, (n, o) => {
console.log('传递参数改变了')
emits('change', n)
}, {deep: true})
const emits = defineEmits(['submit', 'change'])
// 提交 提交事件
const onClick = (e) => {
e.preventDefault();
emits('submit', props.domain)
}
</script>
<template>
<div class="test-component">
<form>
<div class="form-item">
<label for="username">用户名</label>
<input type="text" id="username" name="username" v-model="domain.username" class="form-item-text"/>
</div>
<div class="form-item">
<label>性别</label>
<label for="male">男</label>
<input id="male" type="radio" name="gender" value="1" v-model="domain.gender" class="form-item-radio"/>
<label for="female">女</label>
<input id="female" type="radio" name="gender" value="2" v-model="domain.gender" class="king-input-radio"/>
</div>
<div class="form-item">
<label>性格标签</label>
<label for="game">游戏</label>
<input id="game" type="checkbox" name="tags" value="游戏" v-model="domain.tags" class="king-input-radio"/>
<label for="sport">运动</label>
<input id="sport" type="checkbox" name="tags" value="运动" v-model="domain.tags" class="king-input-radio"/>
<label for="read">读书</label>
<input id="read" type="checkbox" name="tags" value="读书" v-model="domain.tags" class="king-input-radio"/>
</div>
<div class="form-item">
<label>学校经历</label>
<label for="MIT">MIT</label>
<input id="MIT" type="checkbox" name="school" value="MIT" v-model="domain.other.school"
class="king-input-radio"/>
<label for="TSU">TSU</label>
<input id="TSU" type="checkbox" name="school" value="TSU" v-model="domain.other.school"
class="king-input-radio"/>
</div>
<div class="form-item">
<label>工作经历1</label>
<input id="exp1" type="text" name="exp1" v-model="domain.other.work.exp1"
class="king-input-text"/>
</div>
<div class="form-item">
<label>工作经历2</label>
<input id="exp2" type="text" name="exp2" v-model="domain.other.work.exp2"
class="king-input-text"/>
</div>
<button @click="onClick">提交</button>
</form>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# 业务组件(父组件) Test
<script setup>
import {ref} from "vue";
import TestComponent from "@/views/TestComponent.vue";
const profileDomain = ref({
username: '阿迪王',
gender: 1,
tags: ['体育', '游戏'],
other: {
school: ['MIT'],
work: {
exp1: '销售',
exp2: '技术',
}
},
})
const processSubmit = (domain) => {
console.log("提交结果:", domain)
}
const processChange = (domain) => {
profileDomain.value = domain
}
</script>
<template>
<div class="test">
<TestComponent @submit="processSubmit" @change="processChange" :domain="profileDomain"/>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30