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

这么自己建设网站学网络营销有用吗

这么自己建设网站,学网络营销有用吗,平面设计师推荐网站,常州外贸公司网站建设创建响应式对象 RefImpl方式 ref(data) 使用这个构造函数RefImpl创建的响应式对象有一个属性: __v_isReftrue。如果data是原始类型属性_value_rawValue,就是原始值。如果data是对象类型,那么就使用toReactive-->reactive(data) ,此时_va…

创建响应式对象

RefImpl方式

   ref(data)

      使用这个构造函数RefImpl创建的响应式对象有一个属性:  __v_isRef=true。如果data是原始类型属性_value=_rawValue,就是原始值。如果data是对象类型,那么就使用toReactive-->reactive(data) ,此时_value就是一个响应式对象。不会重复封装被ref()封装过的值,

    function ref(value) {return createRef(value, false);}//首先判断是不是Ref,如果是就直接返回,就是不做嵌套封装function createRef(rawValue, shallow) {if (isRef(rawValue)) {return rawValue;}return new RefImpl(rawValue, shallow);}//浅层代理,就是第一层属性function shallowRef(value) {return createRef(value, true);}
 /// ref构造函数class RefImpl {///__v_isShallow 是否是浅层代理,就是代理第一层constructor(value, __v_isShallow) {//__v_isShallow: 标记是否为浅层代理(仅代理第一层属性)this.__v_isShallow = __v_isShallow;this.dep = void 0;//判断是否是RefImpl对象的标识,如果是的话,那么就直接返回valuethis.__v_isRef = true;///_rawValue存放的时最原始的值,就是去掉了响应式代理的值,toRaw会递归去掉代理this._rawValue = __v_isShallow ? value : toRaw(value);//如果toReactive()方法判断如果value是一个object 那么就用reactive() 包装 否则返回原值//toReactive对于原始值 就直接返回value//如果是对象的话 就是Proxy代理了this._value = __v_isShallow ? value : toReactive(value);}get value() {///收集依赖 ReactiveEffect 副作用对象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)) {const oldVal = this._rawValue;this._rawValue = newVal;this._value = useDirectValue ? newVal : toReactive(newVal);triggerRefValue(this, 5, newVal, oldVal);}}}
 const toReactive = (value) => isObject(value) ? reactive(value) : value;

reactive(data)方式

     如果data是原始类型的数据,就直接返回了原始值,这个方式是不能创建基于原始类型数据的响应式对象的,原始类型的数据 需要通过RefImpl 类来创建 。不会重复封装被reactive()封装过的值

    function reactive(target) {//判断是否只读if (isReadonly(target)) {return target;}return createReactiveObject(target,false,mutableHandlers,//这个handler是下面的BaseReactiveHandler mutableCollectionHandlers,reactiveMap);}
 //target这个方法并没有判断 当前target是否是RefImpl类型
function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) {if (!isObject(target)) {{warn$2(`value cannot be made ${isReadonly2 ? "readonly" : "reactive"}: ${String(target)}`);}return target;}///如果本身是响应式数据 就有__v_raw __v_isReactive两个属性if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) {return target;}//proxyMap全局缓存,响应式数据const existingProxy = proxyMap.get(target);if (existingProxy) {return existingProxy;}///返回target 的类型 Object.prototype.toString.call()const targetType = getTargetType(target);if (targetType === 0 /* INVALID */) {return target;}//如果是集合类型就用collectionHandlers处理,其他的用baseHandlers处理const proxy = new Proxy(target,targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);proxyMap.set(target, proxy);return proxy;}
class BaseReactiveHandler {constructor(_isReadonly = false, _isShallow = false) {this._isReadonly = _isReadonly;this._isShallow = _isShallow;}get(target, key, receiver) {const isReadonly2 = this._isReadonly, isShallow2 = this._isShallow;///通过get 方法设置了几个属性的陷阱 __v_isReactive __v_isReadonly __v_isShallow//__v_raw 这个属性是返回最原始的值if (key === "__v_isReactive") {return !isReadonly2;} else if (key === "__v_isReadonly") {return isReadonly2;} else if (key === "__v_isShallow") {return isShallow2;} else if (key === "__v_raw") {if (receiver === (isReadonly2 ? isShallow2 ? shallowReadonlyMap : readonlyMap : isShallow2 ? shallowReactiveMap : reactiveMap).get(target) || // receiver is not the reactive proxy, but has the same prototype// this means the reciever is a user proxy of the reactive proxyObject.getPrototypeOf(target) === Object.getPrototypeOf(receiver)) {return target;}return;}const targetIsArray = isArray(target);if (!isReadonly2) {if (targetIsArray && hasOwn(arrayInstrumentations, key)) {return Reflect.get(arrayInstrumentations, key, receiver);}if (key === "hasOwnProperty") {return hasOwnProperty;}}const res = Reflect.get(target, key, receiver);if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {return res;}if (!isReadonly2) {track(target, "get", key);}if (isShallow2) {return res;}if (isRef(res)) {return targetIsArray && isIntegerKey(key) ? res : res.value;}if (isObject(res)) {return isReadonly2 ? readonly(res) : reactive(res);}return res;}}

使用reactive() 方法创建的对象有一个这个属性 __v_reactive

Proxy代理对象创建

 class BaseReactiveHandler {constructor(_isReadonly = false, _isShallow = false) {this._isReadonly = _isReadonly;this._isShallow = _isShallow;}get(target, key, receiver) {const isReadonly2 = this._isReadonly, isShallow2 = this._isShallow;///__v_isReactive  陷阱属性if (key === "__v_isReactive") {return !isReadonly2;} else if (key === "__v_isReadonly") {return isReadonly2;} else if (key === "__v_isShallow") {return isShallow2;} else if (key === "__v_raw") {///proxy对象通过get 设置了__v_raw 陷阱属性,通过这个属性可以判断是否是Proxy对象 if (receiver === (isReadonly2 ? isShallow2 ? shallowReadonlyMap : readonlyMap : isShallow2 ? shallowReactiveMap : reactiveMap).get(target) || // receiver is not the reactive proxy, but has the same prototype// this means the reciever is a user proxy of the reactive proxyObject.getPrototypeOf(target) === Object.getPrototypeOf(receiver)) {return target;}return;}//省略了部分代码}}

响应式工具API

isRef

 作用

    判断当前对象是不是响应式(RefImpl)对象,

    function isRef(r) {//使用RefImpl封装的对象 都有这个属性__v_isRef,且为true. 不管r是原始值还是对象类型return !!(r && r.__v_isRef === true);}

unref

作用

  去掉响应式封装,不会递归

    function unref(ref2) {///isRef函数根据__v_isRef属性来判断是否是有RefImpl的封装。如果是的话 就返回value值。这个value只也可能还是reactive()响应式对象。return isRef(ref2) ? ref2.value : ref2;}

isReactive

    作用判断value是否是一个reactive()创建的一个响应式对象

    function isReactive(value) {if (isReadonly(value)) {return isReactive(value["__v_raw"]); //__v_raw属性是原始对象值}//__v_isReactive这个属性是在reactive()创建是通过get方法设置的一个陷阱属性。return !!(value && value["__v_isReactive"]);}

isProxy

作用

    function isProxy(value) {return value ? !!value["__v_raw"] : false;}

isReadonly

  作用

   判断一个对象是否是只读的,有__v_isReadonly属性就是,只读具体什么概念??: 

    function isReadonly(value) {return !!(value && value["__v_isReadonly"]);}

toRaw

   作用就是把一个reactive创建的响应式对象递归返回最原始的值,如果是RefImpl创建的对象响应就不能解封了。如果是RefImpl可以通过toRaw(reactiveObj._value)来获取最原始值。

所以toRaw只对reactive创建的响应式对象才有用。那么RefImpl怎么解封呢?

    function toRaw(observed) {//__v_raw这个属性是使用reactive创建时通过get 方法设置的一个陷阱属性,具体实现//在: BaseReactiveHandler中const raw = observed && observed["__v_raw"];return raw ? toRaw(raw) : observed;}

proxyRefs   

function proxyRefs(objectWithRefs) {//如果objectWithRefs本身是reactive封装响应的式对象,就直接返回,//如果不是响应式 就用Proxy代理一次,但是这里创建的proxy对应的shallowUnwrapHandlers不会加入响应式功能return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers);}//handler如下shallowUnwrapHandlersconst shallowUnwrapHandlers = {get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),set: (target, key, value, receiver) => {const oldValue = target[key];if (isRef(oldValue) && !isRef(value)) {oldValue.value = value;return true;} else {return Reflect.set(target, key, value, receiver);}}};
//以下是组件初始化的部分代码
//用shallowUnwrapHandlers 拦截器 把setup结果封装成了代理Proxy但是没有响应式功能
instance.setupState = proxyRefs(setupResult);{///把结果setupState暴露到代理对象中去 exposeSetupStateOnRenderContext(instance);
}function exposeSetupStateOnRenderContext(instance) {const { ctx, setupState } = instance;Object.keys(toRaw(setupState)).forEach((key) => {if (!setupState.__isScriptSetup) {if (isReservedPrefix(key[0])) {warn$1(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" which are reserved prefixes for Vue internals.`);return;}Object.defineProperty(ctx, key, {enumerable: true,configurable: true,get: () => setupState[key],set: NOOP});}});}

组件渲染时处理data和setupState

setupState是setup函数返回的结果。

在vue3内部api中的applyOptions方法中会处理data值。这个方式applyOptions是为了兼容vue2的选项式api的

 把instance.ctx上的属性代理到instance.proxy上。

 PublicInstanceProxyHandlers 的代码如下。可以从代码上看到页面上渲染时,如{{msg}},获取msg值的优先级别是:

SETUP函数返回结果 >data>ctx>props>publicPropertiesMap(全局的)>appContext.config.globalProperties
 

 const PublicInstanceProxyHandlers = {get({ _: instance }, key) {if (key === "__v_skip") {return true;}const { ctx, setupState, data, props, accessCache, type, appContext } = instance;if (key === "__isVue") {return true;}let normalizedProps;if (key[0] !== "$") {//先从访问缓存中获取const n = accessCache[key];if (n !== void 0) {switch (n) {case 1 /* SETUP */:return setupState[key];case 2 /* DATA */:return data[key];case 4 /* CONTEXT */:return ctx[key];case 3 /* PROPS */:return props[key];}} else if (hasSetupBinding(setupState, key)) {accessCache[key] = 1 /* SETUP */;return setupState[key];} else if (data !== EMPTY_OBJ && hasOwn(data, key)) {accessCache[key] = 2 /* DATA */;return data[key];} else if (// only cache other properties when instance has declared (thus stable)// props(normalizedProps = instance.propsOptions[0]) && hasOwn(normalizedProps, key)) {accessCache[key] = 3 /* PROPS */;return props[key];} else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {accessCache[key] = 4 /* CONTEXT */;return ctx[key];} else if (shouldCacheAccess) {accessCache[key] = 0 /* OTHER */;}}///返回公共属性的getterconst publicGetter = publicPropertiesMap[key];let cssModule, globalProperties;if (publicGetter) {if (key === "$attrs") {track(instance.attrs, "get", "");markAttrsAccessed();} else if (key === "$slots") {track(instance, "get", key);}return publicGetter(instance);} else if (// css module (injected by vue-loader)(cssModule = type.__cssModules) && (cssModule = cssModule[key])) {return cssModule;} else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {accessCache[key] = 4 /* CONTEXT */;return ctx[key];} else if (// global propertiesglobalProperties = appContext.config.globalProperties, hasOwn(globalProperties, key)) {{return globalProperties[key];}} else if (currentRenderingInstance && (!isString(key) || // #1091 avoid internal isRef/isVNode checks on component instance leading// to infinite warning loopkey.indexOf("__v") !== 0)) {if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) {warn$1(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved character ("$" or "_") and is not proxied on the render context.`);} else if (instance === currentRenderingInstance) {warn$1(`Property ${JSON.stringify(key)} was accessed during render but is not defined on instance.`);}}},set({ _: instance }, key, value) {const { data, setupState, ctx } = instance;if (hasSetupBinding(setupState, key)) {setupState[key] = value;return true;} else if (setupState.__isScriptSetup && hasOwn(setupState, key)) {warn$1(`Cannot mutate <script setup> binding "${key}" from Options API.`);return false;} else if (data !== EMPTY_OBJ && hasOwn(data, key)) {data[key] = value;return true;} else if (hasOwn(instance.props, key)) {warn$1(`Attempting to mutate prop "${key}". Props are readonly.`);return false;}if (key[0] === "$" && key.slice(1) in instance) {warn$1(`Attempting to mutate public property "${key}". Properties starting with $ are reserved and readonly.`);return false;} else {if (key in instance.appContext.config.globalProperties) {Object.defineProperty(ctx, key, {enumerable: true,configurable: true,value});} else {ctx[key] = value;}}return true;},has({_: { data, setupState, accessCache, ctx, appContext, propsOptions }}, key) {let normalizedProps;return !!accessCache[key] || data !== EMPTY_OBJ && hasOwn(data, key) || hasSetupBinding(setupState, key) || (normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key) || hasOwn(ctx, key) || hasOwn(publicPropertiesMap, key) || hasOwn(appContext.config.globalProperties, key);},defineProperty(target, key, descriptor) {if (descriptor.get != null) {target._.accessCache[key] = 0;} else if (hasOwn(descriptor, "value")) {this.set(target, key, descriptor.value, null);}return Reflect.defineProperty(target, key, descriptor);}};

在vue3内部api中的handleSetupResult方法中会处理setup函数返回的结果setupResult值。

响应式对象处理实例

实例1

 var refObj=ref({num1:123,num2:456}); 

 var tmpObj=toRaw(refObj);

var reactiveObj=reactive(tmpObj);

结果1:   tmpObj==refObj //true

                reactiveObj==refObj //false

因为: refObj首先是一个RefImpl对象,然后被封装的值是一个对象类型的,所以{num1:123,num2:456}会被封装成一个reactive()对象。所以refObj.value是一个响应式对象(Proxy)。然后使用toRaw(refObj),进行解封,但是由于refObj是一个RefImpl类型的对象,不能使用toRaw()方法类解封,因为这个toRaw是通过__v_raw陷阱属性类判断的,refImpl类型的没有这陷阱属性__v_raw。所以oRaw(refObj)还是原样返回refObj。所以 tmpObj==refObj 。

var reactiveObj=reactive(tmpObj); 因为tmpObj是一个RefImpl类型的对象,而使用reactive创建响应式对象时是不会判断当前是RefImpl类型的,只有tmpObj是reactive类型的才不会再次封装。所以这时要回给tmpObj在包装一层。 reactiveObj==refObj 为false.

总结1:

    toRaw 和unref都是分别解封  reactive和RefImpl类型,获取原始值。toRaw递归获取最原始的值。

   ref(value)在封装value之前会判断当前是否是 RefImpl,如果是就直接返回,不会再封装。

   reactive(value) 在封装之前也会判断value之前是否是reactive封装过,如果封装过就直接返回,不会再封装

       

http://www.dtcms.com/wzjs/412233.html

相关文章:

  • 网站广告动态图怎么做长沙网站策划
  • 做品牌形象网站德州seo整站优化
  • 域名查询中心官网佛山网站建设十年乐云seo
  • 商丘做手机做网站网络快速推广渠道
  • wap电影网站建设制作网站的基本流程
  • 建设全网营销型网站怎样建立网站平台
  • 网站设计师需要什么知识与技能新乡seo公司
  • 中国新闻社江西分社移动端关键词优化
  • 临沂专业网站建设公司电话曼联目前积分榜
  • 关于我们 网站广州seo运营
  • wordpress侧边二级导航菜单seo和sem推广
  • 做网站 好苦逼app推广拉新平台
  • 网站子目录建立潮州网站建设
  • 设计logo网站免费南蒲四特什么是长尾关键词举例
  • win10做的网站其他电脑访问不了北京百度推广代运营
  • 做外贸主要是哪些网站搜索引擎排名原理
  • 住房及城乡建设部信息中心网站最好用的免费建站
  • 海淀建设网站东莞企业网站排名
  • 南水北调中线建建设管理局网站巨量引擎广告投放平台登录入口
  • wordpress改为直接填写密码落实好疫情防控优化措施
  • 网站建设邯郸石家庄网站建设公司
  • 网站建设审批爱站网关键词排名
  • dedecms 做电商网站怎么弄一个自己的网址
  • 什么网站免费做游戏seo搜索引擎优化是通过优化答案
  • 青岛门户网站建设百度爱采购关键词优化
  • wordpress 做企业网站网络零售的优势有哪些
  • 威海建设集团网站首页最好用的磁力搜索神器
  • 浦东新区网站建设什么是软文营销
  • 免费做婚礼邀请函的网站网页广告调词平台
  • 简述网站开发设计流程it培训四个月骗局