zoukankan      html  css  js  c++  java
  • 基于vant实现一个问卷调查

    实现背景 

    最近学习《vue实战》,第二篇进阶篇有一个练习

    刚好最近在研究vue移动端框架vant

    两者结合,实现这么个小项目

    实现代码

    新建 vue单文件 L0529L.vue

    <template>
      <div class="dom">
        <div class="tmnr">{{showtm+1}}. {{timu[showtm]['tmcontent']}}</div>
        <component0529
          :info="ziInfo"
          :showtm="showtm"
          @chooseRadio="changeAnswer"
          @chooseCheckbox="changeAnswer"
          @chooseInput="changeAnswer"
        ></component0529>
        <div class="buttondom">
          <van-button type="primary" v-show="showtm>0" @click="shangtm" :disabled="showtm===0">上一题</van-button>
          <van-button
            type="primary"
            v-show="showtm<timu.length-1"
            @click="nexttm"
            :disabled="nextdisable"
          >下一题</van-button>
          <van-button type="warning" @click="chongzhi">重置</van-button>
        </div>
      </div>
    </template>
    
    <script>
    import component0529 from "./views/component0529";
    
    export default {
      name: "",
      data() {
        return {
          showtm: 0,
          timu: [
            {
              id: 1,
              type: "radio",
              tmcontent: "题目内容1-单选",
              xx: [
                { id: "A", nr: "选项A-单选" },
                { id: "B", nr: "选项B-单选" },
                { id: "C", nr: "选项C-单选" }
              ],
              cannext: false,
              answer: ""
            },
            {
              id: 2,
              type: "checkbox",
              tmcontent: "题目内容2-复选",
              xx: [
                { id: "A", nr: "选项A", ischeck: false },
                { id: "B", nr: "选项B", ischeck: false },
                { id: "C", nr: "选项C", ischeck: false },
                { id: "D", nr: "选项D", ischeck: false }
              ],
              cannext: false,
              answer: []
            },
            {
              id: 3,
              type: "input",
              tmcontent: "题目内容3-问答",
              cannext: false,
              answer: ""
            }
          ]
        };
      },
      computed: {
        ziInfo() {
          return this.timu[this.showtm];
        },
        nextdisable() {
          var a = false;
          if (this.showtm == this.timu.length - 1) a = true;
          var t = this.timu[this.showtm]["type"];
          switch (t) {
            case "radio":
              if (this.timu[this.showtm]["answer"] == "") a = true;
              break;
            case "checkbox":
              if (
                this.timu[this.showtm]["answer"].length != 2 &&
                this.timu[this.showtm]["answer"].length != 3
              )
                a = true;
              break;
            case "input":
              var c = this.timu[this.showtm]["answer"];
              if (c.length < 100) a = true;
              break;
          }
          return a;
        }
      },
      components: {
        component0529
      },
      methods: {
        nexttm() {
          this.showtm++;
        },
        shangtm() {
          this.showtm--;
        },
        chongzhi() {
          if (this.timu[this.showtm]["type"] == "checkbox") {
            this.timu[this.showtm]["answer"].length = 0;
            for (var i = 0; i < this.timu[this.showtm]["xx"].length; i++) {
              this.timu[this.showtm]["xx"][i]["ischeck"] = false;
            }
          } else {
            this.timu[this.showtm]["answer"] = "";
          }
        },
        changeAnswer(ans) {
          this.timu[this.showtm]["answer"] = ans;
        }
      }
    };
    </script>
    
    <style scoped>
    .dom{
      padding: 14px;
    }
    .tmnr{
      margin: 10px 0px;
      text-align: left;
    }
    .buttondom {
      position: absolute;
      bottom: 10px;
      text-align: center;
       100%;
    }
    </style>
    

      引入组件 component0529.vue 代码:

    <template>
      <ul>
        <li v-if="info.type==='checkbox'">
          <van-checkbox
            v-for="infoa in childInfo.xx"
            v-model="infoa.ischeck"
            @change="changeCheckbox"
          >{{infoa.nr}}</van-checkbox>
        </li>
        <li v-else-if="info.type==='radio'">
          <van-radio-group v-model="childInfo.answer" @change="changeRadio">
            <van-radio v-for="infoa in childInfo.xx" :name="infoa.id">{{infoa.nr}}</van-radio>
          </van-radio-group>
        </li>
        <li v-else-if="info.type==='input'">
          <van-cell-group>
            <van-field
              v-model="childInfo.answer"
              type="textarea"
              placeholder="请输入不少于100字"
              rows='1'
              autosize
              border="true"
            />
          </van-cell-group>
        </li>
      </ul>
    </template>
    
    <script>
    export default {
      props: ["info", "showtm"],
      data() {
        return {};
      },
      computed: {
        childInfo() {
          var an = this.info["answer"],
            type = this.info["type"];
    
          if (type == "checkbox") {
            for (var i = 0; i < this.info.xx.length; i++) {
              var x = this.info.xx[i];
              if (an.join(",").indexOf(x.id) > -1) x.ischeck = true;
            }
          }
    
          return this.info;
        }
      },
      methods: {
        changeRadio() {
          var a = this.childInfo.answer;
          this.$emit("chooseRadio", a);
        },
        changeCheckbox() {
          var a = [];
          for (var i = 0; i < this.childInfo.xx.length; i++) {
            if (this.childInfo.xx[i]["ischeck"]) a.push(this.childInfo.xx[i]["id"]);
          }
    
          this.$emit("chooseCheckbox", a);
        },
        changeInput() {
          this.$emit("chooseInput", this.childInfo.answer);
        }
      },
      components: {}
    };
    </script>
    
    <style scoped>
    ul li .van-radio,
    .van-checkbox {
      margin: 16px 0px;
    }
    </style>
    

      

    实现页面展示

     

     解释逻辑

     1.在L0529L.vue 定义好相关问卷题目,设计好题目类型,内容,选项,选择或者输入的答案等

    2.定义一个当前题目id==showtm,用这个参数决定当前显示的是哪道题。

    3、将题目传递给子组件component0529.vue,在这里面处理显示选项信息或者输入框

    4、子组件信息操作选择完成或者输入了相关信息,修改对应父组件中问题的答案

    5、刚接触vue,逻辑方面有些冗余啰嗦,以后有更好的实现想法再进行修改

  • 相关阅读:
    angularjs 过滤器
    angularjs 工具方法
    angularjs 模块化
    angularjs ng-app
    angularjs作用域和函数调用
    Android sdk版本以及兼容性问题
    跟谁鼠标移动
    事件捕获,事件冒泡,事件取消
    netsh 转发 5000 端口到 80端口的命令和删除方法
    [微软官网]windows server 内存限制
  • 原文地址:https://www.cnblogs.com/pangchunlei/p/10949416.html
Copyright © 2011-2022 走看看