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

闵行网站开发可以营销的十大产品

闵行网站开发,可以营销的十大产品,wordpress备案号修改,做网站采集内容文章背景 vue项目开发过程中,首先会有一个初始化的流程,以及我们会使用到很多全局的api,如 this.$set this.$delete this.$nextTick,以及初始化方法extend,initUse, initMixin , initExtend, initAssetRegisters 等等那它们是怎么实现,让我们一起来探究下吧 源码目录 global-…文章背景 vue项目开发过程中,首先会有一个初始化的流程,以及我们会使用到很多全局的api,如 this.$set this.$delete this.$nextTick,以及初始化方法extend,initUse, initMixin , initExtend, initAssetRegisters 等等那它们是怎么实现,让我们一起来探究下吧 源码目录 global-api代码初始化 代码路径 src\vue-2.6.14\src\core\global-api\index.js 代码分析 vue挂载的全局属性 vue.util 公共方法 warn 代码警告处理 extend 将源数据中的值拷贝到目标数据中 mergeOptions 合并选项 defineReactive 定义响应式数据 set set 方法修改对象的某个属性以更新视图del del 方法删除数组的某个索引下的数据 或者 对象的某个属性nextTick nextTick方法observable 调用observer类的observe方法将对象变为响应式对象,并且返回该响应式对象options vue的一些选项 初始化方法 extend extend函数此处用于扩展,将源数据中的值拷贝到目标数据中数据类型兼容到了 对象和数组 initUse 初始化插件 initMixin 初始化混入 逻辑有点多后期详细补充 initExtend 构造一个vue的子类 initAssetRegisters(Vue) 注册或者获取全局组件、指令、过滤器 /* flow */import config from ../config import { initUse } from ./use import { initMixin } from ./mixin import { initExtend } from ./extend import { initAssetRegisters } from ./assets import { set, del } from ../observer/index import { ASSET_TYPES } from shared/constants import builtInComponents from ../components/index import { observe } from core/observer/indeximport {warn,extend,nextTick,mergeOptions,defineReactive } from ../util/index export function initGlobalAPI(Vue: GlobalAPI) {// note 初始化全局api sjf-step2debuggerconst configDef {}configDef.get () config// 初始化vue的全局config配置if (process.env.NODE_ENV ! production) {configDef.set () {// set在修改对象的字段时触发此处表示在设置 Vue的config属性时触发warn(Do not replace the Vue.config object, set individual fields instead.)}//在开发环境中不允许替换整个Vue.config 对象只允许设置单独的字段}Object.defineProperty(Vue, config, configDef)// // exposed util methods.// NOTE: these are not considered part of the public API - avoid relying on// them unless you are aware of the risk.Vue.util {//将全局方法挂载到Vue的util方法上warn,extend,mergeOptions,defineReactive}Vue.set set// set 方法修改对象的某个属性以更新视图Vue.delete del // del 方法删除数组的某个索引下的数据 或者 对象的某个属性Vue.nextTick nextTick // nextTick方法// set delete nextTick 除了可以使用 this.$set,this.$delete,this.$nextTick调用亦可以在Vue实例上直接调用// 2.6 explicit observable APIVue.observable (obj) {observe(obj)// 调用observer类的observe方法将对象变为响应式对象return obj//并且返回该响应式对象}Vue.options Object.create(null)//调用 Object.create(null) 创建一个没有原型链的空对象ASSET_TYPES.forEach(type {Vue.options[type s] Object.create(null)})// ASSET_TYPES [component,directive,filter] // 遍历ASSET_TYPES数组给Vue.options添加三个属性分别是components,directives,filters// this is used to identify the base constructor to extend all plain-object// components with in Weexs multi-instance scenarios.Vue.options._base Vue// 将vue赋值给Vue.options._base用于在weex的多实例场景下标识“基础”构造函数以扩展所有纯对象组件extend(Vue.options.components, builtInComponents)// 将builtInComponents对象的属性复制到Vue.options.components上// extend函数此处用于扩展initUse(Vue)//初始化插件initMixin(Vue)//初始化混入 逻辑有点多后期详细补充initExtend(Vue)//构造一个vue的子类 initAssetRegisters(Vue) // 注册或者获取全局组件、指令、过滤器 } extend 扩展数据 代码路径 src\vue-2.6.14\src\shared\util.jsextend函数此处用于扩展,将源数据中的值拷贝到目标数据中数据类型兼容到了 对象和数组入参说明 to 目标值,_from 源数据 核心代码说明 const key in _from _from 可以是一个数组 也可以是一个对象 如果是数组,则key是数组的索引 如果是对象,则key是对象的键值 export function extend (to: Object, _from: ?Object): Object {// sjf-note-best-code// 将源数据中的值拷贝到目标数据中数据类型兼容到了 对象和数组for (const key in _from) {// const key in _from // _from 可以是一个数组 也可以是一个对象// 如果是数组,则key是数组的索引// 如果是对象,则key是对象的键值to[key] _from[key]}//当我们还在苦逼地用 Array.isArray 判断数据类型是否是数组来区分代码写两套逻辑时, vue源代码已经实现了,一个代码同时兼容了数组和对象的拷贝,简直不要太优秀啊return to }优秀代码设计思想 当我们还在苦逼地用 Array.isArray 判断数据类型是否是数组来区分代码写两套逻辑时, vue源代码已经实现了,一个代码同时兼容了数组和对象的拷贝,简直不要太优秀啊 initUse 初始化插件 代码路径 src\vue-2.6.14\src\core\global-api\use.js入参说明plugin 参数 有可能是函数也有能是对象 当是对象时需要访问install属性并且使用apply修改this为plugin后调用 当是函数时则直接调用 核心代码说明installedPlugins 定义 installedPlugins 参数, 读取vue实例上的_installedPlugins属性,如果读取不到则赋值为空数组 缓存插件将插件添加到已安装插件的数组中 防止插件的重复加载 如果插件已经安装,则将插件直接返回 import { toArray } from ../util/indexexport function initUse (Vue: GlobalAPI) {Vue.use function (plugin: Function | Object) {const installedPlugins (this._installedPlugins || (this._installedPlugins []))// _installedPlugins 函数内部的变量 用来存储已经注册的插件// _installedPlugins 不存在时初始化为一个空数组// vue源码中并没有声明 _installedPlugins 并且此处是非箭头函数if (installedPlugins.indexOf(plugin) -1) {// 防止插件的重复加载return this}const args toArray(arguments, 1)// toArray 方法将参数转化为数组// arguments 是一个类数组对象有length属性但是没有数组的方法// 通过toArray方法将arguments转化为数组并且去掉第一个参数args.unshift(this)//再将this添加到args数组的头部if (typeof plugin.install function) {// 如果插件有install方法则调用install方法plugin.install.apply(plugin, args)} else if (typeof plugin function) {// 如果插件是一个函数则直接调用plugin.apply(null, args)}installedPlugins.push(plugin)//缓存插件将插件添加到已安装插件的数组中return this} }initMixin 初始化混入 初始化混入 逻辑有点多后期单独出一篇文章详细补充 initExtend 初始化vue组件对象 代码路径 src\vue-2.6.14\src\core\global-api\extend.js 函数说明基于构造函数Vue,创建了一个Vue组件对象,并初始化vue选项式api 核心代码说明获取父类的cid,也就是组件的id,即组件的标识cachedCtors,定义一个缓存对象 如果缓存对象中已经有了当前类的id,则表明在此操作前已经创建过了 通过id访问到缓存对象中的子类,并直接返回 这样做可以提高性能,避免重复的子类创建 获取到组件的name属性 如果当前传入的组件选项中有name属性则直接读取,否则访问Super(父类的)name属性 name是组件的标识,一般确实永不到,但是组件递归的时候必须要写,否则无法调用子组件 调用validateComponentName校验name属性是否合法sub类的处理 通过函数的方式创建一个sub类并将父类的原型链继承到子类中原型链继承方式同时还需要修正constructor的指向 将父类的options字段和传入组件对象选项进行合并并保存在子类sub的options字段中 将父类保存到子类的 super 字段中确保子类能拿到父类 初始化 props props 是当前组件的props属性 const in props 遍历对象的属性 将 组件传入的props属性代理到组件实例的_props属性上初始化 computed computed 是当前组件的computed属性 const in props 遍历对象的属性 defineComputed 逻辑暂时没看,后期单独出一期文章补充 将 extend,mixin,use等api添加到子类中新增 superOptions,extendOptions,sealedOptions等选项将子类返回 /* flow */import { ASSET_TYPES } from shared/constants import { defineComputed, proxy } from ../instance/state import { extend, mergeOptions, validateComponentName } from ../util/indexexport function initExtend (Vue: GlobalAPI) {/*** Each instance constructor, including Vue, has a unique* cid. This enables us to create wrapped child* constructors for prototypal inheritance and cache them.*/// sjf-note-best-codeVue.cid 0//初始化cid为0 可以理解为组件的标识let cid 1 /*** Class inheritance*/Vue.extend function (extendOptions: Object): Function {// 基于构造函数Vue,创建了一个Vue组件对对象,并初始化vue选项式apiextendOptions extendOptions || {}// extendOptions是一个对象如果没有传入则初始化为空对象// extendOptions 是组件传入的选项const Super this//将thisvue的实例赋值给Superconst SuperId Super.cidconst cachedCtors extendOptions._Ctor || (extendOptions._Ctor {})//定义一个缓存对象用生成的id作为属性键如果cachedCtors[SuperId]存在则表明该组件的构造函数已经生成直接返回即可if (cachedCtors[SuperId]) {return cachedCtors[SuperId]}const name extendOptions.name || Super.options.name// extendOptions 当前组件的选项 的 // Super 是 Vue的实例 options 是Vue的选项// 如果传入了extendOptions.name 则使用extendOptions.name 否则使用Super.options.nameif (process.env.NODE_ENV ! production name) {//判断是否是开发环境validateComponentName(name)//校验组件名称是否合法 如果不合法会抛出异常}const Sub function VueComponent (options) {this._init(options)//此处的this是vue实例 调用了_init方法初始化组件实例}Sub.prototype Object.create(Super.prototype)// Super.prototype 是Vue的原型对象// Object.create(Super.prototype) 创建了一个新的对象该对象的原型是Super.prototype// Object.create() 方法创建一个新对象不会有原型链上的属性和方法Sub.prototype.constructor Sub// consturctor指向自身 sjf-todo// 通过函数的方式创建一个sub类并将父类的原型链继承到子类中原型链继承方式同时还需要修正constructor的指向Sub.cid cid//组件的cid自增1Sub.options mergeOptions(//将父类的options字段和传入组件对象选项进行合并并保存在子类sub的options字段中Super.options,//Vue的选项extendOptions//当前组件的选项)Sub[super] Super//将Super(根组件的实例)赋值给当前组件的super属性 // 将父类保存到子类的 super 字段中确保子类能拿到父类// For props and computed properties, we define the proxy getters on// the Vue instances at extension time, on the extended prototype. This// avoids Object.defineProperty calls for each instance created.if (Sub.options.props) {//如果当前组件有props属性则初始化propsinitProps(Sub) }if (Sub.options.computed) {//如果当前组件有computed属性则初始化computedinitComputed(Sub)}// allow further extension/mixin/plugin usageSub.extend Super.extendSub.mixin Super.mixinSub.use Super.use // Vue的一些原生API 等扩展到子构造器上边// create asset registers, so extended classes// can have their private assets too.ASSET_TYPES.forEach(function (type) {Sub[type] Super[type]})// enable recursive self-lookupif (name) {Sub.options.components[name] Sub}// keep a reference to the super options at extension time.// later at instantiation we can check if Supers options have// been updated.Sub.superOptions Super.optionsSub.extendOptions extendOptionsSub.sealedOptions extend({}, Sub.options) // Vue的一些原生API 等扩展到子构造器上边// cache constructorcachedCtors[SuperId] Subreturn Sub} }function initProps (Comp) {const props Comp.options.props// props 是当前组件的props属性for (const key in props) { // const in props 遍历对象的属性proxy(Comp.prototype, _props, key)// proxy 代理数据// 此处是将 组件传入的props属性代理到组件实例的_props属性上} }function initComputed (Comp) {const computed Comp.options.computed// computed 是当前组件的computed属性for (const key in computed) {// const in computed 遍历对象的属性defineComputed(Comp.prototype, key, computed[key])// defineComputed 代理数据// 此处是将 组件传入的computed属性代理到组件实例的_props属性上} } initAssetRegisters 注册或者获取全局组件、指令、过滤器 src\vue-2.6.14\src\core\global-api\assets.js 函数说明注册或者获取全局 component 组件、directive指令、 filter 过滤器 函数入参说明id 标识名称iddefinition 定义类型是函数或者对象 当type 是directive或者filter的时候,是函数 当type是components的时候是,对象 核心代码说明 判断是是否有传入 definition 参数 无则表明不是注册全局组件、指令、过滤器,而直接读取,直接通过标识名称id读取返回即可 有则标明是注册 校验组件名是否合规 非生产环境 并且type值是component组件名称,则需要校验组件名是否合规 如果不合规则在 validateComponentName函数中抛出异常,下文有说明 根据type类型分别做逻辑处理componenttype为 component,并且 isPlainObject 判断 definition类型是 object,则执行下边逻辑 读取 name 属性,如果读不到definition的name属性,则使用标识名称id 调用 vue 的extend扩展定义,并重新赋值 directive type值为 directive ,并且 definition的类型为 function 定义一个对象有bind和update属性,赋值为definition 以上逻辑处理好了directive和component选项下的definition,filter选项不需要特殊处理根据选项式api对象读取到指定id的component 组件、directive指令、 filter 过滤器并赋值为 definition将 definition返回给调用者 /* flow */import { ASSET_TYPES } from shared/constants import { isPlainObject, validateComponentName } from ../util/indexexport function initAssetRegisters (Vue: GlobalAPI) {/*** Create asset registration methods.*//* component,directive,filter*/ // 注册或者获取全局组件、指令、过滤器debuggerASSET_TYPES.forEach(type {//定义资源注册方法Vue[type] function (id: string,//标识名称iddefinition: Function | Object//定义函数或者对象 // 当type 是directive或者filter的时候,是函数// 当type是components的时候是,对象): Function | Object | void {// console.log(id_definition,type,id,definition)if (!definition) {// 没有传入definition 的时候,则之直接读取并返回return this.options[type s][id]} else {/* istanbul ignore if */if (process.env.NODE_ENV ! production type component) {// 非生产环境 交易案组件名称,如果不合规,则抛出异常validateComponentName(id)}if (type component isPlainObject(definition)) {definition.name definition.name || id//设置 definition.name属性 // 值为组件传入的name || iddefinition this.options._base.extend(definition)// 调用 vue 的extend扩展定义,并重新赋值}if (type directive typeof definition function) {definition { bind: definition, update: definition }// 自定义指令的处理逻辑}this.options[type s][id] definitionreturn definition}}}) }源码中使用到的小代码片段补充 ASSET_TYPES export const ASSET_TYPES [component,directive,filter ]proxy代理函数 代码引用地址 src\vue-2.6.14\src\core\instance\state.js使用defineProperty代理数据 const sharedPropertyDefinition {//代理数据的配置enumerable: true,//是否可枚举configurable: true,//是否可修改删除get: noop,//get方法用于读取数据 noop 定义一个临时的空的函数set: noop//set方法用于设置数据 noop 定义一个临时的空的函数 }export function proxy (target: Object, sourceKey: string, key: string) {// 代理数据sharedPropertyDefinition.get function proxyGetter () {return this[sourceKey][key] //返回数据}sharedPropertyDefinition.set function proxySetter (val) {this[sourceKey][key] val//设置数据}Object.defineProperty(target, key, sharedPropertyDefinition)// 通过Object.defineProperty方法将sharedPropertyDefinition的get和set方法绑定到target对象的key属性上 }toArray 将目标数组中的数据,从指定位置开始拷贝 代码引用地址 src\vue-2.6.14\src\shared\util.js将目标数组中的数据,从指定位置开始拷贝 代码实现原理 接收字段 list 源数据 start 从源数据的哪个位置开始拷贝 默认为 0 声明一个变量i值为 list.length - startwhile 循环 然后将 i start 则 最后的 i start 仍然等于 list.length 当i的值为0时循环结束 则实现了将原数组从指定位置拷贝到目标数组的操作 代码优秀设计思想分析,它凭什么优秀第一点,一般拷贝数组, 常规的操作就是 for 循环,遍历数组中的每一个数据,然后根据条件判断,将数组中满足条件的数据拿到或者将不满足条件的数据过滤掉,这样确实能够处理数据,但是却需要将每条数据都循环一遍 .优秀的写法 此处,使用了while循环,不需要循环每一条数据,在调件变量为false的时候就跳出了循环,提高了代码的执行效率 可拷贝从指定位置开始的数据语法层面上使用了 new Array(i) 创建了指定数组,并且指定了位数,同时生明其中的每个变量都为empty很多人都知道new Array 却不知道 可以传入个数参数 当我们还开为这中需求苦恼,并且写一堆js时,vue源码中已经写出来如此优秀的代码,值得参考 export function toArray (list: any, start?: number): Arrayany {// sjf-note-best-codestart start || 0let i list.length - startconst ret: Arrayany new Array(i)// new Array() 创建一个空数组// new Array(i) 创建i个为空的数组// 相当于 Array.fill(0,i,undefined)while (i--) {ret[i] list[i start]//先将 i list.length - start // 然后将 i start // 则 最后的 i start 仍然等于 list.length// 只不过是i 的值是从 list.length - start 到 0 递减// 当i的值为0时循环结束}// while循环的优点是即即使数组的数据没有处理完成并且不需要break或者return false 以及 throw new Error()来结束循环,就可以自动结束循环return ret// 将处理好的数组返回 }isPlainObject 代码引用地址 src\vue-2.6.14\src\shared\util.js判断 数据类型是否是 object export function isPlainObject (obj: any): boolean {return _toString.call(obj) [object Object] }validateComponentName 代码引用地址 src\vue-2.6.14\src\core\util\options.js校验组件名是否合法 export function validateComponentName (name: string) {if (!new RegExp(^[a-zA-Z][\\-\\.0-9_${unicodeRegExp.source}]*$).test(name)) {warn(Invalid component name: name . Component names should conform to valid custom element name in html5 specification.)}if (isBuiltInTag(name) || config.isReservedTag(name)) {// warn(Do not use built-in or reserved HTML elements as component id: name)} }isBuiltInTag 判断组件名是不是Vue内置的 引用地址 src\vue-2.6.14\src\shared\util.js export const isBuiltInTag makeMap(slot,component, true) // 判断组件名是不是内置的标签不是原生html的标签而是vue内置的标签isReservedTag - 判断是否是 原生html或者isSVG标签 export const isReservedTag (tag: string): ?boolean {return isHTMLTag(tag) || isSVG(tag) } export const isHTMLTag makeMap(html,body,base,head,link,meta,style,title, address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section, div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul, a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby, s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video, embed,object,param,source,canvas,script,noscript,del,ins, caption,col,colgroup,table,thead,tbody,td,th,tr, button,datalist,fieldset,form,input,label,legend,meter,optgroup,option, output,progress,select,textarea, details,dialog,menu,menuitem,summary, content,element,shadow,template,blockquote,iframe,tfoot ) export const isSVG makeMap(svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face, foreignobject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern, polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view,true )致谢 感谢vue源码给予了我学习借鉴的机会感谢日常项目中给我的锻炼这篇文章是vue初始化流程的代码,其实没什么难度,但是这是最开始的一步,无法跳过,后期会有核心代码的分析,如果感兴趣请关注 感谢您百忙之中抽时间阅读我写的博客谢谢你的肯定也希望对您能有所帮助如果您有更好的见解请在评论区留言或者私聊我期待与您的交流
http://www.hkea.cn/news/14331019/

相关文章:

  • 网站域名有效期网站备案归属地
  • 中国网站设计师wordpress如何修改评论
  • 怎样让google收录网站网站建设费计入 科目
  • 直接用ip做网站建设厅安全员证
  • 做水处理药剂的公司网站wordpress 手动安装主题
  • 小程序网站怎么做网站建设费税收分类
  • 苏州专业建设网站大学 两学一做专题网站
  • 南宁网站设计制作公司dw网页制作教程完整版
  • 牛商网 做的p2p网站网页制作设计思路
  • 个人做视频网站视频储存网站建设公司怎么做好
  • 湖北省市政工程建设官方网站安阳网站建设设计
  • 视频素材交易网站建设大连网站外包
  • 新乡网络网站建设Wordpress is快递 接口
  • 营销网站导航栏常见在那个上面做网站都能搜到
  • 网站模板 单页龙凤网站建设云聚达
  • 网站开发网页加载缓慢查询数据库慢用flash做网站超链接
  • 简述网站技术解决方案建外贸网站比较好的公司
  • 专业做房地产网站建设建设网站花费
  • 推荐的网站wordpress相关
  • 网站备案表格下载网站建设公司财务预算
  • 广州技术网站建设wordpress 修改程序文件
  • 潍坊知名网站建设价格低凡科建设网站别人能进去么
  • 建筑师网站有哪些移动互联网开发报告总结
  • 湖州建设局网站 项目验收流程做去自己的网站首页
  • 安顺建设局网站公司网站建设合同要交印花税吗
  • 济宁专业做优化的网站哈尔滨网站制作公司价格
  • 男的女的做那个的视频网站淘宝seo 优化软件
  • 网站开发一般会用到什么语言网站模板 静态模版
  • 个人网站制作wordpress网架公司排名
  • 高职专业建设管理网站创可贴在线设计平台