Vue2之封装Form表单组件
Vue2之封装Form表单组件
·
快速原型开发工具
https://cli.vuejs.org/zh/guide/installation.html
你可以使用 vue serve 和 vue build 命令对单个 *.vue 文件进行快速原型开发,不过这需要先额外安装一个全局的扩展:
npm install -g @vue/cli-service-global
vue serve 的缺点就是它需要安装全局依赖,这使得它在不同机器上的一致性不能得到保证。因此这只适用于快速原型开发。
你所需要的仅仅是一个 App.vue 文件:
<template>
<h1>Hello!</h1>
</template>
然后在这个 App.vue 文件所在的目录下运行:
vue serve
// 运行的时候,默认找main.js ,找不到main.js,则去找App.vue
vue serve 使用了和 vue create 创建的项目相同的默认设置 (webpack、Babel、PostCSS 和 ESLint)。它会在当前目录自动推导入口文件——入口可以是 main.js、index.js、App.vue 或 app.vue 中的一个。你也可以显式地指定入口文件:
vue serve MyComponent.vue
表单组件的封装
- 涉及的细节
- 插槽
- parent、parent、parent、children、provide和inject 组件通信
- 组件的双向数据绑定
- 自定义broadcast、broadcast、broadcast、dispatch
src
├─ components
│ ├─ el-form-item.vue
│ ├─ el-form.vue
│ └─ el-input.vue
├─ App.vue
└─ main.js
App.vue
<template>
<div>
<el-form :model="ruleForm" :rules="rules" ref="ruleForm">
<el-form-item label="用户名" prop="username">
<el-input v-model="ruleForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="ruleForm.password"></el-input>
</el-form-item>
<el-form-item>
<button @click="submitForm">提交表单</button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import elForm from "./components/el-form";
import elInput from "./components/el-input";
import elFormItem from "./components/el-form-item";
export default {
components: {
"el-form": elForm,
"el-input": elInput,
"el-form-item": elFormItem
},
data() {
return {
ruleForm: {
username: "",
password: ""
},
rules: {
username: [
{ required: true, message: "请输入用户名" },
{ min: 3, max: 5, message: "长度在 3 到 5 个字符" }
],
password: [{ required: true, message: "请输入密码" }]
}
};
},
methods: {
submitForm(formName) {
this.$refs["ruleForm"].validate(valid => {
if (valid) {
alert("submit!");
} else {
console.log("error submit!!");
return false;
}
});
}
}
};
</script>
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 不停的找所有的子组件,找到后触发方法
Vue.prototype.$broadcast = function (componentName, eventName) {
let children = this.$children;
let arr = [];
function findFormItem(children) {
children.forEach(child => {
if (child.$options.name === componentName) {
if (eventName) {
arr.push(child.$emit('eventName'))
} else {
arr.push(child)
}
}
if (child.$children) {
findFormItem(child.$children);
}
});
}
findFormItem(children);
return arr;
}
// 找到父组件,向父组件派发方法(可跨级)
Vue.prototype.$dispatch = function (componentName, eventName) {
const parent = this.$parent;
while (parent) {
let name = parent.$options.name;
if (name == componentName) {
break;
} else {
parent = parent.$parent;
}
}
if (parent) {
if (eventName) {
// 找到后,触发这个方法
return parent.$emit(eventName)
}
return parent
}
}
new Vue({
render: h => h(App),
}).$mount('#app')
el-form.vue
<template>
<form @submit.prevent>
<slot></slot>
</form>
</template>
<script>
export default {
name: "elForm",
// 把当前实例暴露出来,放到当前组件的_provided属性
provide() {
return { elForm: this };
},
props: {
model: {
type: Object,
// 返回函数,保证数据不被共享
default: () => ({})
},
rules: {
type: Object,
default: () => ({})
}
},
methods: {
async validate(cb) {
// 需要看一下内部的el-form-item书否都通过校验了
let children = this.$broadcast("elFormItem");
try{
await Promise.all(children.map(child=>child.validate()));
cb(true);
}catch{
cb(false)
}
}
}
};
</script>
el-form-item.vue
<template>
<form @submit.prevent>
<slot></slot>
</form>
</template>
<script>
export default {
name: "elForm",
// 把当前实例暴露出来,放到当前组件的_provided属性
provide() {
return { elForm: this };
},
props: {
model: {
type: Object,
// 返回函数,保证数据不被共享
default: () => ({})
},
rules: {
type: Object,
default: () => ({})
}
},
methods: {
async validate(cb) {
// 需要看一下内部的el-form-item书否都通过校验了
let children = this.$broadcast("elFormItem");
try{
await Promise.all(children.map(child=>child.validate()));
cb(true);
}catch{
cb(false)
}
}
}
};
</script>
el-input.vue
<template>
<input type="text" :value="value" @input="handleInput">
</template>
<script>
export default {
name: "elInput",
props: {
value: {
String,
},
},
methods: {
handleInput(e) {
this.$emit("input", e.target.value);
// 跨级找到对应的formItem组件进行校验
this.$dispatch("elFormItem", "validate");
},
},
};
</script>
更多推荐


所有评论(0)