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

做企业网站的尺寸是多少站长素材官网免费

做企业网站的尺寸是多少,站长素材官网免费,制作网站模板,wordpress模板获取数据最近在研究各个框架的源码,从源码角度去理解 vue3 的 reactive 和 ref API,记录下研究的成果 reactive 首先,reactive() 的参数必须是一个对象,返回值是一个 Proxy 对象,具有响应性。如果参数不是对象类型&#xff0…

最近在研究各个框架的源码,从源码角度去理解 vue3 的 reactive 和 ref API,记录下研究的成果

reactive

首先,reactive() 的参数必须是一个对象,返回值是一个 Proxy 对象,具有响应性。如果参数不是对象类型,会提示:value cannot be made reactive。
多次对同一个对象使用 reactive 进行代理,返回的是相同的代理对象,也就是说使用的是缓存的值。而且,取值时直接读取属性就行,不需要加 .value 。
例子:

import { reactive } from 'vue'
const state = reactive({ count: 0 })
console.log(state.count) // 0const name = reactive('hh')
console.log('name', name) // warn: value cannot be made reactive: hhconst raw = {}
const proxy = reactive(raw)
console.log(proxy === raw) // false
// calling reactive() on the same object returns the same proxy
console.log(reactive(raw) === proxy) // true
// calling reactive() on a proxy returns itself
console.log(reactive(proxy) === proxy) // true

接下来说下 reactive 的局限性。
首先,参数只支持 object 类型 (比如 objects, arrays, Map, Set),不支持基础数据类型,比如string, number 或boolean;
其次,对变量重新赋值会丢失响应性,比如:

let state = reactive({ count: 0 })
// the above reference ({ count: 0 }) is no longer being tracked
// (reactivity connection is lost!)
state = reactive({ count: 1 })

而且,解构赋值容易丢失响应性:

const state = reactive({ count: 0 })// count is disconnected from state.count when destructured.
let { count } = state
// does not affect original state
count++

这种情况下,我们可以使用 toRefs 函数来将响应式对象转换为 ref 对象

import { toRefs } from 'vue';const state = reactive({ count: 0 });
let { count } = toRefs(state);
count++; // count 现在是 1

ref

再来看下 ref() 。reactive 和 ref 都是声明响应式变量的写法,但是,ref 的参数既可以是基本数据类型的值,也可以是对象,很自由!这就是为什么我们在开发时更推荐使用 vue3 的 ref 的原因了。
而且,ref 声明的变量在取值时必须加上 .value,而在 template 调用时中不加。
例子:
再来看下 ref() 。reactive 和 ref 都是声明响应式变量的写法,但是,ref 的参数既可以是基本数据类型的值,也可以是对象,很自由!这就是为什么我们在开发时更推荐使用 vue3 的 ref 的原因了。
而且,ref 声明的变量在取值时必须加上 .value,而在 template 调用时中不加。
例子:

const {ref, effect} = Vueconst name = ref('张三')
console.log('name', name.value) // name 张三const state = ref({ count: 0 })
console.log('state', state.value.count) // state 0

ref 源码

深入源码看下为什么。

ref() 中调用的是 createRef(value, false),在这个函数中,首先判断属性 __v_isRef 是否为 true,为 true 说明是 Ref 类型的值,直接返回;否则,返回的是 RefImpl 类的实例。

类的 get 和 set

再来看 RefImpl 类,重点是类中定义了 get 函数和 set 函数。当我们对类实例的 value 属性取值和赋值时,就会触发这两个函数。

// ref.tsexport function ref(value?: unknown) {return createRef(value, false)
}function createRef(rawValue: unknown, shallow: boolean) {// 判断属性 __v_isRef 是否为 true,为 true 说明是 Ref 类型的值,直接返回if (isRef(rawValue)) {return rawValue}return new RefImpl(rawValue, shallow)
}export function isRef(r: any): r is Ref {return !!(r && r.__v_isRef === true)
}class RefImpl<T> {private _value: Tprivate _rawValue: T// 依赖项public dep?: Dep = undefined// 属性 __v_isRef 设置为 truepublic readonly __v_isRef = trueconstructor(value: T, public readonly __v_isShallow: boolean) {this._rawValue = __v_isShallow ? value : toRaw(value)this._value = __v_isShallow ? value : toReactive(value)}get value() {// 依赖收集trackRefValue(this)// 返回值return this._value}set value(newVal) {const useDirectValue =this.__v_isShallow || isShallow(newVal) || isReadonly(newVal)newVal = useDirectValue ? newVal : toRaw(newVal)if (hasChanged(newVal, this._rawValue)) {this._rawValue = newValthis._value = useDirectValue ? newVal : toReactive(newVal)triggerRefValue(this, newVal)}}
}

举个例子理解下类中的 get 和 set 函数:

class RefImpl {// ref实例的getter行为get value () {console.log('get');return '111'}// ref实例的setter行为set value (val) {console.log('set');}
}const ref = new RefImpl()ref.value = '123'
ref.value

这里定义了 RefImpl 类,当我们对 ref.value 赋值时,会打印 set;当我们调用 ref.value 时,会打印 get。因此,我们不难理解为什么 Vue3 的 ref() 要加上 .value 了,因为也是使用了类中的 getter 和 setter 的写法。
此外,ref() 最终的返回值是 this._value,我们再来看下这部分的代码。这里是判断属性 __v_isShallow 是否为 true,为true 则直接返回,否则经过 toReactive() 处理下再返回。

this._value = __v_isShallow ? value : toReactive(value)

toReactive()

看下这个函数发生了什么。可以看到,如果参数是对象类型,则使用 reactive() 处理一下并返回;否则直接返回这个参数。
而 reactive() 中,我们是返回一个对象的 Proxy 对象,这个 Proxy 对象具有响应性,可以监听到我们对对象属性的读取和修改。值得一提的是,这里的 reactive() 正是 上面说到的声明响应性变量的 reactive() !也就是说,ref 的底层也用到了 reactive() ,二者是相通的,只不过 ref 多包装了一层,支持了基本数据类型的值。

// reactive.ts/*** Returns a reactive proxy of the given value (if possible).** If the given value is not an object, the original value itself is returned.** @param value - The value for which a reactive proxy shall be created.*/
export const toReactive = <T extends unknown>(value: T): T =>isObject(value) ? reactive(value) : value/*** Returns a reactive proxy of the object.** The reactive conversion is "deep": it affects all nested properties. A* reactive object also deeply unwraps any properties that are refs while* maintaining reactivity.** @example* ```js* const obj = reactive({ count: 0 })* ```** @param target - The source object.* @see {@link https://vuejs.org/api/reactivity-core.html#reactive}*/
export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
export function reactive(target: object) {// if trying to observe a readonly proxy, return the readonly version.if (isReadonly(target)) {return target}return createReactiveObject(target,false,mutableHandlers,mutableCollectionHandlers,reactiveMap)
}

createReactiveObject()

看下响应性是如何实现的。

首先,在 createReactiveObject() 函数中,如果传参 target 是非对象类型的,会提示并直接返回,我们之前的例子中也观察到这种现象了;
其次,判断 target 是否是 Proxy 或者已经存在哈希表 proxyMap 中,如果是直接返回;

最后,如果传参只是一个普通的对象,我们需要使用 new Proxy() 将其转化为一个 Proxy 对象,我们知道在 Vue3 中响应性的实现正是通过 Proxy 去实现的。生成 Proxy 对象后,存入 proxyMap 中,并返回该 Proxy 对象即可。

function createReactiveObject(target: Target,isReadonly: boolean,baseHandlers: ProxyHandler<any>,collectionHandlers: ProxyHandler<any>,proxyMap: WeakMap<Target, any>
) {if (!isObject(target)) {if (__DEV__) {console.warn(`value cannot be made reactive: ${String(target)}`)}return target}// target is already a Proxy, return it.// exception: calling readonly() on a reactive objectif (target[ReactiveFlags.RAW] &&!(isReadonly && target[ReactiveFlags.IS_REACTIVE])) {return target}// target already has corresponding Proxyconst existingProxy = proxyMap.get(target)if (existingProxy) {return existingProxy}// only specific value types can be observed.const targetType = getTargetType(target)if (targetType === TargetType.INVALID) {return target}const proxy = new Proxy(target,targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers)proxyMap.set(target, proxy)return proxy
}

小结:
createReactiveObject 函数,即 reactive 函数,最终是将传参的对象转化为一个 Proxy 对象并返回,而 Vue3 中响应性的实现正是通过 Proxy 去实现的。


文章转载自:

http://bV90llHu.bqpgq.cn
http://W85A3e9c.bqpgq.cn
http://zC1cb4BT.bqpgq.cn
http://0oyikZL7.bqpgq.cn
http://Bi325OEb.bqpgq.cn
http://yZeYVfwZ.bqpgq.cn
http://sp6Zflql.bqpgq.cn
http://B3fJSTjg.bqpgq.cn
http://0nuNEFvM.bqpgq.cn
http://0v30Ll9Z.bqpgq.cn
http://pVH080Q6.bqpgq.cn
http://h4KWP0EP.bqpgq.cn
http://ZXSipFJ9.bqpgq.cn
http://xpeoeGKz.bqpgq.cn
http://pYBHRESb.bqpgq.cn
http://bk0wP8iS.bqpgq.cn
http://cVNwhvNs.bqpgq.cn
http://wGMJvsHq.bqpgq.cn
http://59zw8Thp.bqpgq.cn
http://wKAyTFGu.bqpgq.cn
http://eoXPD4Hd.bqpgq.cn
http://pkCnet50.bqpgq.cn
http://Nisa0yR1.bqpgq.cn
http://4VJQXRXv.bqpgq.cn
http://szatLLu1.bqpgq.cn
http://mQhBihj5.bqpgq.cn
http://ZZEdDsHs.bqpgq.cn
http://A7WEHFRL.bqpgq.cn
http://oMhDFEW4.bqpgq.cn
http://pISe6cPU.bqpgq.cn
http://www.dtcms.com/wzjs/753861.html

相关文章:

  • 数码网站建设总体目标推广计划表格
  • 网站自适应屏幕云服务器可以用来做网站么
  • seo网站优化平台芜湖的网站建设公司
  • 海外网站建设推广app开发软件外包
  • 美容加盟网站建设注册公司那家网站做的比较好
  • 网站首页动画代码网站查外链
  • 简单的网站注册流程图大同市建设工程招标投标网站
  • 小榄网站长沙网络公司排行榜
  • 万网企业邮箱登陆界面如何嵌入到自己的网站做网站都需要买什么
  • 什么样的网站利于优化网站开发最新流程
  • 免费crm系统下载杭州seo搜索引擎优化公司
  • 杭州市城乡规划局建设局官方网站专业教育网站建设
  • 有了域名和空间怎么做网站内容太原专业做网站
  • 模拟ip访问网站深圳网站建设网站设计软文推广
  • 卓业网站建设优化营商环境存在问题及整改措施
  • 做网站用哪个写比较好网站免费正能量下载
  • 怎样构建网站建设摩托125图片大全
  • 广东省住房和城乡建设厅网站首页网站建设与管理实训报告
  • 小学科学可以做实验的网站网络设计工作好找吗
  • 移动商务网站开发课程基于node网站毕设代做
  • 住房与建设部网站首页wordpress注册带密码
  • 网站的空间价格吸引人的公众号名称大全
  • 找网站开发郑州互联网seo
  • 怎么看网站哪个公司做的新建的网站必须要备案吗
  • 网站访客网站建设邀请招标书
  • 那个网站做生鲜电子商务网站建设结构分析
  • 河北seo网站优化公司wordpress头像不同步
  • 怎么通过微博做网站外链sogou网站提交
  • 做短租类型的网站网站定制报价表
  • 域名交易网站诚信建设网站的作用