热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

va.js——Vue表单考证插件的写作历程

媒介前段时间,老大搭好了Vue的开辟环境,因而我们愉快地从JQ来到了Vue。这中心做的时刻,在表单考证上做的不高兴,看到vue的插件章节,认为本身也能写一个,因而就本身最先写了一个

媒介

前段时间,老大搭好了Vue的开辟环境,因而我们愉快地从JQ来到了Vue。这中心做的时刻,在表单考证上做的不高兴,看到vue的插件章节,认为本身也能写一个,因而就本身最先写了一个表单考证插件va.js。
固然为何不找个插件呢? vue-validator呀。

  1. 我想了下,一个是表单考证是个高度定制化的东西,这类网上找到的插件为了统筹各个公司的需求,所以加了许多功用,这些我们不须要。事实证明,vue-validator有50kb,而我写的va.js只需8kb。

  2. 另一个是,vue-validator的api我真的认为长, 动不动就v-validate:username=”[‘required’]”,这么一长串,而我设想的挪用也许如——v-va:Money

固然,本文仅是展现下,怎样写个满足本身公司需求的vue表单考证插件。下面引见下思绪。

一、表单考证模块的组成

任何表单考证模块都是由 设置——校验——报错——取值 这几部份组成的。

  1. 设置: 设置划定规矩 和设置报错,以及优先级

  2. 校验: 有在 change 事宜校验, 在点击提交按钮的时刻校验, 固然也有在input事宜取值的

  3. 报错: 报错体式格局平常要分,报错的笔墨有模板,也有自定义的

  4. 取值: 将经由历程考证的数据返还给开辟者挪用

下面是我老大针对公司项目给我提出的请求

  1. 集合式的治理 校验划定规矩 和 报错模板。

  2. 报错机遇可选

  3. 校验准确后的数据,已打包成对象,能够直接用

  4. 许可各个页面临划定规矩举行掩盖,对报错信息举行自定义修正,以及许可ajax猎取数据后,再对划定规矩举行补充

  5. 按递次来校验,在第一个报错的框弹出毛病

我就很猎奇地问, 为何要这模样呢?然后老大就跟我一条一条解答:

  1. 集合式治理划定规矩,和报错模板的优点,就是划定规矩能够全局通用,一改全改。老大跟我说,光是昵称的正则就改了三次。假如这些正则写在各个页面,o( ̄ヘ ̄o#)哼,你就要改N个页面了

  2. pc和挪动的流程不一样,pc许多校验都要在change事宜或许input事宜就校验并报错了,而挪动则平常是要到提交按钮再举行校验。所以写插件的时刻要做好两手预备。然后,报错用的ui要能够支撑我们如今用的layer插件。固然今后这个报错的ui也能够变,所以你懂滴。

  3. 固然本来jq时期,我们的公用表单考证,就可以考证完了,把数据都集合到一个对象里。如许ajax的时刻,就不必再去取值了。你这个插件耶要到达这个效果

  4. 本来jq的谁人公用剧本,正则和报错都集合到一个处所去了,在许多处所已很轻易了。然则在一些页面须要改东西的时刻还不够天真。像RealName这个划定规矩,最早是针对某个页面设置的,用的是后端接口上的字段名。另一个付出页,后端接口上的字段名改成了PayUser了,然则正则照样RealName的,本来我们是要复写一下RealName。这个就不太轻易也不好看了。别的一个,付出金额,有最大值和最小值的限定,这个须要从后端猎取的。你也要斟酌这个状况。要做到各个页面上也能有一些天真的处所能够修正划定规矩,自定义报错等等。

  5. 为何要按递次校验啊?你忘了上次牛哥让我们输入框,从上到下,按递次报错。不然用户都不晓得哪一个处所错了。另有划定规矩也是要按递次的。哦哦哦。看来此次我放东西的时刻,要用下数组了。只管坚持递次。

我听了以后,大抵懂了,本来之前本身写的jq表单考证另有这么多不舒服的点。-_-|||
接下来,是看看vue给我的好东西。让我来写

二、Vue 的插件怎样写

我一个vue小白,怎样就最先写vue插件了呢?那是由于想解决计划的时刻,翻Vue文档翻到了这里

《va.js——Vue 表单考证插件的写作历程》

这些东东,等我写完va.js的时刻,认为尤大写的真的是很清晰了。

实在我是想写个指令来完成表单考证的事的。效果发明能够有2-3个指令,而且要再Vue.prototype上定义些要领,好让各个子实例内部也能拓展划定规矩。因而老大说,这就相称于插件了。这让我非常吃鲸。

va.js主要用的是 Vue指令

《va.js——Vue 表单考证插件的写作历程》

《va.js——Vue 表单考证插件的写作历程》

Vue 文档真的写得很专心,然则我再补充一点吧
vnode.context 就是Vue的实例
我们做项目的时刻,常常一个根组件上挂着N个子组件,子组件上又能够挂着N个子组件。vnode.context猎取的实例,是绑定该指令的组件的实例。这个就相称好用了。你能够做许多事变

固然还用了点Vue.prototype

Vue.prototype.$method 就是能够在各个组件上挪用的要领。能够在组件内部用 this.$method挪用的

## 三、详细完成的思绪 ##

中心思绪如下图:

《va.js——Vue 表单考证插件的写作历程》

  • 划定规矩的组织函数

//va设置的组织函数
function VaConfig(type, typeVal, errMsg, name, tag){
this.type = type, this.typeVal = typeVal, this.errMsg = errMsg, this.name = name, this.tag = tag
}

  1. type: nonvoid(非空), reg(正则), limit(区间), equal(与某个input相称),unique(不能雷同)

  2. typeVal: 依据差别type设置差别的值

  3. errMsg: 自定义的报错信息

  4. name: 用来传ajax的字段,如Password, Username

  5. tag:用来报错的名字,如‘银行账号’,‘姓名’

设置了三种划定规矩

1.默许划定规矩: 只需绑定指令,就默许有的校验。 比方非空的校验。 能够额外加修饰符来去除
2.选项划定规矩: 经由历程Vue指令的修饰符增加的划定规矩。
3.自定义划定规矩: Vue指令属性值上增加的划定规矩。
同一个type的划定规矩只存在一个,也就是说,假如type为reg(正则),那末会相互掩盖。
掩盖的优先级: 自定义划定规矩 > 选项划定规矩 > 默许划定规矩

思绪讲的多了。也不晓得怎样讲了,下面人人直接看源码把。

源码

var Vue
var checkWhenChange = true //每一个输入框须要离焦即校验
// 给一个dom增加class
function addClass(dom, className){
// if (dom.classList){
// dom.classList.add(className);
// }else{
// dom.className += ' ' + className;
// }
var hasClass = !!dom.className.match(new RegExp('(\\s|^)' + _class + '(\\s|$)'))
if(!hasClass){
dom.className += ' ' + _class
}
}
//经常运用正则表
var regList = {
ImgCode: /^[0-9a-zA-Z]{4}$/,
SmsCode: /^\d{4}$/,
MailCode: /^\d{4}$/,
UserName: /^[\w|\d]{4,16}$/,
Password: /^[\w!@#$%^&*.]{6,16}$/,
Mobile: /^1[3|4|5|7|8]\d{9}$/,
RealName: /^[\u4e00-\u9fa5|·]{2,16}$|^[a-zA-Z|\s]{2,20}$/,
BankNum: /^\d{10,19}$/,
Money: /^([1-9]\d*|[0-9]\d*\.\d{1,2}|0)$/,
Answer: /^\S+$/,
Mail: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/
}
// 断言函数
function assert(condition, message){
if(!condition){
console.error('[va-warn]:' + message)
}
}
// Rule组织器
function Rule(ruleType, ruleValue, errMsg){
this.ruleType = ruleType
this.ruleValue = ruleValue
this.errMsg = errMsg || ''
}
//VaForm组织器
function VaForm(el, finalRules, modifiers){
this.ruleOrder = []
this.rules = {}
this.dom = el
this.value = el.value //值的副本
this.validated = false //是不是被考证过
this.tag = el.getAttribute('tag') //提醒的字段名
// this.correctMsg = `${this.tag}输入准确!`
this.correctMsg = ''
this.modifiers = modifiers //一些特别的设置
this.noCheck = false //为true则不要校验
this.ruleOrder = finalRules.map(item=>{
this.rules[item.ruleType] = item
return item.ruleType
})
}
//rules中靠前的设置优先级最高
function mergeRule(...rules){
var mergeResult = []
var combineArr = Array.prototype.concat.apply([], rules)
var hash = {}
combineArr.forEach((rule)=>{
if(hash[rule.ruleType] === undefined){
mergeResult.push(rule)
hash[rule.ruleType] = mergeResult.length - 1
}else{
var index = hash[rule.ruleType]
Object.assign(mergeResult[index], rule)
}
})
return mergeResult
}
//单个划定规矩的考证效果
function VaResult(ruleType, ruleValue, isPass, errMsg){
this.ruleType = ruleType
this.ruleValue = ruleValue
this.isPass = isPass
this.errMsg = errMsg
}
// 显现效果的组织器
function DisplayResult(isPass, message){
this.isPass = isPass
this.message = message
}
//单个划定规矩的校验,或许单个表单的校验
function validate(field, ruleType){
assert(field, '未输入要考证的字段')
var vaForm = this.forms[field]
var {ruleOrder, rules} = vaForm
if(ruleType === undefined){
return this.checkForm(vaForm)
}else{
var rule = rules[ruleType] //划定规矩
return this.checkRule(vaForm, rule)
}
// vaForm.validated = true
}
// 取得差别的报错信息
function getErrMsg(vaForm, ruleType, ruleValue){
var tag = vaForm.tag
var errMsgs = {
NonEmpty: `${tag}不能为空`,
reg: `${tag}花样毛病`,
limit: `${tag}必需在${ruleValue[0]}与${ruleValue[1]}之间`,
equal:`两次${tag}不雷同`,
length: `${tag}长度必需在${ruleValue[0]}与${ruleValue[1]}之间`,
unique: `${tag}不能雷同`
}
return errMsgs[ruleType]
}
//检测非空
function checkEmpty(ruleValue, vaForm, va){
return vaForm.value.trim() ? true : false
}
//检测正则
function checkReg(ruleValue, vaForm, va){
return ruleValue.test(vaForm.value) ? true : false
}
//检测数字区间
function checkLimit(ruleValue, vaForm, va){
var value = vaForm.value
return ((+value >= ruleValue[0]) && (+value <= ruleValue[1])) ? true : false
}
//检测相称
function checkEqual(ruleValue, vaForm, va){
var target = va.forms[ruleValue]
return target.value === vaForm.value ? true : false
}
//检测字符长度
function checkCharLength(ruleValue, vaForm, va){
var length = vaForm.value.length
return ((+length >= ruleValue[0]) && (+length <= ruleValue[1])) ? true : false
}
//几个输入框要各不雷同
function checkUnique(ruleValue, vaForm, va){
var uniqueGroup = va.uniqueGroup[ruleValue]
var values = uniqueGroup.map(field=>va.forms[field].value)
var uniqueValues = values.filter((item,index,arr)=>arr.indexOf(item) === index)
return values.length === uniqueValues.length ? true : false
}
// 检测单个划定规矩
function checkRule(vaForm, rule){
var forms = this.forms
var {ruleType, ruleValue, errMsg} = rule
//假如有自定义报错就按自定义报错,没有就花样化报错
errMsg = errMsg || getErrMsg(vaForm, ruleType, ruleValue)
var ruleCheckers = {
NonEmpty: checkEmpty,
reg: checkReg,
limit: checkLimit,
equal: checkEqual,
length: checkCharLength,
unique: checkUnique
}
var ruleChecker = ruleCheckers[ruleType]
var isPass = ruleChecker(ruleValue, vaForm, this)
var vaResult = new VaResult(ruleType, ruleValue, isPass, isPass ? null : errMsg)
return vaResult
}
//检测单个表单
function checkForm(vaForm){
var results = vaForm.ruleOrder.map(ruleType=>{
var rule = vaForm.rules[ruleType]
return this.checkRule(vaForm,rule)
})
var errIndex = null
for(var i = 0;i var result = results[i]
if(result.isPass === false){
errIndex = i
break
}
}
if(errIndex === null){
return new DisplayResult(true, vaForm.correctMsg)
}else{
return new DisplayResult(false, results[errIndex].errMsg)
}
}
//革新vaForm中的值的数据
function refreshValue(field, newValue){
this.forms[field].value = newValue + ''
}
//更新一切表单的值
function refreshAllValue(){
this.fieldOrder.forEach(field=>{
var vaForm = this.forms[field]
vaForm.value = vaForm.dom.value
})
}
// 校验一切的表单,并弹出第一个毛病。斟酌能够为空的状况
function checkAll(){
var firstErr = null
this.fieldOrder.forEach(field=>{
var vaForm = this.forms[field]
var canNull = vaForm.ruleOrder.every(ruleType=>ruleType !== 'NonEmpty') //输入框能够为空
var noCheckEmpty = (vaForm.value === '' && canNull) //该输入框能够为空,且输入为空
if(vaForm.noCheck === false && noCheckEmpty === false){
var result = this.setVmResult(field)
// var result = this.validate(field)
// this.vmResult[field] = result
// vaForm.validated = true
if(firstErr === null && result.isPass === false){
firstErr = result.message
}
}
})
return firstErr
}
//考证单个字段,返回值,并弹出报错
function setVmResult(field){
var result = this.validate(field) //本输入框效果
this.vmResult[field] = result //将报错弹出
this.forms[field].validated = true //校验过了
return result
}
// 返回各个表单的值对象
function getValue(){
var dataSet = {}
for(var field in this.forms){
dataSet[field] = this.forms[field].value
}
return dataSet
}
//增加一个划定规矩
function addRule(field, index, Rule){
var vaForm = this.forms[field]
vaForm.ruleOrder.splice(index, 0, Rule.ruleType)
vaForm.rules[Rule.ruleType] = Rule
}
// function resetAll(){
// this.fieldOrder.forEach(field=>{
// this.refreshValue(field, '')
// })
// }
// 设置不校验的表单
function setNoCheck(field, bool){
this.forms[field].noCheck = bool
}
function createVa(vm, field){
var va = {
vmResult:vm.va,
fieldOrder:[],
forms:{},
group:{
base:[],
},
equalGroup:{}, //必需相称的字段
uniqueGroup:{}, //必需差别的字段
Rule:Rule, //Rule组织器
VaForm:VaForm, //VaForm组织器
validate: validate, //暴露的校验函数
setVmResult: setVmResult, //校验并报错
checkRule: checkRule, //内部的校验单条划定规矩的函数
checkForm: checkForm, //内部的校验单个表单的函数
refreshValue: refreshValue, //更新某个表单的值
checkAll: checkAll, //搜检一切的函数
getValue: getValue, //猎取一切表单的当前值,获得一个对象
setNoCheck:setNoCheck, //设置为不校验
addRule:addRule, //给一个表单增加一个划定规矩
refreshAllValue:refreshAllValue //更新一切表单的值
// resetAll: resetAll
}
if(vm.$va){
return vm.$va
}else{
vm.$va = va
return va
}
}
//v-va:Password.canNull = "[{reg:/^\d{4}$/}]"
//arg = Password, modifiers.canNull = true, value为背面相干的
//arg用来存字段名, modifiers用来存特别设置, value为划定规矩, tag是中文提醒名, group 为分组
var main = {}
main.install = function(_Vue, options){
Vue = _Vue
Vue.directive('va',{
bind:function(el, binding, vnode){
var vm = vnode.context //当前的vue实例
var field = binding.arg === 'EXTEND' ? el.getAttribute('name') : binding.arg // 当arg为EXTEND,从name属性取得值
var option = binding.modifiers //特别设置(许可非空,编辑新增共用等)
var value = el.value //输入框的初始值
var group = el.getAttribute('group') || 'base' //分组,一个表单框在多个组呢?这个还没设,要兼容。 经由历程相似 'group1 group2 group3 group4'
var tag = el.getAttribute('tag')
var regMsg = el.getAttribute('regMsg') || '' //针对正则的自定义报错
var baseRule = [] //默许的校验划定规矩 --不必写,默许存在的划定规矩(如非空),优先级最高
var customRule = [] //用户自定义的划定规矩(组件中) --bingding.value
var optiOnalRule= [] //设置项中引伸出来的划定规矩,优先级最低
assert(tag, '未设置输入框的tag')
assert(vm.va, '实例的data选项上,未设置va对象') //实例上假如没有设置效果则报错。
assert(field, '未设置输入框字段')
var va = createVa(vm, field) //单例形式建立va,绑定在vm上
va.fieldOrder.push(field) //字段的磨练递次
va.group[group].push(field) //分组
var NOnEmpty= new Rule('NonEmpty', true, '')
//默许非空
if(option.CanNull === undefined){
baseRule.push(NonEmpty)
}
//假如regList里有name对应的,直接就加进optionalConfig
if(regList[field]){
optionalRule.push(new Rule('reg', regList[field], regMsg))
}
//假如modefiers中的字段有在正则内外,将其到场optionalRule
var regOptiOns= Object.keys(option);
for(var i = 0;i var regOption = regOptions[i]
if(regList[regOptions[i]]){
optionalRule.push(new Rule('reg', regList[regOption], regMsg))
}
}
//用户自定义的划定规矩
if(binding.value !== undefined){
customRule = binding.value.map(item=>{
var ruleType = Object.keys(item)[0];
var errMsg = ruleType === 'reg' ? regMsg : ''
return new Rule(ruleType, item[ruleType], errMsg)
})
}
var finalRules = mergeRule(baseRule, optionalRule, customRule)
var hasUniqueRule = false
//春团结校验的举行预处置惩罚
finalRules.forEach(rule=>{
var {ruleType, ruleValue} = rule
if(ruleType === 'equal'){
if(va.equalGroup[ruleValue] === undefined){
va.equalGroup[ruleValue] = [field]
}else{
va.equalGroup[ruleValue].push(field)
}
}
if(ruleType === 'unique'){
hasUniqueRule = ruleValue
if(va.uniqueGroup[ruleValue] === undefined){
va.uniqueGroup[ruleValue] = [field]
}else{
va.uniqueGroup[ruleValue].push(field)
}
}
})
var vaForm = new VaForm(el, finalRules, option)
va.forms[field] = vaForm
if(checkWhenChange){
function validateSingle(){
va.refreshValue(field, el.value) //更新值
//假如许可为空的此时为空,不校验
if(vaForm.value === '' && option.CanNull){
va.vmResult[field] = {} //假如为空,把界面显现上面的提醒清掉
return
}
if(vaForm.noCheck === false){
va.setVmResult(field)
}
var isEqualTarget = false
for(var index in va.equalGroup){
if(index === field){
isEqualTarget = true
}
}
//相称框的团结校验
if(isEqualTarget){
va.equalGroup[field].forEach(item=>{va.setVmResult(item)})
}
//差别框的团结校验
if(hasUniqueRule){
va.uniqueGroup[hasUniqueRule].forEach(item=>{va.setVmResult(item)})
}
}
//在change和blur上都绑定了处置惩罚事宜
el.addEventListener('change', validateSingle)
el.addEventListener('blur', validateSingle)
}
},
})
}
export default main

如今项目已用起来了。固然表单考证这类是高度定制化的。地道分享个历程和思绪。也算我这个vue新手的一次阶段性效果吧。哈哈~

运用实例

《va.js——Vue 表单考证插件的写作历程》

第一个框,加了两条指令

  1. v-va:Password 这个代表运用设置表中password对应的设置(包含非空和正则,默许划定规矩),同时运用Password作为校验胜利猎取的 数据对象的key

  2. tag为报错显现中此输入框的名字

第二个框,为确认框,也加了两个指令
1.v-va:checkPassword.Password = &#8220;[{&#8216;equal&#8217;:&#8217;Password&#8217;}]&#8221;
平常v-va背面的第一个字段为数据对象的key,他和正则对应的名字有能够差别。
这个字段假如和设置表中的设置婚配,那末天然运用设置。
假如不婚配,就要本身在背面用.的体式格局加设置(选项划定规矩)。像这里的Password。

最背面另有一个 属性值 &#8220;[{&#8216;equal&#8217;:&#8217;Password&#8217;}]&#8221;(自定义划定规矩)。
这个处所用了数组,即会按这个数组的设置来举行校验。
同时这个数组有递次,递次代表划定规矩的优先级。
这个设置代表,这个框必需和上面谁人Password的框值相称,不然报错。
别的确认框不到场末了的效果数据对象。

2.tag 用来作为报错信息的名字

校验触发按钮 上面有一个指令 v-va-check
1.用来触发校验
2.校验胜利后,将数据对象存在实例的vaVal属性下

依据上面的实例

划定规矩的优先级:
1.自定义划定规矩 > 选项划定规矩 > 默许划定规矩
2.划定规矩中的优先级遵照数组递次

别的,能够看到为了运用者轻易,我在我们团队中事前做了一些商定,并能够会用到 v-va、v-va-check、tag等指令,占用了实例的两个属性名vaConfig、vaVal。这些商定和设置能够使运用者运用轻易(经由历程设置掌握校验机遇, 校验胜利后天然天生经由历程的数据对象,自定义报错信息等等)。然则也减少了这个插件的普适性。

此计划仅供应列位做思绪参考。个人认为,表单考证是高度定制化的需求,只管依据各个营业状况举行弃取。在我的计划中,并不像vue-validator一样做了脏校验。


推荐阅读
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • 本文总结了在编写JS代码时,不同浏览器间的兼容性差异,并提供了相应的解决方法。其中包括阻止默认事件的代码示例和猎取兄弟节点的函数。这些方法可以帮助开发者在不同浏览器上实现一致的功能。 ... [详细]
  • Vue基础一、什么是Vue1.1概念Vue(读音vjuː,类似于view)是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不 ... [详细]
  • 获取时间的函数js代码,js获取时区代码
    本文目录一览:1、js获取服务器时间(动态)2 ... [详细]
  • 媒介本文的前身是源自github上的项目awesome-github-vue,但由于该项目上次更新时候为2017年6月12日,许多内容早已逾期或是许多近期优异组件未被收录,所以小肆 ... [详细]
  • fileuploadJS@sectionscripts{<scriptsrc~Contentjsfileuploadvendorjquery.ui.widget.js ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • java程序设计试题_《Java语言程序设计》期末考试模拟试题——填空题和编程题...
    一、根据题意,填写出空格中的内容Java平台包括三个技术方向,其中J2ME代表____________、J2SE代表___________、J2EE代表 ... [详细]
  • ①页面初始化----------收到客户端的请求,产生相应页面的Page对象,通过Page_Init事件进行page对象及其控件的初始化.②加载视图状态-------ViewSta ... [详细]
  • KVC:Key-valuecodingisamechanismforindirectlyaccessinganobject’sattributesandrelations ... [详细]
author-avatar
南阳啸68
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有