【Vue3.0实战逐步深入系列】扩展投票功能基于elementui进行组件封装实现一个简单的问卷调查功能

【千字长文,熬夜更新,原创不易,多多支持,感谢大家】

前言

小伙伴们大家好。在前面一偏文章中我们把投票功能进行了简单的改造:引入了axios第三方库并进行了二次封装用于模拟请求服务器数据。同时添加了一个json文件来替代服务器从而达到前后端交互的目的,最终实现了一个可动态配置的,不限个数的投票功能。然而不管有多少个投票功能都只能统计支持和不支持的个数,如果来了新的需求:想要实现点选或者输入功能,那么简单的投票就无法满足。接下来这篇文章就基于前面的投票功能继续扩展改造,实现一个可以点击,可以点选,可以输入的问卷调查功能。

分析

在我们常见的问卷调查中一般都会包含:单选部分,多选部分,用户输入部分;一般的调查问卷设计会尽量的让用户去点选而不是输入,所以在设计问卷的时候回尽量多的设计一些单选或多选部分,而放在最后设计一到两个用户输入的,最后放一个提交按钮。为了让代码可用性高一点,我们对每种类型进行一个独立的封装,比如投票封装成Vote组件,单选封装为myradio组件,多选封装为mycheck组件,输入封装为myinput组件,评分封装为mystar组件,下面我们就来对以上组件进行一一封装。另外Vote组件在前面分享投票功能的时候已经进行了封装,这里就不再说明。

单选组件myradio

本次对单选组件的封装我们需要基于elementui的el-radio。我们知道单选按钮一般都应该放在同一个组中,这样才能够实现单选,否则不进行分组即使是单选按钮也可以进行多选,因此还得需要借助el-radio-group

  • 首先我们需要定义两个属性:
    • title:String类型,必须,用于展示问卷的标题
    • itemData:Array类型,必须,用于加载单选按钮选项
  • 导入elementui中的ElCard, ElRadioGroup, ElRadio
  • 导入vue中ref方法用于定义响应式属性
  • 在setup函数中定义一个响应式属性selectedValue,用于接收已选中的值
  • 在template模板中使用分别添加el-card,el-radio-group和el-radio组件
  • 在el-card组件的标题中显示我们的问卷标题:title
  • 在el-radio-group中设置v-model属性值为selectedValue,用于接收已选的值
  • 最后添加一个el-radio并使用v-for指令循环itemData属性加载选项
<template>
  <el-card class="box-card">
    <template #header>
      <h1>{
   
   { title }}</h1>
    </template>
    <div>
      <el-radio-group v-model="selectedValue">
        <el-radio v-for="item in itemData" :key="item" :label="item">{
   
   {
          item
        }}</el-radio>
      </el-radio-group>
    </div>
  </el-card>
</template>
import {
    
     ElCard, ElRadioGroup, ElRadio } from "element-plus";
import {
    
     ref } from "vue";
export default {
    
    
  components: {
    
     ElCard, ElRadioGroup, ElRadio },
  props: {
    
    
    title: {
    
    
      type: String,
      required: true,
    },
    itemData: {
    
    
      type: Array,
      required: true,
    },
  },
  setup() {
    
    
    let selectedValue = ref(0);

    return {
    
     selectedValue };
  },
 };

多选组件mycheck

多选组件跟单选组件非常类似,只不过是用到的elementui组件不同。多选组件我们需要借助elementui组件库中的el-checlbox-group和el-checkbox,步骤与单选按钮相同:

  • 首先我们需要定义两个属性:
    • title:String类型,必须,用于展示问卷的标题
    • itemData:Array类型,必须,用于加载多选按钮选项
  • 导入elementui中的ElCard, ElCheckboxGroup, ElCheckbox
  • 导入vue中ref方法用于定义响应式属性
  • 在setup函数中定义一个响应式属性selectedValue,用于接收已选中的值
  • 在template模板中使用分别添加el-card,el-checkbox-group和el-checkbox组件
  • 在el-card组件的标题中显示我们的问卷标题:title
  • 在el-checkbox-group中设置v-model属性值为selectedValue,用于接收已选的值
  • 最后添加一个el-checkbox并使用v-for指令循环itemData属性加载选项
<template>
  <el-card class="box-card">
    <template #header>
      <h1>{
   
   { title }}</h1>
    </template>
    <div>
      <el-checkbox-group v-model="selectedValue">
        <el-checkbox v-for="item in itemData" :key="item" :label="item">{
   
   {
          item
        }}</el-checkbox>
      </el-checkbox-group>
    </div>
  </el-card>
</template>
import {
    
     ElCard, ElCheckboxGroup, ElCheckbox } from "element-plus";
import {
    
     ref } from "vue";
export default {
    
    
  components: {
    
     ElCard, ElCheckboxGroup, ElCheckbox },
  props: {
    
    
    title: {
    
    
      type: String,
      required: true,
    },
    itemData: {
    
    
      type: Array,
      required: true,
    },
  },
  setup() {
    
    
    let selectedValue = ref([]);

    return {
    
     selectedValue };
  },
 };

输入组件myinput

这个输入组件要比前两个都简单得多,我们只需要一个问卷标题和一个用户输入的文本框即可,因此本组件主要基于elementui库的el-input实现

  • 首先定义一个title属性,String类型,必须,用于展示问卷的标题
  • 导入elementui中的ElCard和ElInput
  • 导入vue中ref方法用于定义响应式属性
  • 在setup函数中定义一个响应式属性selectedValue,用于接收已输入的值
  • 在template模板中使用分别添加el-card和el-input组件
  • 在el-input中设置:
    • v-model属性,值为selectedValue,用于接收已的输入值
    • type属性,值为textarea,用户可多行输入
    • rows属性,值为4,设置输入框高度为4行
    • placeholder属性,设置提示信息
    • clearable属性,设置可清空
  • 最后在el-card组件的标题中显示我们的问卷标题:title
<template>
  <el-card class="box-card">
    <template #header>
      <h1>{
   
   { title }}</h1>
    </template>
    <div>
      <el-input
        v-model="selectedValue"
        type="textarea"
        :rows="4"
        placeholder="Please input"
        clearable
      />
    </div>
  </el-card>
</template>
import {
    
     ElCard, ElInput } from "element-plus";
import {
    
     ref } from "vue";
export default {
    
    
  components: {
    
     ElCard, ElInput },
  props: {
    
    
    title: {
    
    
      type: String,
      required: true,
    },
  },
  setup() {
    
    
    let selectedValue = ref("");

    return {
    
     selectedValue };
  },
 };

评分组件mystar

为了展示更多的功能,我们最后再加一个评分组件mystar,这个组件跟前两个类似仍然需要定义两个属性:

  • 首先我们需要定义两个属性:
    • title:String类型,必须,用于展示问卷的标题
    • itemData:Array类型,必须,用于展示每个等级的分数或描述(可根据需要自定义)
  • 导入elementui中的ElCard, ElRate
  • 导入vue中ref方法用于定义响应式属性
  • 在setup函数中定义一个响应式属性selectedValue,用于接收已选中的值
  • 在template模板中使用分别添加el-card和el-rate组件
    • 在el-rate组件中需要设置如下属性:
    • v-model属性,值为selectedValue
    • texts属性,值为上面定义的属性itemData
    • show-text属性,值为true
  • 在el-card组件的标题中显示我们的问卷标题:title
<template>
  <el-card class="box-card">
    <template #header>
      <h1>{
   
   { title }}</h1>
    </template>
    <div>
      <el-rate v-model="selectedValue" :texts="itemData" show-text> </el-rate>
    </div>
  </el-card>
</template>
import {
    
     ElCard, ElRate } from "element-plus";
import {
    
     ref } from "vue";
export default {
    
    
  components: {
    
     ElCard, ElRate },
  props: {
    
    
    title: {
    
    
      type: String,
      required: true,
    },
    itemData: {
    
    
      type: Array,
      required: true,
    },
  },
  setup() {
    
    
    let selectedValue = ref("");

    return {
    
     selectedValue };
  },
};

在json文件中添加数据源

同样为了实现各类组件的可配置性,我们仍然需要在json文件中设置各个组件的数据源,用于模拟服务器请求实现前后端交互

{
    
    
    "data":[
        {
    
    "id":1,"title":"Vue3.0好学吗?"}
    ],
    "radios":[
        {
    
    "id":1,"title":"您对公司的福利是否满意?","items":["非常满意","满意","基本满意","不满意"]},{
    
    "id":2,"title":"您对当前的收入是否满意?","items":["非常满意","满意","基本满意","不满意"]}
    ],
    "checks":[
        {
    
    "id":1,"title":"您还希望公司增加哪些福利?","items":["涨工资","涨饭补","发女朋友","以上都要"]}
    ],
    "inputs":[
        {
    
    "id":1,"title":"您有什么想对公司说的?"},
        {
    
    "id":2,"title":"随便说点啥吧"}
    ],
    "stars":[
        {
    
    "id":1,"title":"请给本次分享打个分吧!","items":["糟糕","失望","一般","很好","非常好"]}
    ]
}

在App.vue中引入封装好的组件

万事俱备只欠东风,组件都封装好了 接下来就是导入并注册它们然后使用了,这里就不多说了,直接上代码吧

<template>
  <Vote v-for="vote in data" :key="vote.id" :title="vote.title" />
  <myradio
    v-for="radio in radios"
    :key="radio.id"
    :title="radio.title"
    :itemData="radio.items"
  />
  <mycheck
    v-for="check in checks"
    :key="check.id"
    :title="check.title"
    :itemData="check.items"
  />
  <myinput v-for="inp in inputs" :key="inp.id" :title="inp.title" />
  <mystar
    v-for="star in stars"
    :key="star.id"
    :title="star.title"
    :itemData="star.items"
  />
  <el-button type="primary">提交</el-button>
</template>
import Vote from "./Vote.vue";
import myradio from "./myradio.vue";
import mycheck from "./mycheck.vue";
import myinput from "./myinput.vue";
import mystar from "./mystar.vue";
import http from "./api/http";
import {
    
     ref } from "vue";
import {
    
     ElButton } from "element-plus";

export default {
    
    
  name: "App",
  components: {
    
    
    Vote,
    myradio,
    mycheck,
    myinput,
    mystar,
    ElButton,
  },
  setup() {
    
    
    let data = ref([]);
    let radios = ref([]);
    let checks = ref([]);
    let inputs = ref([]);
    let stars = ref([]);
    http.get("/caoxuhaijing.json").then((res) => {
    
    
      console.log(res);
      data.value = res.data;
      radios.value = res.radios;
      checks.value = res.checks;
      inputs.value = res.inputs;
      stars.value = res.stars;
    });

    return {
    
    
      data,
      radios,
      checks,
      inputs,
      stars,
    };
  },
};

最终效果图如下
在这里插入图片描述在这里插入图片描述

总结

本文我们基于前面的投票功能做了一下扩展,实现了一个简单的问卷调查功能。在实现的过程中对各类型的调查组件进行了简单的封装以实现代码的可服用,同时继续沿用前面文章中的axios请求和json文件来模拟与服务器交互。最终实现了一个简单的问卷调查小功能。
好了小伙伴们,本次分享就到这里了,喜欢的小伙伴欢迎点赞评论加关注哦!

Guess you like

Origin blog.csdn.net/lixiaosenlin/article/details/121461816