vue的input复选框、单选框的数据绑定
代码是一个调查问卷页面,可以直接使用
<template>
<div class="feedbackSurvey">
<main class="main">
<h1 class="title">调查问卷</h1>
<p class="description">请填写调查问卷表</p>
<div class="survey-form">
<h2 class="section-title">个人信息</h2>
<div class="section w40">
<label
>Name:<span class="fontColor">*</span></label
>
<input
type="text"
v-model="userName"
placeholder="Enter your name"
/>
</div>
<div class="section w40">
<label for="gender"
>Gender:<span class="fontColor">*</span></label
>
<input
type="text"
v-model="gender"
placeholder="Enter your gender"
required
/>
</div>
<div class="section w40">
<label for="occupation"
>Occupation:<span class="fontColor">*</span></label
>
<input
type="text"
v-model="occupation"
placeholder="Enter your occupation"
required
/>
</div>
<div class="section w40">
<label for="dropdown">Country of Origin:<span class="fontColor" >*</span></label>
<select name="dropdown" id="dropdown" v-model="country" required>
<option disabled selected value> Select an option </option>
<option v-for="item in CountryList" :key="item" :value="item">{{ item }}</option>
</select>
</div>
<div class="section">
<label for="email"
>Email:<span class="fontColor">*</span></label
>
<input
type="email"
v-model="email"
placeholder="Enter your email"
required
/>
</div>
<div class="section">
<p>Age Group:<span class="fontColor">*</span></p>
<label>
<input
type="radio"
value="below20"
name="age"
v-model="age"
/>
Below 20
</label>
<label>
<input checked type="radio" value="20-30" v-model="age" name="age" />
20-30
</label>
<label>
<input type="radio" value="30-40" v-model="age" name="age" />
30-40
</label>
<label>
<input type="radio" value="40+" v-model="age" name="age" />
40+
</label>
</div>
<h2 class="section-title">Survey Questions</h2>
<div class="section">
<p>
2. 问题2:<span class="fontColor">*</span>
</p>
<label>
<input
type="checkbox"
name="checkbox-question"
value="1"
v-model="improve"
/>
1
</label>
<label>
<input
type="checkbox"
name="checkbox-question"
value="2"
v-model="improve"
/>
2
</label>
<label>
<input
type="checkbox"
name="checkbox-question"
:value="othersImprovel"
class="marTop1"
v-model="improve"
/>
<span> Others:</span>
<!-- <input
class="others-input"
type="text"
/> -->
<textarea
name="comments"
id="text-area"
:value="othersImprovel"
placeholder="Please enter..."
></textarea>
</label>
</div>
<div class="section">
<p>3. 问题3<span class="fontColor">*</span></p>
<label>
<input
type="radio"
value="yes"
v-model="isSubscribe"
name="radio-question"
/>
Yes
</label>
<label>
<input v-model="isSubscribe" type="radio" value="no" name="radio-question" />
No
</label>
</div>
<div class="section" v-show="isSubscribe == 'no'">
<p>If NO, please share why:<span class="fontColor">*</span></p>
<label>
<input
type="checkbox"
value="Not useful"
name="reasonForNotSubscribe"
v-model="reasonForNotSubscribe"
/>
没用
</label>
<label>
<input type="checkbox" v-model="reasonForNotSubscribe" value="Too expensive" name="reasonForNotSubscribe" />
太贵
</label>
<label>
<input
type="checkbox"
name="reasonForNotSubscribe"
:value="othersIsSubscribeCause"
v-model="reasonForNotSubscribe"
class="marTop1"
/>
<span> Others:</span>
<textarea
name="comments"
id="text-area"
v-model="othersIsSubscribeCause"
placeholder="Please enter..."
></textarea>
</label>
</div>
<div class="section">
<p>
其他:
</p>
<textarea
name="comments"
id="text-area"
v-model="designTools"
placeholder="Please enter..."
></textarea>
</div>
<div class="section">
<button class="submit" @click="setSubmit">Submit</button>
</div>
</div>
</main>
</div>
</template>
<script lang="ts">
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Modal,message } from 'ant-design-vue';
import { defineComponent, toRefs,ref, reactive, createVNode } from "vue";
export default defineComponent({
setup() {
const feedbackData:any = reactive({
userName:'',
gender:'',
occupation:'',
country:'',
email:'',
age:'20-30',
improve:[],
isSubscribe:'',
reasonForNotSubscribe:[],
designTools:'',
});
let othersHelpful = ref()
let othersImprovel = ref()
let othersIsSubscribeCause = ref()
let CountryList = [
"Albania",
"Algeria",
"Andorra",
"Angola",
"Antigua and Barbuda",
"Argentina",
"Armenia",
"Australia",
"Austria",
"Azerbaijan",
"Bahamas",
"Bangladesh",
"Barbados",
"Belgium",
"Belize",
"Benin",
"Bhutan",
"Bolivia",
"Bosnia and Herzegovina",
"Botswana",
"Brazil",
"Brunei",
"Bulgaria",
"Burkina Faso",
"Cabo Verde",
"Canada",
"China",
"Chile",
"Colombia",
"Comoros",
"Congo",
"Costa Rica",
"Côte d'Ivoire",
"Croatia",
"Cyprus",
"Czech Republic",
"Denmark",
"Djibouti",
"Dominica",
"Dominican Republic",
"Ecuador",
"El Salvador",
"Estonia",
"Fiji",
"Finland",
"France",
"Gabon",
"Gambia",
"Georgia",
"Germany",
"Ghana",
"Greece",
"Grenada",
"Guatemala",
"Guinea",
"Guinea-Bissau",
"Guyana",
"Haiti",
"Holy See",
"Honduras",
"Hong Kong, China",
"Hungary",
"Iceland",
"India",
"Indonesia",
"Iraq",
"Ireland",
"Israel",
"Italy",
"Jamaica",
"Japan",
"Jordan",
"Kazakhstan",
"Kenya",
"Kiribati",
"Kuwait",
"Kyrgyzstan",
"Latvia",
"Lebanon",
"Lesotho",
"Liberia",
"Liechtenstein",
"Lithuania",
"Luxembourg",
"Madagascar",
"Malawi",
"Malaysia",
"Maldives",
"Mali",
"Malta",
"Marshall Islands",
"Mauritania",
"Mauritius",
"Mexico",
"Micronesia",
"Moldova",
"Monaco",
"Mongolia",
"Montenegro",
"Morocco",
"Mozambique",
"Myanmar",
"Namibia",
"Nauru",
"Nepal",
"Netherlands",
"New Zealand",
"Nicaragua",
"Niger",
"Nigeria",
"North Macedonia",
"Norway",
"Oman",
"Pakistan",
"Palau",
"Palestine",
"Panama",
"Papua New Guinea",
"Paraguay",
"Peru",
"Philippines",
"Poland",
"Portugal",
"Qatar",
"Romania",
"Rwanda",
"Saint Kitts and Nevis",
"Saint Lucia",
"Saint Vincent and the Grenadines",
"Samoa",
"San Marino",
"Sao Tome and Principe",
"Senegal",
"Serbia",
"Seychelles",
"Sierra Leone",
"Singapore",
"Slovakia",
"Slovenia",
"Solomon Islands",
"South Africa",
"South Korea",
"Spain",
"Sri Lanka",
"Suriname",
"Sweden",
"Switzerland",
"Taiwan, China",
"Tanzania",
"Thailand",
"Timor-Leste",
"Togo",
"Tonga",
"Trinidad and Tobago",
"Tunisia",
"Turkey",
"Tuvalu",
"Uganda",
"Ukraine",
"United Arab Emirates",
"United Kingdom",
"United States of America",
"Uruguay",
"Vanuatu",
"Zambia"
]
let setSubmit = () => {
let state = false
console.log(feedbackData);
let skipList = ['designTools','reasonForNotSubscribe']
for (const key in feedbackData) {
if(skipList.indexOf(key) > -1){
continue
}
let keyList = ['improve']
if(keyList.indexOf(key) > -1){
if(feedbackData[key].length == 0){
state = true
break
}
}else if(feedbackData.isSubscribe == 'no' && feedbackData.reasonForNotSubscribe.length){
state = true
break
}else{
if(feedbackData[key] == ''){
state = true
break
}
}
}
if(state){
message.info('Please check that all the * numbers have been filled in')
return
}
let _this = this
Modal.confirm({
title: `Please confirm your email address to ensure it is correct. ${feedbackData.email}`,
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
}
});
};
return {
...toRefs(feedbackData),
othersHelpful,
othersImprovel,
othersIsSubscribeCause,
CountryList,
setSubmit,
};
},
data() {
return {
// moodTemplateId: "", //模板id
};
},
mounted() {},
methods: {},
});
</script>
<style lang="less" scoped>
@import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@400;700&display=swap");
.feedbackSurvey {
font-family: "Quicksand", sans-serif;
text-align: center;
line-height: 1.5;
// background: linear-gradient(180deg, #f3f3e6 0%, #eee4f3 100%);
margin: 1rem;
height: 100%;
overflow-y: auto;
.main{
background: linear-gradient(45deg, #eee4f3, #f3f4e6);
min-height: 100%;
}
.title {
font-size: 6rem;
margin: 0;
font-weight: 900;
}
.description {
font-size: 2.8rem;
font-style: italic;
}
.survey-form {
position: relative;
background: rgba(255, 255, 255, 0.2);
width: 60%;
left: 50%;
transform: translateX(-50%);
text-align: left;
border-radius: 15px;
padding: 3rem;
box-shadow: -1px 1px 5px 0.5px;
font-size: 2.4rem;
transition: width 1s ease;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
@media (max-width: 760px) {
form {
width: 75%;
}
}
h2 {
width: 100%;
font-weight: 900;
}
.section {
display: flex;
flex-direction: column;
margin: 1rem;
width: 100%;
}
.w40 {
width: 40%;
}
.fontColor{
color: rgb(255, 2, 2);
}
p{
font-size: 2.8rem;
}
p,
label {
font-weight: bold;
margin: 0;
margin-left: 5px;
}
input,
#dropdown {
border: none;
border-radius: 5px;
padding: 10px;
outline: 0;
}
input:focus,
#dropdown:focus {
border: 2px solid rgb(173, 173, 173);
}
input,select{
height: 40px;
}
input,
button,
select,
textarea {
cursor: pointer;
font-family: inherit;
font-size: inherit;
}
input[type="radio"],
input[type="checkbox"] {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: middle;
margin: 0;
}
label{
vertical-align: baseline;
cursor: pointer;
.others-input{
background: rgba(255, 255, 255, 0);
border-top: none;
border-right: none;
border-left: none;
border-radius: 0;
border-bottom: 2px solid;
}
.others-input:focus{
border: none;
border-bottom: 2px solid;
}
span{
vertical-align: top;
}
textarea{
width: 80%;
vertical-align: top;
margin-left: 1rem;
}
}
textarea {
min-height: 75%;
max-height: 250px;
width: 100%;
resize: vertical;
border: none;
border-radius: 10px;
padding: 10px;
box-sizing: border-box;
}
.submit {
background: #39215b;
border: none;
border-radius: 10px;
color: white;
font-size: 3rem;
transition: all 0.3s ease-in;
}
.submit:hover {
background: darkgreen;
background: #543087;
}
}
</style>
效果图如下
单选框和复选框都需要有一个相同的name
复选框需要一个value 和v-model value表示值,v-model表示需要双向绑定的内容
单选也是同理