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.js
、index.js
、App.vue
或app.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)) } }
-
此时重新运行,开启表单验证
项目地址
网友评论