美文网首页
快速原型开发

快速原型开发

作者: 翔子丶 | 来源:发表于2021-04-07 11:51 被阅读0次

VueCli提供一个插件可以进行原型快速开发

  • 安装

    npm install -g @vue/cli-service-global
    
  • 使用 vue serve

    在开发环境模式下零配置为 .js 或 .vue 文件启动一个服务器
    
    Options:
    
      -o, --open  打开浏览器
      -c, --copy  将本地 URL 复制到剪切板
      -h, --help  输出用法信息
    
  • 创建App.vue文件

    <template>
      <h1>Hello!</h1>
    </template>
    
  • 运行

    vue serve
    

    vue serve会在当前目录自动推导入口文件——入口可以是 main.jsindex.jsApp.vueapp.vue 中的一个

    可以显式地指定入口文件:

    vue serve MyComponent.vue
    
安装ElementUI
  • 创建文件,初始化package.json

    mkdir custom-component
    cd custom-component
    yarn init -y
    
  • 安装ElementUI

    vue add element
    
  • 创建main.js,加载ElementUI,使用Vue.use()安装插件

    import Vue from 'vue'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    import Login from './src/Login.vue'
    
    Vue.use(ElementUI)
    
    new Vue({
      el: '#app',
      render: h => h(Login)
    })
    
  • 创建src/Login.vue,并使用vue serve运行

    <template>
      <el-form class="form" ref="form" :model="user" :rules="rules">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="user.username"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input type="password" v-model="user.password"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="login">登 录</el-button>
        </el-form-item>
      </el-form>
    </template>
    
    <script>
    export default {
      name: 'Login',
      data() {
        return {
          user: {
            username: '',
            password: '',
          },
          rules: {
            username: [
              {
                required: true,
                message: '请输入用户名',
              },
            ],
            password: [
              {
                required: true,
                message: '请输入密码',
              },
              {
                min: 6,
                max: 12,
                message: '请输入6-12位密码',
              },
            ],
          },
        }
      },
      methods: {
        login() {
          this.$refs.form.validate((valid) => {
            if (valid) {
              alert('验证成功')
            } else {
              alert('验证失败')
              return false
            }
          })
        },
      },
    }
    </script>
    
    <style>
    .form {
      width: 30%;
      margin: 150px auto;
    }
    </style>
    
组件开发
步骤条组件
  • 创建Steps.vue

    <template>
      <div class="lg-steps">
        <div class="lg-steps-line"></div>
        <div
          class="lg-step"
          v-for="index in count"
          :key="index"
          :style="{ color: active >= index ? activeColor : defaultColor }"
        >
          {{ index }}
        </div>
      </div>
    </template>
    
    <script>
    import './steps.css'
    export default {
      name: 'LgSteps',
      props: {
        count: {
          type: Number,
          default: 3,
        },
        active: {
          type: Number,
          default: 0,
        },
        activeColor: {
          type: String,
          default: 'red',
        },
        defaultColor: {
          type: String,
          default: 'green',
        },
      },
    }
    </script>
    <style></style>
    

    使用vue serve ./Steps.vue运行,打开页面访问此组件

  • 创建Steps-test.vue组件,进行测试

    <template>
      <div>
        <steps :count="count" :active="active"></steps>
        <button @click="next">下一步</button>
      </div>
    </template>
    
    <script>
    import Steps from './Steps.vue'
    export default {
      components: {
        Steps,
      },
      data() {
        return {
          count: 4,
          active: 0,
        }
      },
      methods: {
        next() {
          if (this.active < this.count) {
            this.active++
          }
        },
      },
    }
    </script>
    <style></style>
    
表单组件
  • 模仿Element的Form组件,在src下创建form文件夹

  • 创建Form.vue、FormItem.vue、Input.vue以及Button.vue组件

    <!-- Form.vue -->
    <template>
      <form>
        <slot></slot>
      </form>
    </template>
    
    <script>
    export default {
      name: 'wangForm',
      props: {
        model: {
          type: Object
        },
        rules: {
          type: Object
        }
      }
    }
    
    </script>
    <style>
    </style>
    <!-- FormItem.vue -->
    <template>
      <div>
        <label>{{ label }}</label>
        <div>
          <slot></slot>
          <p v-if="errMessage">{{ errMessage }}</p>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'wangFormItem',
      props: {
        label: {
          type: String
        },
        prop: {
          type: String
        }
      },
      data () {
        return {
          errMessage: ''
        }
      }
    }
    </script>
    
    <style>
    </style>
    <!-- Input.vue -->
    <template>
      <div>
        <input v-bind="$attrs" :type="type" :value="value" @input="handleInput">
      </div>
    </template>
    
    <script>
    export default {
      name: 'wangInput',
      // 禁用父组件默认属性
      inheritAttrs: false,
      props: {
        value: {
          type: String
        },
        type: {
          type: String,
          default: 'text'
        }
      },
      methods: {
        handleInput (evt) {
          this.$emit('input', evt.target.value)
        }
      }
    }
    </script>
    <style>
    </style>
    <!-- Button.vue -->
    <template>
      <div>
        <button @click="handleClick"><slot></slot></button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'wangButton',
      methods: {
        handleClick (evt) {
          this.$emit('click', evt)
          evt.preventDefault()
        }
      }
    }
    </script>
    <style></style>
    
  • 创建Form-test.vue测试组件

    <template>
      <wang-form class="form" ref="form" :model="user" :rules="rules">
        <wang-form-item label="用户名" prop="username">
          <!-- <wang-input v-model="user.username"></wang-input> -->
          <wang-input :value="user.username" @input="user.username=$event" placeholder="请输入用户名"></wang-input>
        </wang-form-item>
        <wang-form-item label="密码" prop="password">
          <wang-input type="password" v-model="user.password"></wang-input>
        </wang-form-item>
        <wang-form-item>
          <wang-button type="primary" @click="login">登 录</wang-button>
        </wang-form-item>
      </wang-form>
    </template>
    
    <script>
    import WangForm from './form/Form'
    import WangFormItem from './form/FormItem'
    import WangInput from './form/Input'
    import WangButton from './form/Button'
    export default {
      components: {
        WangForm,
        WangFormItem,
        WangInput,
        WangButton
      },
      data () {
        return {
          user: {
            username: '',
            password: ''
          },
          rules: {
            username: [
              {
                required: true,
                message: '请输入用户名'
              }
            ],
            password: [
              {
                required: true,
                message: '请输入密码'
              },
              {
                min: 6,
                max: 12,
                message: '请输入6-12位密码'
              }
            ]
          }
        }
      },
      methods: {
        login () {
          console.log('button')
          // this.$refs.form.validate(valid => {
          //   if (valid) {
          //     alert('验证成功')
          //   } else {
          //     alert('验证失败')
          //     return false
          //   }
          // })
        }
      }
    }
    </script>
    
    <style>
      .form {
        width: 30%;
        margin: 150px auto;
      }
    </style>
    
    

    vue serve ./src/Form-test.vue运行

  • 设置表单验证

    表单验证原则:input组件中触发自定义事件validate、FormItem渲染完毕注册自定义事件validate

    修改Input.vue

    ...
    <script>
    export default {
      ...
      methods: {
        // input组件中触发自定义事件validate
        // FormItem渲染完毕注册自定义事件validate
        handleInput (evt) {
          this.$emit('input', evt.target.value)
          // 找input的父组件
          const findParent = parent => {
            while (parent) {
              if (parent.$options.name === 'LgFormItem') {
                break
              } else {
                parent = parent.$parent
              }
            }
            return parent
          }
          const parent = findParent(this.$parent)
          // 如果找到就触发自定义事件
          if (parent) {
            parent.$emit('validate')
          }
        }
      }
    }
    </script>
    

    需要在Fome.vue中将Form组件实例注册依赖

    provide () {
        return {
          form: this
        }
      }
    

    修改FormItem.vue,使用async-validator进行验证

    ...
    <script>
    import AsyncValidator from 'async-validator'
    export default {
      name: 'WangFormItem',
      inject: ['form'],
      ...
      mounted () {
        this.$on('validate', () => {
          this.validate()
        })
      },
      methods: {
        validate () {
          // 如果没有prop 就不需要验证
          if (!this.prop) return
          const value = this.form.model[this.prop]
          const rules = this.form.rules[this.prop]
    
          const descriptor = { [this.prop]: rules }
          const validator = new AsyncValidator(descriptor)
          return validator.validate({ [this.prop]: value }, errors => {
            if (errors) {
              this.errMessage = errors[0].message
            } else {
              this.errMessage = ''
            }
          })
        }
      }
    }
    </script>
    
    <style>
    </style>
    
    

    修改Form.vue,提供validate方法

    methods: {
        validate (cb) {
          // 过滤出含有prop验证的节点 执行validate方法 返回promise对象
          const tasks = this.$children
            .filter(child => child.prop)
            .map(child => child.validate())
    
          Promise.all(tasks)
            .then(() => cb(true))
            .catch(() => cb(false))
        }
    }
    
  • 此时重新运行,开启表单验证
    项目地址

相关文章

网友评论

      本文标题:快速原型开发

      本文链接:https://www.haomeiwen.com/subject/ddzykltx.html