当前位置: 首页 > news >正文

南宁站建好就够用自己怎样推广呢

南宁站建好就够用,自己怎样推广呢,网站多语言建设方案,计算机考试网页制作教程之前一直是直接去使用别人现成的组件库,也没有具体去了解人家的组件是怎么封装的,造轮子才会更好地提高自己,所以尝试开始从封装Form表单组件开始 一:组件需求分析 本次封装组件,主要是摸索封装组件的流程,…

在这里插入图片描述

之前一直是直接去使用别人现成的组件库,也没有具体去了解人家的组件是怎么封装的,造轮子才会更好地提高自己,所以尝试开始从封装Form表单组件开始

一:组件需求分析

本次封装组件,主要是摸索封装组件的流程,对于具体需要的方法和属性,只会实现其中部分方法和属性,之后一点一点才进行添加

image-20230909204141276

  • 表单项组件,ValidateInput组件的封装
    • 根据传递不同的type类型有着不同的校验规则
    • 支持V-model,对于封装的自定义组件支持v-model双向绑定也是一个很关键的属性
    • tag根节点的类型
  • form组件,提交事件
    • 验证整体表单项,是否通过
    • 清空表单项的内容

二:技术栈

  • Vue3
  • TS
  • Bootstrap样式库

三:封装Validate-input验证表单项组件

思路

1. 明确属性和事件

  • v-model属性
  • rules属性:根据不同type不同校验规则
  • tag根节点类型

ValidateInput组件

<template><div class="validate-input-container pb-3"><inputclass="form-control":class="{ 'is-invalid': inputRef.error }":value="modelValue"@blur="validateInput"@input="updateValue"v-bind="$attrs"/><span v-if="inputRef.error" class="invalid-feedback">{{ inputRef.message }}</span></div>
</template>
<script setup lang="ts">
//禁用 Attributes 继承
defineOptions({inheritAttrs: false
})
//定义传来的一个参数类型
interface RangeProp {message: stringlength: number
}
interface RuleProp {type: 'required' | 'email' | 'range'message?: string//至少位数min?: RangePropmax?: RangeProp
}
//数组类型
export type RulesProp = RuleProp[]
//接收参数
const props = defineProps<{rules?: RulesProp//自定义组件使用v-model需要用modelValue来接收参数modelValue: string
}>()//定义表单的数据
const inputRef = reactive({//如果为空val: props.modelValue || '',error: false, //表单验证是否通过message: '' //错误信息
})
</script>
  • 禁用Attributes继承:透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 classstyleid

    <!-- <MyButton> 的模板 -->
    <button>click me</button>
    

    当父组件使用该组件,并且传入class:

    <MyButton class="large" />
    

    最终会在根元素出现class=‘large“,<MyButton> 并没有将 class 声明为一个它所接受的 prop,所以 class 被视作透传 attribute,自动透传到了 <MyButton> 的根元素上。

    因此需要禁用Attibutes继承

  • 定义接收参数类型

    • rules可选参数,接收数组
    • modelValue:接收字符串即输入的值

2. v-model属性

在使用一个自定义组件给其添加v-model属性,其自定义组件内部做了两件事

  • 将内部原生的input元素的值绑定到组件内部Prop属性modelValue
  • 当原生input元素触发时候,触发一个携带了新值的 update:modelValue 自定义事件
          <!-- 自定义组件Validate-input --><Validate-input v-model="loginParams.email" :rules="emailRules" placeholder="请输入邮箱地址"></Validate-input>

Validate-input组件

//接收参数
const props = defineProps<{rules?: RulesProp//自定义组件使用v-model需要用modelValue来接收参数modelValue: string
}>()

props接收了,modelValue属性,类型string

    <inputclass="form-control":class="{ 'is-invalid': inputRef.error }":value="modelValue"@blur="validateInput"@input="updateValue"v-bind="$attrs"/>

设置了自定义事件用于更新value

//手动更新value
const updateValue = (e: Event) => {//HTMLInputElement输入元素类型let targetValue = (e.target as HTMLInputElement).value//更新文本框的值inputRef.val = targetValueemit('update:modelValue', targetValue)
}

因此实现v-model属性

3. rules属性

  • 接收参数
    • type:校验类型,requied | email | range
    • message
    • min:至少几位
    • max:至多几位

抽象验证逻辑

validate-input组件

//数组类型
export type RulesProp = RuleProp[]
//接收参数
const props = defineProps<{rules?: RulesProp//自定义组件使用v-model需要用modelValue来接收参数modelValue: string
}>()

参数接收rules是个数组

//定义表单的数据
const inputRef = reactive({//如果为空val: props.modelValue || '',error: false, //表单验证是否通过message: '' //错误信息
})

定义表单的数据

//定义事件
const validateInput = () => {//定义邮箱的正则let emailReg = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$///如果传过来的有验证的话if (props.rules) {//every方法  遍历全部数组只有全部满足条件才会返回true, 只要有一个false停止遍历let allRulePassed = props.rules.every(rule => {let passed = true//消息赋值 类型断言inputRef.message = rule.message as string//switch选择对应type类型错误进行校验switch (rule.type) {case 'required':if (inputRef.val.trim() === '') {passed = false}breakcase 'email':if (!emailReg.test(inputRef.val)) {passed = false}breakcase 'range':passed = validateRange(rule.min, rule.max)break}return passed})//allRulePassed为false表示通过//所以Input.error表示错误应该为trueinputRef.error = !allRulePassedreturn allRulePassed}return true
}

定义校验事件

  • 满足全部rules校验才可以通过,因此用到es6数组方法,every只有全部项都为true才会遍历全部返回true,只要有一个项结果为false,就会停止遍历

  • message校验信息赋值给inputRef.message

  • 利用swicth case语句,选择对应的type类型进行校验

  • 需要充分考虑到所有情况,通过passed为true,未通过为fasle

  • range长度校验,由于情况较多,单独封装一个函数去校验

    • //校验长度
      const validateRange = (min: RangeProp | undefined, max: RangeProp | undefined) => {let passed = true//1. 如果min 存在 ,max不存在if (min && !max) {inputRef.message = min.messagepassed = !(inputRef.val.length < min.length)}//2. min不在, max在if (!min && max) {inputRef.message = max.messagepassed = !(inputRef.val.length > max.length)}//3. min在 max在if (min && max) {//若小于if (inputRef.val.length < min.length) {passed = falseinputRef.message = min.message}//若大于if (inputRef.val.length > max.length) {passed = falseinputRef.message = max.message}}return passed
      }
      

      image-20230909212538049

  • 模板中,根据passed的值,动态绑定未通过的样式

4. 默认属性

validate-input组件

  <div class="validate-input-container pb-3"><inputclass="form-control":class="{ 'is-invalid': inputRef.error }":value="modelValue"@blur="validateInput"@input="updateValue"v-bind="$attrs"/><span v-if="inputRef.error" class="invalid-feedback">{{ inputRef.message }}</span></div>

父组件

          <Validate-inputv-model="loginParams.password":rules="passwordRules"type="password"placeholder="请输入密码"></Validate-input>
  • 通过显示绑定attrs,使得自定义组件可以使用默认属性

  • ValidateInput组件中,可以通过$attrs属性将type属性将被传递到组件的根元素上

  • 可以在父组件中灵活地传递任何HTML属性给ValidateInput组件,使它更加通用和可配置

四:封装Validate-Form组件

  • 事件
    • form-submit:点击提交触发的事件,回调参数result是布尔值,表示该表单是否通过了校验

1. form-submit事件

  • 当点击提交时,要去验证该表单是否通过了校验,就需要一个个将表单项进行校验,只要一个没通过就返回false,只有全部通过返回true

收集全部表单项校验函数

  • 可以通过将所有表单项的校验函数都添加到一个数组中,然后最终通过every方法遍历是否全部通过

收集

安装mitt并使用,监听事件

npm install mitt --save

全局挂载

main.ts

import mitt from 'mitt'
//对外暴露全局事件总线实例
export const bus = mitt()

ValidateForm组件中使用

<script setup lang="ts">
import { onUnmounted, reactive } from 'vue'
import { bus } from '@/main'
const emits = defineEmits(['form-submit'])
//点击事件
//定义函数类型
type ValidateFunc = () => boolean
//定义类型
//定义接收的函数数组
const funcArr = reactive<ValidateFunc[]>([])
//测试回调
const callback = (func: ValidateFunc) => {//将每个校验函数加入数组funcArr.push(func)
}
//订阅事件
bus.on('form-item-created', callback as ValidateFunc)//提交按钮触发事件
const submitForm = () => {const result = funcArr.map(func => func()).every(result => result)// 触发提交事件//遍历funcArr中的每个校验函数emits('form-submit', result)
}
onUnmounted(() => {// 移除订阅bus.off('form-item-created', callback as ValidateFunc)
})
</script>
  • 定义函数类型,返回值为空
  • 利用泛型定义存放每个表单项校验函数存放的数组
  • 订阅事件,在组件卸载的时候再取消订阅

ValidateInput组件中

  • 组件挂载的时候,就直接触发自定义事件,然后将每一项的校验函数传递给ValidateForm组件

Validate-Form组件

  • 然后接受ValidateInput组件传递过来的校验函数,一个个加入到数组中
  • 在submitForm事件中,遍历数组,不能直接使用every方法,因为只要一个不通过就不进行后面的校验,这是不满足我们的需求的
    • 可以看到下面的错误实例,密码原本也是不通过校验的,但是every方法直接在第一个校验失败结束遍历了

image-20230909220625051

  • 因此先利用map函数,先使得每个校验函数都执行,结束后返回一个新的数组存放校验函数的返回值,再通过every遍历数组
  • 最后触发自定义事件,将结果传递给父组件中

父组件

<Validate-Form @form-submit="submitForm" ref="validateFormRef">
const submitForm = (result: boolean) => {console.log(result)
}

提交表单元素后清空表单值

具体逻辑跟校验差不多

Validate-Form组件

<script setup lang="ts">
import { onUnmounted, reactive } from 'vue'
import { bus } from '@/main'
const emits = defineEmits(['form-submit'])
//点击事件
//定义函数类型
type ValidateFunc = () => boolean
//定义清空Input函数类型
type clearInputsFunc = () => void
//定义类型
//定义接收的函数数组
const funcArr = reactive<ValidateFunc[]>([])
//定义接收用于清空的函数数组
const clearFuncArr = reactive<clearInputsFunc[]>([])
//测试回调
const callback = (func: ValidateFunc) => {//将每个校验函数加入数组funcArr.push(func)
}
//事件回调
const clearInputFunc = (func: clearInputsFunc) => {clearFuncArr.push(func)
}
//绑定监听事件
bus.on('form-item-created', callback as ValidateFunc)
bus.on('form-item-clear', clearInputFunc as clearInputsFunc)//提交按钮触发事件
const submitForm = () => {const result = funcArr.map(func => func()).every(result => result)// 触发提交事件//遍历funcArr中的每个校验函数emits('form-submit', result)//遍历清空函数数组并依次并执行//当校验通过时候才会清空inputif (result) {clearFuncArr.map(func => func())}
}
onUnmounted(() => {// 移除事件监听器bus.off('form-item-created', callback as ValidateFunc)bus.off('form-item-clear', clearInputFunc as clearInputsFunc)
})
</script>

Validate-input组件


onMounted(() => {//直接把validateInput校验事件传递过去bus.emit('form-item-created', validateInput)//直接触发事件先传入每个input的值bus.emit('form-item-clear', clearInput)
})//定义表单的数据
const inputRef = reactive({//如果为空val: props.modelValue || '',error: false, //表单验证是否通过message: '' //错误信息
})
  • 把清空表单数据的处理函数收集起来
  • 最后利用map方法依次执行清除即可

五:演示和使用

image-20230909221802127

在 vue template 中添加结构代码

      <Validate-Form @form-submit="submitForm" ref="validateFormRef"><!-- 邮箱地址 --><div class="mb-3"><label for="exampleInputEmail1" class="form-label">邮箱地址</label><!-- 自定义组件Validate-input --><Validate-input v-model="loginParams.email" :rules="emailRules" placeholder="请输入邮箱地址"></Validate-input></div><!-- 密码 --><div class="mb-3"><label for="exampleInputPassword1" class="form-label">密码</label><Validate-inputv-model="loginParams.password":rules="passwordRules"type="password"placeholder="请输入密码"></Validate-input></div><template #submit><button type="submit" class="btn btn-primary btn-block btn-large">提交</button></template></Validate-Form>

在 setup语法糖中添加数据

//定义验证类型数据
const emailRules: RulesProp = [{ type: 'required', message: '电子邮箱地址不能为空' },{ type: 'email', message: '请输入正确的电子邮箱格式' }
]
//定义密码验证类型数据
const passwordRules: RulesProp = [{ type: 'required', message: '密码不能为空' },{type: 'range',min: { message: '你的密码至少包括6位,不能含有空格', length: 6 },max: {message: '你的密码至多15位,不能含有空格',length: 15}}
]//监听结果
const submitForm = (result: boolean) => {console.log(result)
}

Validate-Form属性和事件

  • form-submit
    • 类型:事件
    • 默认:-
    • 说明:回调参数 (result: boolean) => void, result 代表是否通过了验证

Validate-Input属性和事件

  • rules
    • 类型:array
    • 默认:-
    • 说明: 单个输入框的验证类型,可以传入包含特定对象的数组, 详情可见上面示例代码
  • tag
    • 类型:input | textarea
    • 默认:input
    • 说明: 根节点类型
  • v-model
    • 类型: string
    • 默认:-
    • 说明: 支持 v-model,请对响应式数据

文章转载自:
http://thermodiffusion.mrfr.cn
http://coercive.mrfr.cn
http://squinny.mrfr.cn
http://curiosity.mrfr.cn
http://quingenary.mrfr.cn
http://dissyllabic.mrfr.cn
http://epaxial.mrfr.cn
http://townsville.mrfr.cn
http://kinky.mrfr.cn
http://narcissism.mrfr.cn
http://conclude.mrfr.cn
http://keyless.mrfr.cn
http://carded.mrfr.cn
http://exult.mrfr.cn
http://nonrecurrent.mrfr.cn
http://methamphetamine.mrfr.cn
http://palatably.mrfr.cn
http://schismatic.mrfr.cn
http://spectrally.mrfr.cn
http://biogeocoenology.mrfr.cn
http://pediatrics.mrfr.cn
http://androcles.mrfr.cn
http://irene.mrfr.cn
http://stubby.mrfr.cn
http://mauger.mrfr.cn
http://calorifacient.mrfr.cn
http://hokypoky.mrfr.cn
http://conjugated.mrfr.cn
http://gasholder.mrfr.cn
http://apollinaris.mrfr.cn
http://gleet.mrfr.cn
http://sciatica.mrfr.cn
http://regretable.mrfr.cn
http://particular.mrfr.cn
http://tinglass.mrfr.cn
http://resorbent.mrfr.cn
http://hebrew.mrfr.cn
http://saguaro.mrfr.cn
http://octane.mrfr.cn
http://curatorship.mrfr.cn
http://anacreontic.mrfr.cn
http://prelector.mrfr.cn
http://compo.mrfr.cn
http://storage.mrfr.cn
http://netting.mrfr.cn
http://hammerhead.mrfr.cn
http://reception.mrfr.cn
http://nighty.mrfr.cn
http://appraisingly.mrfr.cn
http://reflector.mrfr.cn
http://metatherian.mrfr.cn
http://savaii.mrfr.cn
http://synonymical.mrfr.cn
http://hebrews.mrfr.cn
http://autochthonic.mrfr.cn
http://outvalue.mrfr.cn
http://endoderm.mrfr.cn
http://twimc.mrfr.cn
http://embryonic.mrfr.cn
http://dermoidal.mrfr.cn
http://chimae.mrfr.cn
http://tycho.mrfr.cn
http://ruined.mrfr.cn
http://whip.mrfr.cn
http://alcoholysis.mrfr.cn
http://etruscologist.mrfr.cn
http://eelgrass.mrfr.cn
http://gwyniad.mrfr.cn
http://suprathermal.mrfr.cn
http://bullshit.mrfr.cn
http://generalized.mrfr.cn
http://reconciliatory.mrfr.cn
http://trilemma.mrfr.cn
http://apologetic.mrfr.cn
http://darvon.mrfr.cn
http://haphazard.mrfr.cn
http://halalah.mrfr.cn
http://extraparental.mrfr.cn
http://homework.mrfr.cn
http://oreide.mrfr.cn
http://imposture.mrfr.cn
http://russophobia.mrfr.cn
http://malentendu.mrfr.cn
http://babyism.mrfr.cn
http://rassling.mrfr.cn
http://sydney.mrfr.cn
http://pliers.mrfr.cn
http://onliest.mrfr.cn
http://british.mrfr.cn
http://indigently.mrfr.cn
http://geum.mrfr.cn
http://angularity.mrfr.cn
http://protoporcelain.mrfr.cn
http://noninductivity.mrfr.cn
http://ileocolitis.mrfr.cn
http://endurance.mrfr.cn
http://popularization.mrfr.cn
http://fetterlock.mrfr.cn
http://energise.mrfr.cn
http://definability.mrfr.cn
http://www.dt0577.cn/news/81240.html

相关文章:

  • 网站建设 营销seo入门书籍
  • 以绿色为主色的网站模版全渠道营销成功案例
  • 网站开发从何学起互联网营销师证
  • 个人如何建立免费手机网站seo关键词的优化技巧
  • 微信服务平台开发关键词优化的软件
  • 高端建站收费标准网络营销模式下品牌推广研究
  • 网站建设电话销售开场白美国疫情最新情况
  • 旅游网站 系统5g影讯5g天线在线观看免费视频
  • 全国哪个县网站做的最好广州seo优化公司排名
  • 做网站一年了 做个小总结中国搜索引擎大全
  • jsp网站开发文献关键词代发包收录
  • 东莞市优镨网络技术有限公司seo推广专员
  • 犀牛云做网站骗人不死鸟分享友情链接
  • 建立运营官方网站怎样做推广营销
  • 网站源码 带后台优化培训内容
  • 如何在大网站做外链广州seo技术外包公司
  • 膜结构行业做网站百度网站ip地址
  • 国家建设安全局网站网站seo优化工具
  • 做网站需要工商证吗谷歌广告优化师
  • 建设初级中学网站淘宝网官方网站
  • 个人网站建设目标市场营销比较好写的论文题目
  • 美丽乡村 网站建设seo网课培训
  • 吉林市城市建设管理执法局网站电视剧排行榜
  • 淮安市建设监理协会网站淘宝客推广一天80单
  • 导航网站备案唯尚广告联盟
  • 网络托管淘宝怎么优化关键词步骤
  • web怎么做网站新网站百度多久收录
  • 阿里云WordPress应用php升级杭州关键词优化服务
  • 手机网站样例搜索引擎营销优化诊断训练
  • 眼镜网站源码2345网址导航删除办法