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

Php做网站创业信用网站建设意义

Php做网站创业,信用网站建设意义,微信公众号自定义菜单wordpress,美食网页模板免费下载文章目录 1. 前言2. initInjections函数分析resolveInject函数分析 3. 总结 1. 前言 本篇文章介绍生命周期初始化阶段所调用的第四个初始化函数——initInjections。从函数名字上来看#xff0c;该函数是用来初始化实例中的inject选项的。说到inject选项#xff0c;那必然离… 文章目录 1. 前言2. initInjections函数分析resolveInject函数分析 3. 总结 1. 前言 本篇文章介绍生命周期初始化阶段所调用的第四个初始化函数——initInjections。从函数名字上来看该函数是用来初始化实例中的inject选项的。说到inject选项那必然离不开provide选项这两个选项都是成对出现的它们的作用是允许一个祖先组件向其所有子孙后代注入一个依赖不论组件层次有多深并在起上下游关系成立的时间里始终生效。并且 provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的属性。在该对象中你可以使用 ES2015 Symbols 作为 key但是只在原生支持 Symbol 和 Reflect.ownKeys 的环境下可工作。 inject 选项应该是 一个字符串数组或一个对象对象的 key 是本地的绑定名value 是 在可用的注入内容中搜索用的 key (字符串或 Symbol)或一个对象该对象的 from 属性是在可用的注入内容中搜索用的 key (字符串或 Symbol)default 属性是降级情况下使用的 value 这两个选项在我们日常开发中使用的频率不是很高但是在一些组件库中使用的很频繁官方文档给出了使用示例如下 // 父级组件提供 foo var Parent {provide: {foo: bar},// ... }// 子组件注入 foo var Child {inject: [foo],created () {console.log(this.foo) // bar}// ... }利用 ES2015 Symbols、函数 provide 和对象 inject const s Symbol()const Provider {provide () {return {[s]: foo}} }const Child {inject: { s },// ... }接下来 2 个例子只工作在 Vue 2.2.1 或更高版本。低于这个版本时注入的值会在 props 和 data 初始化之后得到。 使用一个注入的值作为一个属性的默认值 const Child {inject: [foo],props: {bar: {default () {return this.foo}}} }使用一个注入的值作为数据入口 const Child {inject: [foo],data () {return {bar: this.foo}} }在 2.5.0 的注入可以通过设置默认值使其变成可选项 const Child {inject: {foo: { default: foo }} }如果它需要从一个不同名字的属性注入则使用 from 来表示其源属性 const Child {inject: {foo: {from: bar,default: foo}} }与 prop 的默认值类似你需要对非原始值使用一个工厂方法 const Child {inject: {foo: {from: bar,default: () [1, 2, 3]}} }总结起来一句话就是父组件可以使用provide选项给自己的下游子孙组件内注入一些数据在下游子孙组件中可以使用inject选项来接收这些数据以便为自己所用。 另外这里有一点需要注意provide 和 inject 选项绑定的数据不是响应式的。 了解了他们的作用及使用方法后我们就来看下initInjections函数是如何来初始化inject选项的。 2. initInjections函数分析 分析之前我们先说一个问题细心的同学可能会发现既然inject选项和provide选项都是成对出现的那为什么在初始化的时候不一起初始化呢为什么在init函数中调用initInjections函数和initProvide函数之间穿插一个initState函数呢 其实不然在官方文档示例中说了provide选项注入的值作为数据入口如下 const Child {inject: [foo],data () {return {bar: this.foo}} }这里所说的数据就是我们通常所写data、props、watch、computed及method所以inject选项接收到注入的值有可能被以上这些数据所使用到所以在初始化完inject后需要先初始化这些数据然后才能再初始化provide所以在调用initInjections函数对inject初始化完之后需要先调用initState函数对数据进行初始化最后再调用initProvide函数对provide进行初始化。 OK接下来我们就来分析initInjections函数的具体原理该函数定义位于源码的src/core/instance/inject.js中如下 export function initInjections (vm: Component) {const result resolveInject(vm.$options.inject, vm)if (result) {toggleObserving(false)Object.keys(result).forEach(key {defineReactive(vm, key, result[key])}toggleObserving(true)} }export let shouldObserve: boolean true export function toggleObserving (value: boolean) {shouldObserve value }可以看到initInjections函数的逻辑并不复杂首先调用resolveInject把inject选项中的数据转化成键值对的形式赋给result如官方文档给出的例子那么result应为如下样子 // 父级组件提供 foo var Parent {provide: {foo: bar} }// 子组件注入 foo var Child {inject: [foo], }// result result {foo:bar }然后遍历result中的每一对键值调用defineReactive函数将其添加当前实例上如下 if (result) {toggleObserving(false)Object.keys(result).forEach(key {defineReactive(vm, key, result[key])}toggleObserving(true) }此处有一个地方需要注意在把result中的键值添加到当前实例上之前会先调用toggleObserving(false)而这个函数内部是把shouldObserve false这是为了告诉defineReactive函数仅仅是把键值添加到当前实例上而不需要将其转换成响应式这个就呼应了官方文档在介绍provide 和 inject 选项用法的时候所提示的 provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而如果你传入了一个可监听的对象那么其对象的属性还是可响应的。 initInjections函数的逻辑就介绍完了接下来我们看看resolveInject函数内部是如何把inject 选项中数据转换成键值对的。 resolveInject函数分析 我们知道inject 选项中的每一个数据key都是由其上游父级组件提供的所以我们应该把每一个数据key从当前组件起不断的向上游父级组件中查找该数据key对应的值直到找到为止。如果在上游所有父级组件中没找到那么就看在inject 选项是否为该数据key设置了默认值如果设置了就使用默认值如果没有设置则抛出异常。 OK以上是我们的分析下面我们就来看下resolveInject函数的源码验证我们的分析源码如下 export function resolveInject (inject: any, vm: Component): ?Object {if (inject) {const result Object.create(null)const keys Object.keys(inject)for (let i 0; i keys.length; i) {const key keys[i]const provideKey inject[key].fromlet source vmwhile (source) {if (source._provided hasOwn(source._provided, provideKey)) {result[key] source._provided[provideKey]break}source source.$parent}if (!source) {if (default in inject[key]) {const provideDefault inject[key].defaultresult[key] typeof provideDefault function? provideDefault.call(vm): provideDefault} else if (process.env.NODE_ENV ! production) {warn(Injection ${key} not found, vm)}}}return result} }在分析函数源码之前我们对照着官网给出的示例这样会比较好理解一些。 var Parent {provide: {foo: bar},// ... } const Child {inject: {foo: {from: bar,default: () [1, 2, 3]}} }可以看到在函数源码中首先创建一个空对象result用来存储inject 选项中的数据key及其对应的值作为最后的返回结果。 然后获取当前inject 选项中的所有key然后遍历每一个key拿到每一个key的from属性记作provideKeyprovideKey就是上游父级组件提供的源属性然后开启一个while循环从当前组件起不断的向上游父级组件的_provided属性中父级组件使用provide选项注入数据时会将注入的数据存入自己的实例的_provided属性中查找直到查找到源属性的对应的值将其存入result中如下 for (let i 0; i keys.length; i) {const key keys[i]const provideKey inject[key].fromlet source vmwhile (source) {if (source._provided hasOwn(source._provided, provideKey)) {result[key] source._provided[provideKey]break}source source.$parent} }如果没有找到那么就看inject 选项中当前的数据key是否设置了默认值即是否有default属性如果有的话则拿到这个默认值官方文档示例中说了默认值可以为一个工厂函数所以当默认值是函数的时候就去该函数的返回值否则就取默认值本身。如果没有设置默认值则抛出异常。如下 if (!source) {if (default in inject[key]) {const provideDefault inject[key].defaultresult[key] typeof provideDefault function? provideDefault.call(vm): provideDefault} else if (process.env.NODE_ENV ! production) {warn(Injection ${key} not found, vm)} }最后将result返回。这就是resolveInject函数的所有逻辑。 此时你可能会有个疑问官方文档中说inject 选项可以是一个字符串数组也可以是一个对象在上面的代码中只看见了处理当为对象的情况那如果是字符串数组呢怎么没有处理呢 其实在初始化阶段_init函数在合并属性的时候还调用了一个将inject 选项数据规范化的函数normalizeInject该函数的作用是将以下这三种写法 // 写法一 var Child {inject: [foo] }// 写法二 const Child {inject: {foo: { default: xxx }} }// 写法三 const Child {inject: {foo} }统统转换成以下规范化格式 const Child {inject: {foo: {from: foo,default: xxx //如果有默认的值就有default属性}} }这样做的目的是不管用户使用了何种写法统统将其转化成一种便于集中处理的写法。 该函数的定义位于源码的src/core/util/options.js中如下 function normalizeInject (options: Object, vm: ?Component) {const inject options.injectif (!inject) returnconst normalized options.inject {}if (Array.isArray(inject)) {for (let i 0; i inject.length; i) {normalized[inject[i]] { from: inject[i] }}} else if (isPlainObject(inject)) {for (const key in inject) {const val inject[key]normalized[key] isPlainObject(val)? extend({ from: key }, val): { from: val }}} else if (process.env.NODE_ENV ! production) {warn(Invalid value for option inject: expected an Array or an Object, but got ${toRawType(inject)}.,vm)} }该函数的逻辑并不复杂如果用户给inject选项传入的是一个字符串数组写法一那么就遍历该数组把数组的每一项变成 inject:{foo:{from:foo} }如果给inject选项传入的是一个对象那就遍历对象中的每一个key给写法二形式的key对应的值扩展{ from: key }变成 inject:{foo:{from: foo,default: xxx} }将写法三形式的key对应的值变成 inject:{foo:{from: foo} }总之一句话就是把各种写法转换成一种规范化写法便于集中处理。 3. 总结 本篇文章介绍生命周期初始化阶段所调用的第四个初始化函数——initInjections。该函数是用来初始化inject选项的。 由于inject选项在日常开发中使用频率不高所以首先我们先根据官方文档回顾了该选项的作用及使用方法。 接着我们分析了initInjections函数的内部实现原理分析了是根据inject选项中的数据key是如何自底向上查找上游父级组件所注入的对应的值。 另外对inject选项的规范化函数normalizeInject也进行了分析Vue为用户提供了自由多种的写法其内部是将各种写法最后进行统一规范化处理。
http://www.zqtcl.cn/news/903669/

相关文章:

  • 外贸有哪些网站成都网络营销搜索推广优势
  • 国外mod大型网站财税公司
  • 一个很好的个人网站开发做一个简单网页多少钱
  • 东莞在哪里学网站建设网站建设团队与分工
  • 网站功能插件昆明网站建设技术研发中心
  • 网站开发培训中心 市桥移动端ui
  • 高碑店地区网站建设上海排名十大装潢公司
  • 无锡自助建站网站还是新能源专业好
  • pc 手机网站 微站如何建设与维护网站
  • 大学生兼职网站开发毕设论文杭州网络排名优化
  • 做教育机器网站网站建设的步骤图
  • 桔子建站是什么平台郑州公司注册网上核名
  • 网站开发技能有哪些网站建设艾金手指科杰
  • 网站建设挂什么费用网站建设学那些课
  • 网站定位与功能分析在互联网公司做网站
  • 安阳网站建设兼职做网站推广有哪些公司
  • 网站制作的一般过程怎么用手机搭建网站
  • 备案 网站名称 怎么改深圳建网站公司
  • html 企业网站模板网站策划书免费
  • 网站建设销售ppt拖拽建站系统源码
  • 网站托管费用多少网站的开发流程
  • 周到的商城网站建设北京品牌网站
  • 网站开发费用属于什么科目网站建设考试多选题
  • c asp做网站wordpress4.5.2文章采集
  • 百度网站建设电话建立网站站建设可以吗
  • 网站后台代码在哪修改网站如何做下一页
  • 网站开发职业要求百度推广代理商与总公司的区别
  • 西安网站建设中心网页 网 址网站区别
  • 技术支持东莞网站建设机械seo岗位是什么意思
  • 做商城网站需要备案什么域名硬件开发工具有哪些