总文件入口-index.vue
用户使用层
- 主要是用来定义:
- 校验规则
- 登陆事件处理(全部校验通过与否调用全局弹窗)
项目结构说明
用户入口文件-inex.vue
<template> <div> <Vfrom :model="model" :rules="rules" ref="from"> <Vfromitem label="用户名" prop="username"> <Vinpnt v-model="model.username"></Vinpnt> </Vfromitem> <Vfromitem label="密码" prop="password"> <Vinpnt v-model="model.password"></Vinpnt> </Vfromitem> <Vfromitem> <button @click="login"> 提交 </button> </Vfromitem> </Vfrom> {{model}} </div></template><script>import Vfrom from './vfrom';import Vfromitem from './vfromitem';import Vinpnt from './vinput';export default { components:{ Vfrom, Vfromitem, Vinpnt }, data() { return { model:{ username: 'sss', password:'' }, rules:{ username:[ {required:true, message:'请输入姓名'}, ], password:[ {required:true, message:'请输入密码'}, ] } } }, methods:{ login(){ this.$refs.from.validator((isvalid)=>{ // console.log(isvalid, 'isvalid') // if(isvalid) { // console.log('验证通过') // } else { // console.log('验证失败') // } // this.$notice({ // title:'校验结果', // message:isvalid?'验证通过':'验证失败', // duration:2000 // }).show() // console.log(isvalid,'isvalid') this.$notice({ title: '校验结果', message: isvalid ? '请求登录' : '校验失败', duration: 2000 }).show() }) } }}</script><style></style>
提交按钮<button @click="login">登录</button>
登陆事件处理(全部校验通过与否调用全局弹窗)
全局校验-From.vue
- 全局的校验,调用每个自组建的校验结果
<template> <div> <slot></slot> </div></template><script>export default { name:'vfrom', provide(){ return{ from: this } }, props:{ model:{ type:Object, requiree:true }, rules:Object }, methods:{ validator:function(cb){ const tasks =this.$children .filter(item=> item.prop) .map(item=> item.validator()) Promise.all(tasks) .then(()=>{cb(true)}) .catch(()=>{cb(false)}) } }}</script><style></style>
单一input内容校验-FromItem.vue
- 获取校验规则
- 获取当前的值
- import Schema from "async-validator"; 引入校验模块
- 创建校验规则
- 执行校验
- if(erro){thi.message='错误信息'}else{this.messgae=''}
<template> <div> <label :for="prop">{{label}}</label> <slot></slot> <span v-if="error">{{error}}</span> </div></template><script>import Schema from 'async-validator';export default { name: 'vfromitem', inject:['from'], props:{ // label="用户名" prop="username" label:{ default:'', type:String }, prop:{ default:'', type:String } }, data() { return { error:'' } }, mounted(){ this.$on('validator', ()=>{ this.validator() }) }, methods:{ validator:function(){ // console.log('进来了吗') // 获取校验规则 const rules =this.from.rules[this.prop] // 获取当前的值 const value =this.from.model[this.prop] // 创造校验器 const schema= new Schema({ [this.prop]:rules }) // console.log({[this.prop]:rules}, '[this.prop]:rules') return schema.validate({ [this.prop]:value },errors=>{ // console.log(errors,'sdsds') if(errors){ this.error=errors[0].message }else{ this.error='' } }) } }}</script><style> span{ color:red; font-size: 10px; }</style>
type:text填写信息-Input.vue
- 改变value值
- 调用父组建校验方法
<template> <div> <input :type="type" :value="value" @input="Oninput"> </div></template><script>export default { name:'vinput', props:{ type:{ type:String, default:'text' }, value:{ type:String, default:'' } }, methods:{ Oninput:function (e) { this.$emit('input',e.target.value) this.$parent.$emit('validator') } }}</script><style></style>
通知全局组建-Vue.prototype.$notice
(弹窗类组建封装)-全局注册组建
- 在vue定义方法$notice
- 方法内部调用create方法
- 传入组建和props
使用new Vue 生成组建挂在在dome上;
思路:
- 创建dom元素
- 将dom元素放在body里面
- 显示后,消失操作, 删除dom元素以及销毁实例
在new Vue中,redner中的参数 h
h: 是一个`createElement函数` 可以返回一个虚拟dome
调用new Vue().$mount()
`$mount()`的目的 :将vdome -> dom
vm
`vm` : new Vue()构造函数
vm.$el
真实的dom元素
vm.$children
[Vuecomponent]
const comp = vm.$children[0] comp.remove=()=>{}
给vue组建定义删除组建的方法 使用new Vue 生成组建挂在在dome上;
/utils/create-构造组件实例
import Vue from 'vue' // 实现一个create方法,能够创建指定组件实例 // 并将其挂载至body上 // Component是组件配置对象 export default function create(Component, props) { // 怎么创建组件实例 // 方案1:可以通过Vue.extend(Component)获取组件构造函数 // const Ctor = Vue.extend(Component) // const comp = new Ctor() // 方案2:借助Vue构造组件实例 const vm = new Vue({ render(h) { // h是createElement函数,可以返回vdom return h(Component, {props}) } }).$mount() // $mount()目标:将vdom=》dom // 手动追加dom document.body.appendChild(vm.$el) const comp = vm.$children[0] // 淘汰逻辑 comp.remove = () => { document.body.removeChild(vm.$el) // 执行 remove 方法时,执行 $destroy 销毁实例 comp.$destroy() } return comp }
组建内容-/components/Notice.vue
<template> <div class="box" v-if="isShow"> //ishow 是用来判断是否展示 <h3>{{title}}</h3> //传入进来的参数的title <p class="box-content">{{message}}</p> //提示信息 </div> </template>
<script> export default { props: { title: { // 弹窗的标题 type: String, default: "" }, message: { // 展示内容 type: String, default: "" }, duration: { // 延迟的关闭的时间 type: Number, default: 1000 } }, data() { return { isShow: false // 默认组建为隐藏状态不限时 }; }, methods: { show() { // 调用show 方法显示组建时,先将内部data定义的isShow改为true // 展示之后,执行hide 进行隐藏。使用setTimeout;隐藏的时间将有传进来的参数进行调动 this.isShow = true; // 当执行show方法之后,执行hide方法 setTimeout(this.hide, this.duration); }, hide() { this.isShow = false; this.remove(); } } }; </script>
<style> .box { position: fixed; width: 100%; top: 16px; left: 0; text-align: center; pointer-events: none; background-color: #fff; border: grey 3px solid; box-sizing: border-box; } .box-content { width: 200px; margin: 10px auto; font-size: 14px; padding: 8px 16px; background: #fff; border-radius: 3px; margin-bottom: 8px; } </style>
学习资源
思维导图: https://www.processon.com/vie...
github:https://github.com/speak44/Vu...