强调vue语法
createElement 函数是用来生成 HTML DOM 元素的
Vue.js 里面的 createElement 函数,这个函数的作用就是生成一个 VNode节点,render 函数得到这个 VNode 节点之后,返回给 Vue.js 的 mount 函数,渲染成真实 DOM 节点,并挂载到根节点上。
Vue 的$mount() 为手动挂载,
在项目中可用于延时挂载( 例如在挂载之前要进行一些其他操作、 判断等)
之后要手动挂载上。 new Vue时, el和$mount并没有本质上的不同。
this.$destroy()内部銷毀組件
async-validator是一个表单的异步验证的第三方库
// 基本用法
var schema = require('async-validator'); // 引用组件
var descriptor = {
name: {
type: "string",
required: true,
validator: (rule, value) => value === 'muji',
}
}; // 定义一个descriptor
var validator = new schema(descriptor); // descriptor分配给schema,创建一个validator
validator.validate({name: "muji"}, (errors, fields) => {
if(errors) {
// validation failed, errors is an array of all errors
// fields is an object keyed by field name with an array of
// errors per field
return handleErrors(errors, fields);
}
// validation passed
}); // 参数一:要验证的对象、参数二:回调函数
v-mod是语法糖,实现自定义组件双绑需要指定:value和@input即可
**其中要思考的问题
1 input是自定义组件,它是怎么实现双向绑定的
2 formItem是怎么知道执行校验的,它是怎么知道input状态的?它是怎么获得对应的数据模型的
3.form是怎么进行全局校验的 它用什么方法把数据模型和校验规则传递给内部组件?**
index.vue
<template>
<div>
<h3>KForm表单</h3>
<hr\>
<!-- <k-input :value="model.username" @input="model.username=$event"></k-input> -->
<k-form :model="model" :rules="rules" ref="kForm">
<k-form-item label="用户名" prop="username">
<k-input v-model="model.username"></k-input>
</k-form-item>
<k-form-item label="密码" prop="password">
<k-input type="password" v-model="model.password"></k-input>
</k-form-item>
<k-form-item>
<el-button type="primary" @click="submitForm('kForm')">提交</el-button>
</k-form-item>
</k-form>
<h3>Element表单</h3>
<hr>
<el-form :model="model" :rules="rules" ref="loginForm">
<el-form-item label="用户名" prop="username">
<el-input v-model="model.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="password">
<el-input type="password" v-model="model.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('loginForm')">提交</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import KInput from './Input.vue'
import KFormItem from './FormItem.vue'
import KForm from './Form.vue'
export default {
components: {
KInput,
KFormItem,
KForm
},
data () {
return {
// 数据模型
model: { username: 'tom', password: '' },
// 校验规则
rules: {
username: [{ required: true, message: '请输入用户名' }],
password: [{ required: true, message: '请输入密码' }]
}
}
},
methods: {
submitForm (form) {
// 表单全局校验
this.$refs[form].validate(valid => {
if (valid) {
alert('请求登录!')
} else {
alert('校验失败!')
}
})
}
}
}
</script>
<style scoped>
</style>
Form
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
// provide可以跨层级传参给子代
provide () {
return {
form: this
}
},
props: {
model: {
type: Object,
required: true
},
rules: {
type: Object
}
},
methods: {
async validate (cb) {
// 執行表單中所有的表单项的校验
// 返回的 promise的数组
const tasks = this.$children.filter(item => item.prop).map(item => item.validate())
// tasks中任意一个错误就校验失败
// await是直接获取多个promise的结果的,因为Promise.all()返回的也是一个promise所以如果要使用await拿到多个promise的值,
// 同步化
const result = await Promise.all(tasks)
if (result.some(valid => !valid)) {
// eslint-disable-next-line
cb(false)
} else {
// eslint-disable-next-line
cb(true)
}
}
}
}
</script>
<style scoped>
</style>
FormItem
<template>
<div>
<label v-if="label">{{label}}</label>
<!-- 插槽 -->
<slot></slot>
<!-- 校验错误信息 -->
<p v-if="errorMessage" class="error">{{errorMessage}}</p>
</div>
</template>
<script>
import Validator from 'async-validator'
import { Promise } from 'q'
export default {
inject: ['form'],
props: ['label', 'prop'],
data () {
return {
errorMessage: ''
}
},
created () {
this.$on('validate', this.validate)
},
methods: {
validate () {
return new Promise(resolve => {
// 校验规则制定
// [this.prop]计算属性 希望this prop key的值是一个表达式
const descriptor = { [this.prop]: this.form.rules[this.prop] }
// 创建校验器
const validator = new Validator(descriptor)
// 执行校验
validator.validate(
{ [this.prop]: this.form.model[this.prop] },
errors => {
if (errors) {
// 显示错误信息
this.errorMessage = errors\[0\].message
resolve(false)
} else {
this.errorMessage = ''
resolve(true)
}
}
)
})
}
}
}
</script>
<style scoped>
.error {
color: red;
}
</style>
Input
<template>
<div>
<input :type="type" :value="value" @input="onInput">
</div>
</template>
<script>
export default {
props: {
type: {
type: String,
default: 'text'
},
value: {
type: String,
default: ''
}
},
methods: {
onInput (e) {
// 通知老爹发生了input事件
this.$emit('input', e.target.value)
// 通知FormItem校验
this.$parent.$emit('validate')
}
}
}
</script>
<style scoped>
</style>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。