zoukankan      html  css  js  c++  java
  • vue-播种量小工具总结

    业务介绍

    公司开会说需要一个计算播种量的小工具,其实各种参数关系比较简单,估计正常的农民很少会用工具来计算,因为早就熟练了.目前拿到的需求中,参数有以下几个(直接贴自定义的变量了):

    • density: 密度,
    • KWEI: 百粒重(g),
    • preHectareWeight: 公顷用量(Kg),
    • ridgingSpacing: 垄距cm,
    • ridgingSpacingNum: 垄距米间粒数,
    • spacing: 株距cm
    • toFixedNum: 小数点保留位数

    其中toFixedNum:(小数点保留位数)是自己加的,用来测试精度.几个参数之间的计算关系已知的有:

    • 公顷用量 = 密度*百粒重/10
    • 垄距米间粒数 = (垄距/100)*密度
    • 株距(cm) = 100/((垄距/100)*密度)
      感觉垄距和密度应该是有换算关系的,但是没有给我.所以暂时无法联动了

    项目搭建

    为了省去UI,直接用vue的element-ui框架,计算部分使用了math.js库.初始化项目时候加上了vuex等,原因是通过之前保存的模版,省去了自定义的麻烦.

    实现部分

    路由router.js

    router中使用hash模式,直接做了个跳转.如下:

    {
        path: "/kftools",
        name: "kftools",
        component: { render: h => h("router-view") },
        children: [
          {
            path: "/kftools/cornsow",
            name: "",
            component: () =>
              import(/* webpackChunkName: "kftools" */ "../views/CornSowTools.vue")
          }
        ]
      }
    

    math.js配置

    在使用math.js库的时候直接丢进了全局,main.js的内容如下:

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router";
    import store from "./store";
    
    import "element-ui/lib/theme-chalk/index.css";
    
    Vue.config.productionTip = false;
    
    import * as math from "mathjs";
    Vue.prototype.$math = math;
    
    import {
      Form,
      FormItem,
      Input,
      Button,
      Row,
      Col,
      Select,
      Option
    } from "element-ui";
    
    Vue.use(Form);
    Vue.use(Input);
    Vue.use(Button);
    Vue.use(FormItem);
    Vue.use(Row);
    Vue.use(Col);
    Vue.use(Select);
    Vue.use(Option);
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount("#app");
    

    页面组件

    组件起名叫CornSowTools.vue,代码如下:

    <template>
      <div>
        <el-col :span="7">
          <el-row>
            <el-form
              :model="ruleForm"
              status-icon
              :rules="rules"
              ref="ruleForm"
              label-width="100px"
              class="demo-ruleForm"
            >
              <el-form-item label="小数点" prop="toFixedNum" style="150">
                <el-select v-model="ruleForm.toFixedNum" placeholder="请选择">
                  <el-option
                    v-for="item in options"
                    :key="item"
                    :label="item"
                    :value="item"
                  >
                  </el-option>
                </el-select>
                默认2位
              </el-form-item>
              <el-form-item label="密度" prop="density">
                <el-input v-model="ruleForm.density"></el-input>
              </el-form-item>
              <el-form-item label="百粒重(g)" prop="KWEI">
                <el-input v-model="ruleForm.KWEI"></el-input>
              </el-form-item>
              <el-form-item label="公顷用量(Kg)" prop="preHectareWeight">
                <el-input
                  :disabled="true"
                  v-model="ruleForm.preHectareWeight"
                  placeholder="密度*百粒重/10"
                ></el-input>
              </el-form-item>
              <el-form-item label="垄距(cm)" prop="ridgingSpacing">
                <el-input
                  v-model="ruleForm.ridgingSpacing"
                  placeholder="65"
                ></el-input
                >{{ "垄距和密度的换算关系不知道" }}
              </el-form-item>
              <el-form-item label="垄距米间粒数" prop="ridgingSpacingNum">
                <el-input
                  :disabled="true"
                  v-model="ruleForm.ridgingSpacingNum"
                  placeholder="(垄距/100)*密度"
                ></el-input>
              </el-form-item>
              <el-form-item label="株距(cm)" prop="spacing">
                <el-input
                  :disabled="true"
                  v-model="ruleForm.spacing"
                  placeholder="100/((垄距/100)*密度)"
                ></el-input>
              </el-form-item>
    
              <el-form-item>
                <el-button type="primary" @click="submitForm('ruleForm')"
                  >提交</el-button
                >
                <el-button @click="resetForm('ruleForm')">重置</el-button>
              </el-form-item>
            </el-form>
          </el-row>
        </el-col>
      </div>
    </template>
    
    <script>
    import { create, all } from "mathjs/number";
    
    export default {
      data() {
        const validateNull = (rule, value, callback) => {
          if (value === "") {
            callback(new Error(rule.messageNull));
          } else {
            callback();
          }
        };
        const validateNumber = (rule, value, callback) => {
          const reg = /^[0-9]+.?[0-9]*$/;
          if (!reg.test(value)) {
            callback(new Error(rule.message));
          } else {
            callback();
          }
        };
    
        return {
          /**
           *  
           * density: 密度,
            KWEI: 百粒重(g),
            preHectareWeight: 公顷用量(Kg),
            ridgingSpacing: 垄距cm,
            ridgingSpacingNum: 垄距米间粒数,
            spacing: 株距cm
            toFixedNum: 小数点保留位数
           */
          ruleForm: {
            density: "",
            KWEI: "",
            preHectareWeight: "",
            ridgingSpacing: 65,
            ridgingSpacingNum: "",
            spacing: null,
            toFixedNum: ""
          },
          rules: {
            density: [
              {
                required: true,
                validator: validateNull,
                trigger: "blur",
                messageNull: "密度不能为空,请输入密度"
              },
              {
                type: "number",
                validator: validateNumber,
                message: "密度必须为正数值"
              }
            ],
            KWEI: [
              {
                required: true,
                validator: validateNull,
                trigger: "blur",
                messageNull: "百粒重不能为空,请输入百粒重"
              },
              {
                type: "number",
                validator: validateNumber,
                message: "百粒重必须为正数值"
              }
            ],
            ridgingSpacing: [
              {
                required: true,
                validator: validateNull,
                trigger: "blur",
                messageNull: "垄距不能为空,请输入垄距"
              },
              {
                type: "number",
                validator: validateNumber,
                message: "垄距必须为正数值"
              }
            ]
          },
    
          options: this.$math.range(0, 4, true)._data
        };
      },
      methods: {
        roundFixedNum(value, n) {
          return Math.round(value * Math.pow(10, n)) / Math.pow(10, n);
        },
        submitForm(formName) {
          if (this.ruleForm.toFixedNum === "") {
            this.ruleForm.toFixedNum = 2;
          }
          this.$math = create(all);
          this.$refs[formName].validate(valid => {
            if (valid) {
              this.ruleForm.preHectareWeight = this.roundFixedNum(
                this.$math
                  .chain(this.ruleForm.density)
                  .multiply(this.ruleForm.KWEI)
                  .divide(10)
                  .done(),
                this.ruleForm.toFixedNum
              );
    
              const temp = this.$math
                .chain(this.ruleForm.ridgingSpacing)
                .divide(100)
                .multiply(this.ruleForm.density)
                .done();
    
              this.ruleForm.ridgingSpacingNum = this.roundFixedNum(
                temp,
                this.ruleForm.toFixedNum
              );
              this.ruleForm.spacing = this.roundFixedNum(
                this.$math
                  .chain(100)
                  .divide(temp)
                  .done(),
                this.ruleForm.toFixedNum
              );
            } else {
              alert("error:错误提示");
              return false;
            }
          });
        },
        resetForm(formName) {
          this.$refs[formName].resetFields();
        }
      }
    };
    </script>
    

    TIPS

    自定义校验

    在使用自定义校验规则时,如以下示例中:

     rules: {
         density: [
            {
              required: true,
              validator: validateNull,
              trigger: "blur",
              messageNull: "密度不能为空,请输入密度"
            },
            {
              type: "number",
              validator: validateNumber,
              message: "密度必须为正数值"
            }
          ],
         ...略
          ]
        },
    

    messageNull为自定义的一个属性,在rule的对象中,已经有message这个属性可以用.对应初始化在data()中的校验规则如下,分别用来判断""和是否为数字.

    const validateNull = (rule, value, callback) => {
          if (value === "") {
            callback(new Error(rule.messageNull));
          } else {
            callback();
          }
        };
     const validateNumber = (rule, value, callback) => {
        const reg = /^[0-9]+.?[0-9]*$/;
        if (!reg.test(value)) {
          callback(new Error(rule.message));
        } else {
          callback();
        }
      };
    

    math.js的常用方法

    API地址

    • math.sqrt(4) 开方
    • math.add( ) 加
    • math.subtract( )减
    • math.divide( ) 除
    • math.multiply( )乘

    进行链式操作时可以如下(这里的math放到了vue的全局中,正式使用时注意改代码)

    const tmp0 = 9000/100*2
    const tmp1 = this.$math.chain(9000)
                  .divide(100)
                  .multiply(2)
                  .done(),
    

    在math.js中要保留多少个数字可以使用math.format(),官方示例如下:

    const ans = math.add(0.1, 0.2)     //  0.30000000000000004
    math.format(ans, {precision: 14})  // '0.3'
    

    本次代码中如果使用此种需求,可以这样:

     this.ruleForm.ridgingSpacingNum = this.$math.format(
              this.$math
                 .chain(this.ruleForm.ridgingSpacing)
                 .divide(100)
                 .multiply(this.ruleForm.density)
                 .done(),
               4
             );
    

    或者

    this.ruleForm.ridgingSpacingNum = this.$math.format(
    this.$math
      .chain(this.ruleForm.ridgingSpacing)
      .divide(100)
      .multiply(this.ruleForm.density)
      .done(),
    { precision: 14 }
    );
    

    在初始化下拉选择保留几位小数时,偷懒了下,直接生成数组,如下.其中_data的内部属性是Array类型,而直接返回的类型是Matrix,这块和官网的API说明有歧义,不知道为什么.

    this.$math.range(0, 4, true)._data
    

    小数点精度

    开始使用toFixed来判断精度,但是后来想起来这个是银行的精度计算.目前的需求是完全的四舍五入.所以只能使用Math.round()来处理,所以定义了一个方法,根据选择的精度,来处理响应的数据,代码如下:

    /**
    * value 参数数值
    * n 保留的小数点位数
    */
    roundFixedNum(value, n) {
    return Math.round(value * Math.pow(10, n)) / Math.pow(10, n);
    },
    
  • 相关阅读:
    YaCy is a free search engine
    html css js dom树到底是什么关系
    清华的搜索课程
    Gentle中的O/R映射Attributes
    PHP headers_sent() 函数
    阿里云服务器怎么设置能让网站发邮件
    关于PHP 开启zlib gzip配置
    thinkphp无法加载控制器:Admin
    阿里云邮件服务器怎么设置才能在QQ邮箱访问,互发邮件?
    linux下配置apachenutch 笨笨熊
  • 原文地址:https://www.cnblogs.com/GYoungBean/p/12748274.html
Copyright © 2011-2022 走看看