barriers / 阅读 / 详情

从源码的角度分析vue computed的依赖搜集

2023-08-25 07:18:42
共1条回复
豆豆staR
* 回复内容中包含的链接未经审核,可能存在风险,暂不予完整展示!
vue 源码版本是2.6.12

很多介绍vue源码的文章对computed怎么计算值讲的很清楚,但是对computed 怎么搜集到依赖它的视图渲染watcher,以及怎么去通知对应的渲染watcher去更新讲解的很模糊或者干脆一笔带过。这篇文章主要讲解——computed watcher是怎么搜集到订阅它的渲染watcher。

文件在src/core/instance/state.js

当组件读取computed a的值的时候会执行 computedGetter函数,先是通过

计算出computed函数的值,然后通过

进行依赖搜集。
Dep.target指向当前组件的渲染watcher,进入watcher.depend()看看是怎么进行依赖搜集的
文件位于 src/core/observer/watcher.js

第一个问题:this.deps的赋值

是在cleanupDeps函数中执行this.deps = this.newDeps,所以要看cleanupDeps在哪里被调用的,以及this.newDeps中的值是哪里产生的

get函数是在computed 通过watcher.evaluate()计算值的时候被调用的,讲解下这个函数的核心操作

这个this是计算属性的watcher,调用dep.js中的

作用是放到栈顶,同时将计算属性的watcher赋值给Dep.taget

会调用 计算属性a的函数

由于引用到了i,所以会触发i的get 函数,就会调用dep.depend(),实际上是i的依赖搜集,这里的dep对象属于i

dep.depend() 位于src/core/observer/dep.js

这里的Dep.target就是上面保存的computed watcher实例,会执行watcher中的addDep,这里的this就是i的dep实例
文件位于 src/core/observer/watcher.js

做了两件事

把栈顶的watcher弹出,改变Dep.target的指向,此时指向组件的渲染watcher

这一步就是 将this.newDeps的值赋给this.deps,此时this.deps中的数组中的对象其实就是i的dep实例

再回到 watcher.depend()

this.deps[i].depend() 这里就是执行

此时Dep.target是组件的渲染watcher,所以实现的逻辑是组件渲染watcher调用addDep(this),其实就是持有i的dep,最终被i搜集到依赖。
转了这么大一圈,实际上是为了让组件的watcher被计算属性中引用的data变量搜集到,这也不难理解,既然组件依赖computed的变化,当然也依赖computed中的值的变化,示例中computed中的值变化来自于i的变化,所以当i变化时,就让去通知计算属性的watcher去重新计算,通知组件watcher重新渲染。
对于data中变量的响应式原理和依赖搜集、派发更新可以参考我的这篇文章
从源码的角度分析Vue视图更新和nexttick机制

参考:
https://ustbhuangyi.github.io/vue-analysis/v2/reactive/getters.html#dep
https://j****.cn/post/6877451301618352141

相关推荐

watcher是什么意思

watcher的意思是观察家。观察家评论是评论员文章的另一种形式。通常用于重要的时事评论。以观察家的身份出现,使得评论显得客观和具有权威性。在写法上,观察家评论着重于评析和论辩,高屋建瓴,寓评论于“观察”之中。观察形势,分析形势,预测未来,引导舆论。《Watcher》故事有点虚,却传递出信念对于人生的重要性,都治光就是一个对正义的理解有争议的代表,他为了抓金英郡的爸爸会捏造证据,为了从朴次长那里得到证据可以下毒逼供,甚至他可以为了继续抓坏警察会和廉厅长做交易他是在面对社会大众的时候对于自己的罪过也毫不掩饰,从头到尾,哪怕到故事结束的未来,他都坦言从不认为自己正义.《WATCHER》是从同一事件的相关人员的视角,站在语言心理学的角度,观察每一个真相和案中人,最终揭露警察内部腐败的烧脑惊悚电视剧。”《Watcher》会证明影视剧市场的王者,依旧属于内容为王,业务水平过硬的演技派。对于剧情节奏而言,《WATCHER》温而不慢,稳而不乱,紧缓得宜,张弛有度,避免因为太过紧凑而造成后续格局难以把握的问题,同时有新老戏骨们的加持,通过语言对话的逐渐推陈,显露每个人物的动机,以此发挥出心理悬疑剧的最佳效果。
2023-08-19 18:07:201

如何使用vue中的watcher

这篇文章主要介绍了vue 中的 watcher的相关资料,需要的朋友可以参考下观察 Watchers虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的 watcher 。这是为什么 Vue 提供一个更通用的方法通过watch 选项,来响应数据的变化。当你想要在数据变化响应时,执行异步操作或开销较大的操作,这是很有用的。大家对于 watch 应该不陌生,项目中都用过下面这种写法:watch: { someProp () { // do something }}// 或者watch: { someProp: { deep: true, handler () { // do something } }}上面的写法告诉 vue,我需要监听 someProp 属性的变化,于是 vue 在内部就会为我们创建一个 watcher 对象。(限于篇幅,我们不聊 watcher 的具体实现,感兴趣的可以直接看源码 watcher)然而在 vue 中,watcher 的功能并没有这么单一,先上段代码:<template> <p> <p>a: {{ a }}</p> <p>b: {{ b }}</p> <button @click="increment">+</button> </p></template><script>export default { data () { return { a: 1 } }, computed: { b () { return this.a * 2 } }, watch: { a () { console.log("a is changed") } }, methods: { increment () { this.a += 1 } }, created () { console.log(this._watchers) }}</script>在线demo上面代码非常简单,我们现在主要关注 created 钩子中打印的 this._watchers,如下:分别展开三个 watcher,观察每一个 expression,从上到下分别为:b() { return this.a * 2;? }"a"function () { vm._update(vm._render(), hydrating);? }上面三个 watcher 代表了三种不同功能的 watcher,我们将其按功能分为三类:在 watch 中定义的,用于监听属性变化的 watcher (第二个)用于 computed 属性的 watcher (第一个)用于页面更新的 watcher (第三个)normal-watcher我们在 watch 中定义的,都属于这种类型,即只要监听的属性改变了,都会触发定义好的回调函数computed-watcher每一个 computed 属性,最后都会生成一个对应的 watcher 对象,但是这类 watcher 有个特点,我们拿上面的 b 举例:属性 b 依赖 a,当 a 改变的时候,b 并不会立即重新计算,只有之后其他地方需要读取 b 的时候,它才会真正计算,即具备 lazy(懒计算)特性render-watcher每一个组件都会有一个 render-watcher, function () {? vm._update(vm._render(), hydrating);? }, 当 data/computed中的属性改变的时候,会调用该 render-watcher 来更新组件的视图三种 watcher 的执行顺序除了功能上的区别,这三种 watcher 也有固定的执行顺序,分别是:computed-render -> normal-watcher -> render-watcher这样安排是有原因的,这样就能尽可能的保证,在更新组件视图的时候,computed 属性已经是最新值了,如果 render-watcher 排在 computed-render 前面,就会导致页面更新的时候 computed 值为旧数据。下面从一段实例代码中看下vue中的watcher在这个示例中,使用 watch 选项允许我们执行异步操作(访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这是计算属性无法做到的。<p id="watch-example"><p>Ask a yes/no question:<input v-model="question"></p><p>{{ answer }}</p></p><!-- Since there is already a rich ecosystem of ajax libraries --><!-- and collections of general-purpose utility methods, Vue core --><!-- is able to remain small by not reinventing them. This also --><!-- gives you the freedom to just use what you"re familiar with. --><script src="https://unpkg.com/axios@0.12.0/dist/axios.min.js"></script><script src="https://unpkg.com/lodash@4.13.1/lodash.min.js"></script><script>var watchExampleVM = new Vue({el: "#watch-example",data: {question: "",answer: "I cannot give you an answer until you ask a question!"},watch: { // 如果 question 发生改变,这个函数就会运行question: function (newQuestion) {this.answer = "Waiting for you to stop typing..."this.getAnswer()}},methods: { // _.debounce 是一个通过 lodash 限制操作频率的函数。 // 在这个例子中,我们希望限制访问yesno.wtf/api的频率 // ajax请求直到用户输入完毕才会发出 // 学习更多关于 _.debounce function (and its cousin// _.throttle), 参考: https://lodash.com/docs#debouncegetAnswer: _.debounce(function () {var vm = thisif (this.question.indexOf("?") === -1) {vm.answer = "Questions usually contain a question mark. ;-)"return}vm.answer = "Thinking..."axios.get("https://yesno.wtf/api").then(function (response) {vm.answer = _.capitalize(response.data.answer)}).catch(function (error) {vm.answer = "Error! Could not reach the API. " + error})},// 这是我们为用户停止输入等待的毫秒数500)}})</script>上面是我整理给大家的,希望今后会对大家有帮助。相关文章:在Vue中有关响应式原理(详细教程)在angularjs中如何实现柱状图动态加载在Angular作用域中scope的如何使用使用react如何实现菜单权限控制详细解读vue.js中props如何传递参数
2023-08-19 18:07:461

漫威观察者名字

观察者是美国漫威漫画旗下角色。漫威观察者队员宇宙级别但是自身实力很一般,再很多重要时刻可以看到他们的身影,很神秘的样子,他就是Watcher。拓展资料:Watchers相信他们的知识和力量是属于宇宙的,所以他们去到Prosilicus星,帮助那里新生的民族的进化与发展。可是,Prosilicus星的种族却因为科技进步而加速腐化.最后毁灭了自己的星球。此事之后watcher决定他们不会再参与宇宙中任何生命体的事件,只是会以旁观者的身份见证着,这就是watcher他们终身的承诺。参考资料:百度百科-观察者
2023-08-19 18:07:571

一文了解Zookeeper的Watcher机制

Zookeeper系列介绍( 持续更新 ) u2002u2002Zookeeper提供了数据的发布/订阅功能,多个订阅者可同时监听某一特定主题对象,当该主题对象的自身状态发生变化时(例如节点内容改变、节点下的子节点列表改变等),会实时、主动通知所有订阅者。 u2002u2002Zookeeper采用了Watcher机制实现数据的发布/订阅功能。该机制在被订阅对象发生变化时会异步通知客户端,因此客户端不必在Watcher注册后轮询阻塞,从而减轻了客户端压力。 Watcher实现由三个部分组成: u2002u2002客户端首先将Watcher注册到服务端,同时将Watcher对象保存到客户端的Watch管理器中。当ZooKeeper服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的Watch管理器会触发相关Watcher来回调相应处理逻辑,从而完成整体的数据发布/订阅流程。 u2002u2002Watcher是一个接口, 任何实现了Watcher接口的类就是一个新的Watcher 。Watcher内部包含了两个枚举类:KeeperState、EventType。 u2002u2002KeeperState是客户端与服务端连接状态发生变化时对应的通知类型。路径为org.apache.zookeeper.Watcher.Event.KeeperState,是一个枚举类,其枚举属性如下; u2002u2002EventType是数据节点(znode)发生变化时对应的通知类型。 EventType变化时KeeperState永远处于SyncConnected通知状态下;当KeeperState发生变化时,EventType永远为None 。其路径为org.apache.zookeeper.Watcher.Event.EventType,是一个枚举类,枚举属性如下; 注 :客户端接收到的相关事件通知中只包含状态及类型等信息,不包括节点变化前后的具体内容,变化前的数据需业务自身存储,变化后的数据需调用get等方法重新获取;
2023-08-19 18:08:101

Eternal丶Watcher什么意思?

你好!Eternaladj. 永恒的;不朽的Watchern. 观察者;看守人;哨兵;(美)选举监票员
2023-08-19 18:08:221

ZooKeeper Watcher 和 AsyncCallback 的区别与实现

Watcher:Watcher是用于监听节点,session 状态的,比如getData对数据节点a设置了watcher,那么当a的数据内容发生改变时,客户端会收到NodeDataChanged通知,然后进行watcher的回调。AsyncCallback:AsyncCallback是在以异步方式使用 ZooKeeper API 时,用于处理返回结果的。例如:getData同步调用的版本是:byte[] getData(String path, boolean watch,Stat stat),异步调用的版本是:void getData(String path,Watcher watcher,AsyncCallback.DataCallback cb,Object ctx),可以看到,前者是直接返回获取的结果,后者是通过AsyncCallback回调处理结果的。
2023-08-19 18:08:331

请问audience ,viewer ,watcher ,spectator有什么区别?

上面四词均有观众之意:但各自所代表的含义有所不同,audience用于在那种听众和主讲人双方都清楚的情况下,即双方都知道对方的存在;而且一般都限于人的观众;viewer的对象可以是人也可以是人以外的物,而且被观察者未必知道viewer的存在;watcher 强调于对于正在运动活动的对象,而且对象人和物皆可;spectator一般只限于对象为人。其他地方 与audience类似,但有一点区别audience一般被观察人只有一人,而spectator的对象可同时多人
2023-08-19 18:08:552

vue watch原理

1、很多情况下,computed和watch可以实现相同的功能; 2、当需要在数据变化时执行异步或开销较大的操作时,使用watch会更好一些。因为computed会立即返回,此时异步操作可能还没有完成; 3、因为数据是响应式的,使得watch有意义。并不是因为watch了才使得数据是响应式的。 4、使用immediate:true,会在初始化watch时就立即执行handler回调函数,而不用等下一次数据更新。 5、使用deep:true,才会递归监听对象的属性(如果监听的是对象或数组)。 在created函数调用之前,调用了initWatcher方法,(调用该方法时,若immediate为真,则会立即执行回调函数),为每一个watcher属性实例化了一个Watcher,new Watcher ,会传入监听的属性key、回调函数和options,包括handler、deep和immediate的值,实例化的结尾会调用watcher.prototype.get方法,该方法会获得值并返回,值存在watcher.value属性上。 Get函数(即autorun)的执行即导致了watcher被收集为依赖。至此成功的监听了属性。 Get时,如果deep为真,则会递归监听所有的属性。 在数据发生变化时,调用watcher.prototype.update方法,最终会执行第三步的get。 watch的watcher中的lazy和sync都为false,所以会执行queueWatcher. 第一步 第二步 第三步 watch的get方法 第四步 更新数据 第五步 Q:哪些对象是Watcher? A :在源码中,看到三个地方会初始化Watcher对象。挂载组件(mountComponent方法)、初始化watch(initWatch方法)和初始化computed(initComputed方法)。
2023-08-19 18:09:041

【手把手教你搓Vue响应式原理】(五) Watcher 与 Dep

【手把手教你搓Vue响应式原理】(一)初识Vue响应式 【手把手教你搓Vue响应式原理】(二)深度监测对象全部属性 【手把手教你搓Vue响应式原理】(三)observe 以及 ob 【手把手教你搓Vue响应式原理】(四) 数组的响应式处理 之前已经将数据劫持已经全部完成了。 那么,接下来,主要的要点就是在于两点,依赖收集和触发依赖更新。 它的意义主要在于控制哪些地方使用了这个变量,然后,按照最小的开销来更新视图 。 首先,要先明白,依赖是什么,比方说在我们的模板中有 {{a}} ,那么,这个地方就有对于变量 a 的依赖。 在模板编译的时候,就会触发 a 变量的 getter 。 然后,当我们执行 a++; 的时候,那么,我们就要触发依赖的更新,当初模板中 {{a}} 的地方,就要更新,是吧! 所以,我们都是 在 getter 中收集依赖,在 setter 中触发依赖更新 。 这一节的内容,主要就是用来专门讲清楚这两件事情。 依赖收集和触发依赖更新主要由两个类来完成, Dep 和 Watcher 。 Dep 和 Watcher 在设计模式中,就是 发布-订阅者 的模式。 而依赖,你可以理解为所谓的订阅者。 Dep 说白了就是发布者,它的工作就是依赖管理,要知道哪些地方用到了这个变量,可能用到这个变量的地方有很多,所以,它会有多个订阅者。 然后,每个变量都应该有属于自己的 Dep ,因为每个变量所在的依赖位置是不一样的,所以他们的订阅者也不一样。 然后在变量更新之后,就去通知所有的订阅者(Watcher),我的变量更新了,你们该触发视图更新了。 Watcher 说白了就是订阅者,它接受 Dep 发过来的更新通知之后,就去执行视图更新了。 它其实就是所谓的 watch 监听器,变量改变之后,执行一个回调函数。 我们先按照图例来创建我们的 Dep 类 根据我们的需求: Dep 我们在前面也说了,每个属性都应该有它自己的 Dep ,用来管理依赖。 所以,首先,如果我们在 Observer 中创建 Dep,那不就可以了。毕竟 Observer 会遍历到每一个对象。 所以,很明显,我们可以在 defineReactive 的 get 中收集依赖 因为有了 if(Dep.target) 的判断,所以, 只有绑定 Watcher 的变量触发 getter 时,才会添加依赖 。 这个 Dep.target 其实就是 Watcher 的实例 所以,很明显,我们可以在 defineReactive 的 set 中收调用 notify() 方法告知 Watcher 实例,数据更新了。 至此, Dep 的所有职责,我们已经帮它完成了。 其实照道理应该有一个删除依赖,我们这里就不再扩展了。 首先, Watcher 实例应该大家会相对而言更加好理解点,因为,我们有一个 watch 侦听器,大家一定都很熟悉,这两个其实一样。 我们先按照图例来创建我们的 Watcher 类 根据我们的需求: 这个 parsePath 需要单独拎出来说一下,比方说我们现在有这么一个对象 我们要监听到 a.b.c.d ,所以,我们需要下面的这种格式 所以,这个 get 很明显就有点难度了。 我们需要通过循环 拿到 a.b 然后 .c 然后 .d。 我们将这个方法命名为 parsePath 。 入参接受我们的 b.c.d ,我们可以看到 第一句执行之后 segments=["b","c","d"] ,然后进行第二层,这是返回了一个方法,按照循环,那就是 obj=obj.b => obj=obj.c => obj=obj.d ,所以,就是返回一个对象的 obj.b.c.d,相当于是遍历字符串中的属性树。 在执行 a.b.c.d=55; 的同时,我们的控制台就会输出 ok 55 10 。 【尚硅谷】Vue源码解析之数据响应式原理
2023-08-19 18:10:081

elasticsearch watcher 收费吗

目前还不清楚呢
2023-08-19 18:10:242

c#如何用FileStreamWatcher来监控frp上的目录?? 例如,ftp://192.1

FileStreamWatcher 只能监视本地的目录
2023-08-19 18:10:472

你好,这是腾讯的监测软件,名义上说是抗木马,其实是监测第三方软件用的,有时候卡顿就是那个原因,占内存挺多的,会玩的基本把那个关掉,免得掉线。如果启动游戏后,出现gamebababytqmwatcher停止工作的报错,请删除安装目录/bin/tqm/dump下的所有文件即可解决这个问题。
2023-08-19 18:11:131

vue数据控制视图如何实现(附代码)

这次给大家带来vue数据控制视图如何实现(附代码),vue数据控制视图实现的注意事项有哪些,下面就是实战案例,一起来看一下。前记三个月前看了vue源码来分析如何做到响应式数据的, 文章名字叫vue源码之响应式数据, 最后分析到, 数据变化后会调用Watcher的update()方法. 那么时隔三月让我们继续看看update()做了什么. (这三个月用react-native做了个项目, 也无心总结了, 因为好像太简单了).本文叙事方式为树藤摸瓜, 顺着看源码的逻辑走一遍, 查看的vue的版本为2.5.2. 我fork了一份源码用来记录注释.目的明确调查方向才能直至目标, 先说一下目标行为: 数据变化以后执行了什么方法来更新视图的. 那么准备开始以这个方向为目标从vue源码的入口开始找答案.从之前的结论开始先来复习一下之前的结论:vue构造的时候会在data(和一些别的字段)上建立Observer对象, getter和setter被做了拦截, getter触发依赖收集, setter触发notify.另一个对象是Watcher, 注册watch的时候会调用一次watch的对象, 这样触发了watch对象的getter, 把依赖收集到当前Watcher的deps里, 当任何dep的setter被触发就会notify当前Watcher来调用Watcher的update()方法.那么这里就从注册渲染相关的Watcher开始.找到了文件在src/core/instance/lifecycle.js中.new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */)mountComponent渲染相关的Watcher是在mountComponent()这个方法中调用的, 那么我们搜一下这个方法是在哪里调用的. 只有2处, 分别是src/platforms/web/runtime/index.js和src/platforms/weex/runtime/index.js, 以web为例:Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean): Component { el = el && inBrowser ? query(el) : undefined return mountComponent(this, el, hydrating)}原来如此, 是$mount()方法调用了mountComponent(), (或者在vue构造时指定el字段也会自动调用$mount()方法), 因为web和weex(什么是weex?之前别的文章介绍过)渲染的标的物不同, 所以在发布的时候应该引入了不同的文件最后发不成不同的dist(这个问题留给之后来研究vue的整个流程).下面是mountComponent方法:export function mountComponent ( vm: Component, el: ?Element, hydrating?: boolean): Component { vm.$el = el // 放一份el到自己的属性里 if (!vm.$options.render) { // render应该经过处理了, 因为我们经常都是用template或者vue文件 // 判断是否存在render函数, 如果没有就把render函数写成空VNode来避免红错, 并报出黄错 vm.$options.render = createEmptyVNode if (process.env.NODE_ENV !== "production") { /* istanbul ignore if */ if ((vm.$options.template && vm.$options.template.charAt(0) !== "#") || vm.$options.el || el) { warn( "You are using the runtime-only build of Vue where the template " + "compiler is not available. Either pre-compile the templates into " + "render functions, or use the compiler-included build.", vm ) } else { warn( "Failed to mount component: template or render function not defined.", vm ) } } } callHook(vm, "beforeMount") let updateComponent /* istanbul ignore if */ if (process.env.NODE_ENV !== "production" && config.performance && mark) { // 不看这里的代码了, 直接看else里的, 行为是一样的 updateComponent = () => { const name = vm._name const id = vm._uid const startTag = `vue-perf-start:${id}` const endTag = `vue-perf-end:${id}` mark(startTag) const vnode = vm._render() mark(endTag) measure(`vue ${name} render`, startTag, endTag) mark(startTag) vm._update(vnode, hydrating) mark(endTag) measure(`vue ${name} patch`, startTag, endTag) } } else { updateComponent = () => { vm._update(vm._render(), hydrating) } } // we set this to vm._watcher inside the watcher"s constructor // since the watcher"s initial patch may call $forceUpdate (e.g. inside child // component"s mounted hook), which relies on vm._watcher being already defined // 注册一个Watcher new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */) hydrating = false // manually mounted instance, call mounted on self // mounted is called for render-created child components in its inserted hook if (vm.$vnode == null) { vm._isMounted = true callHook(vm, "mounted") } return vm}这段代码其实只做了3件事:调用beforeMount钩子建立Watcher调用mounted钩子(哈哈哈)那么其实核心就是建立Watcher了.看一下Watcher的参数: vm是this, updateComponent是一个函数, noop是空, null是空, true代表是RenderWatcher.在Watcher里看了isRenderWatcher:if (isRenderWatcher) { vm._watcher = this }是的, 只是复制了一份用来在watcher第一次patch的时候判断一些东西(从注释里看的, 我现在还不知道是干嘛的).那么只有一个问题没解决就是updateComponent是个什么东西.updateComponent在Watcher的构造函数的第二个参数传了function, 那么这个函数就成了watcher的getter. 聪明的你应该已经猜到, 在这个updateComponent里一定调用了视图中所有的数据的getter, 才能在watcher中建立依赖从而让视图响应数据的变化.updateComponent = () => { vm._update(vm._render(), hydrating) }那么就去找vm._update()和vm._render().在src/core/instance/render.js找到了._render()方法.Vue.prototype._render = function (): VNode { const vm: Component = this const { render, _parentVnode } = vm.$options // todo: render和_parentVnode的由来 // reset _rendered flag on slots for duplicate slot check if (process.env.NODE_ENV !== "production") { for (const key in vm.$slots) { // $flow-disable-line vm.$slots[key]._rendered = false } } if (_parentVnode) { vm.$scopedSlots = _parentVnode.data.scopedSlots || emptyObject } // set parent vnode. this allows render functions to have access // to the data on the placeholder node. vm.$vnode = _parentVnode // render self let vnode try { vnode = render.call(vm._renderProxy, vm.$createElement) } catch (e) { // catch其实不需要看了, 都是做异常处理, _vnode是在vm._update的时候保存的, 也就是上次的状态或是null(init的时候给的) handleError(e, vm, `render`) // return error render result, // or previous vnode to prevent render error causing blank component /* istanbul ignore else */ if (process.env.NODE_ENV !== "production") { if (vm.$options.renderError) { try { vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e) } catch (e) { handleError(e, vm, `renderError`) vnode = vm._vnode } } else { vnode = vm._vnode } } else { vnode = vm._vnode } } // return empty vnode in case the render function errored out if (!(vnode instanceof VNode)) { if (process.env.NODE_ENV !== "production" && Array.isArray(vnode)) { warn( "Multiple root nodes returned from render function. Render function " + "should return a single root node.", vm ) } vnode = createEmptyVNode() } // set parent vnode.parent = _parentVnode return vnode }}这个方法做了:根据当前vm的render方法来生成VNode. (render方法可能是根据template或vue文件编译而来, 所以推论直接写render方法效率最高)如果render方法有问题, 那么首先调用renderError方法, 再不行就读取上次的vnode或是null.如果有父节点就放到自己的.parent属性里.最后返回VNode所以核心是这句:vnode = render.call(vm._renderProxy, vm.$createElement)其中的render(), vm._renderProxy, vm.$createElement都不知道是什么.先看vm._renderProxy: 是initMixin()的时候设置的, 在生产环境返回vm, 开发环境返回代理, 那么我们认为他是一个可以debug的vm(就是vm), 细节之后再看.vm.$createElement的代码在vdom文件夹下, 看了下是一个方法, 返回值一个VNode.render有点复杂, 能不能以后研究, 总之就是把template或者vue单文件和mount目标parse成render函数.小总结: vm._render()的返回值是VNode, 根据当前vm的render函数接下来看vm._update()Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) { const vm: Component = this if (vm._isMounted) { callHook(vm, "beforeUpdate") } // 记录update之前的状态 const prevEl = vm.$el const prevVnode = vm._vnode const prevActiveInstance = activeInstance activeInstance = vm vm._vnode = vnode // Vue.prototype.patch is injected in entry points // based on the rendering backend used. if (!prevVnode) { // 初次加载, 只有_update方法更新vm._vnode, 初始化是null // initial render vm.$el = vm.patch( // patch创建新dom vm.$el, vnode, hydrating, false /* removeOnly */, vm.$options._parentElm, vm.$options._refElm ) // no need for the ref nodes after initial patch // this prevents keeping a detached DOM tree in memory (#5851) vm.$options._parentElm = vm.$options._refElm = null } else { // updates vm.$el = vm.patch(prevVnode, vnode) // patch更新dom } activeInstance = prevActiveInstance // update vue reference if (prevEl) { prevEl.vue = null } if (vm.$el) { vm.$el.vue = vm } // if parent is an HOC, update its $el as well if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { vm.$parent.$el = vm.$el } // updated hook is called by the scheduler to ensure that children are // updated in a parent"s updated hook. }我们关心的部分其实就是patch()的部分, patch()做了对dom的操作, 在_update()里判断了是否是初次调用, 如果是的话创建新dom, 不是的话传入新旧node进行比较再操作.结论vue的视图渲染是一种特殊的Watcher, watch的内容是一个函数, 函数运行的过程调用了render函数, render又是由template或者el的dom编译成的(template中含有一些被observe的数据). 所以template中被observe的数据有变化触发Watcher的update()方法就会重新渲染视图.遗留render函数是在哪里被编译的vue源码发布时引入不同平台最后打成dist的流程是什么patch和VNode的分析相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!推荐阅读:el表达式怎样判断非空ElTableColumn扩展方法详解
2023-08-19 18:11:391

关键文件异常将导致cf file watcher错误,或出现文件异常的提示,无法正常进行游戏

很多玩家在玩CF时候会遇到“CF File Watcher”这样令人头疼的问题,那么如何才能有效的解决这类问题呢?下面我就给大家介绍一下常用有效的解决方法,希望下面的方法能为大家排忧。问题原因: 这是因为移动等网络本身为节约宽带成本,会在上层路由器进行缓存. 而版本更新后, 由于缓存的原因, CF客户端拿不到正确的校验列表, 所以才会报错. 方法(一).清理IE缓存, 然后重新进入游戏.。该做法可以基本解决CF File Watcher问题. 如清理缓存后依旧无效, 请参考下方法2、3 (附:清理IE缓存的方法方法1、在IE中选择工具——Internet选项——“常规”选项卡。在Internet临时文件中,点击“删除文件”可以清楚所有IE临时文件。方法2、也可以在系统分区中右击,选择属性——点击磁盘清理按钮,系统会自动扫猫系统中的无用文件,其中就包括“IE临时文件”和其他一些东西(如回收站、压缩旧文件、office安装文件、图标缓存等)方法3、IE临时文件默认的存放位置是:系统分区Documents and Settings你登录的用户名Local SettingsTemporary Internet Files,把这个文件夹里的东西全选然后彻底删掉,也可以清理掉所有IE缓存。)方法( 二).清空hosts文件。hosts 文件在C:WINDOWSsystem32driversetc下用记事本打开编辑, 删除全部内容, 然后保存即可。方法(三).使用360电脑管家帮助修复。如下图。第一步:点击“电脑救援”第二步:点击“游戏环境”第三步:找到“穿越火线运行时报错”,再点击下面的”立即修复“;就可以了。这种方法可以有效解决部分玩家的问题。方法(4)调试DNS修复方法:1.如何查看自己DNS服务器IP地址操作方法:双击右下角系统图标,就是下面这个小图标,右下角没有的请去网上邻居。2.打开详细信息看见自己的IP和默认网关之类的主要看下自己的DNS那一栏有没有空着。3.如果空着请看下面:右键点击网络连接-属性-单击Internet 协议(Tcp/Ip)点击属性出现如下图所示:下面DNS那块 把“自动获得DNS服务器地址”前面勾选换成“使用下面的DNS服务器地址”备注:DNS地址呢去度娘搜索:全国DNS服务器地址 找到自己当地的DNS填上就可以了
2023-08-19 18:12:125

什么是越野星球 北京越野带你研究

什么是快乐星球?想必这段话你一定听过,这段次元“说唱”在这个信息同质化严重的世界已经人人皆知,这既是我们的幸福,也是悲哀。人在社会中需要共性的存在,而关起门来自己又向往个性,追求个性。那说到玩车怎么玩出个性,一定是去越野。由北京越野联合多方机构举办的“再创经典计划·北京越野设计大赛”上的几个最强作品,就带我们领略了一次未来越野时代,他们构建的“越野星球”,独一无二,令人神往。BJ ROVER 30同济大学的濮启航最终获得先锋奖,他对于未来越野车的理解更多的其实是应用,首先致敬212的前脸能够很明显的看出。整体线条简洁而凸显力量感,他设计的Rover30是专为年轻用户打造全地形越野车。目标是2030年,能够自动驾驶的一款越野车。内饰设计上,给人更多的概念是家的延续,环绕式的设计给乘客安全感。可开启的顶棚,可欣赏风景,让乘客更多亲近自然。其实他的演讲中,最能打动我的是他认为越野车将来会成为多个空间的主宰,他构建的全地形越野车可以在中国复杂地形的多场景应用和科幻的地下世界越野地形,这其实离我们并不远,毕竟日本目前的地下世界已经初具规模了。POP-RUN湖南大学张沙的作品《POP-RUN》赢得了专业评委的心,这款车其实是作品中最硬核的一个设计了,与其说他是越野车,不如说是个带有很多炫丽科技配置的救援车。车的外形更像是一个金甲虫,但硕大的轮毂和离地间距告诉你他的强大越野能力。整车最大的特点之一是前舱盖可以前后开关,完全封闭后应该可以具备很强的防滚性能了。另外这款车的实际用途被设定成未来N年后,在极限运动的过程中,可以全程直播、发布整个过程,甚至可以救援和伴行这些极限运动员们。但我其实在一些现在的汽车品牌发布会上已经看到可以全程直播旅行的概念了,科技飞速进步,让科幻就在我们身边。WETWO北京理工大学的吕艺丰设计的WETWO为面向年轻情侣的小型越野房车,该车旨在为年轻人打造一款可以摆脱市井生活、可以载着他们翻山越岭亲近自然的情侣越野车。该车的特点还是比较鲜明的,主要还是围绕着“二人世界”,有点末日情侣的感觉。WETWO用有个可升降的车顶系统,在原有的车顶上可以再打造出一个空间,相当于双层越野车。那个时代就都自动驾驶了,可以两人躺在车里越野了。然而,年轻人注重浪漫,但评委也考虑到了这款车的未来市场定位,真有了孩子怎么办?我倒是觉得,现在有Coupe车型卖,还不允许未来世界的情侣越野车存在么,这也是不错的细分市场,甚至现在还没有出现。WATCHER武汉理工大学团队的WATCHER获得了优胜奖,打造的这款车有其独特设定背景。未来世界所有工作和生活可以在线上完成,人们更喜欢过游牧式的生活,载体就是越野车。其实这倒是有点赛博朋克了。但该车的使用场景其实更贴近现实,比如设定了车顶部有勘探路况和航拍的无人机等等,不过我认为还可以更大胆一些。已经是游牧生活了,捕个猎也是可以有的。以上的设计也都很天马行空,代表了年轻人对未来世界越野车的不同憧憬和科学幻想,其实从目前来看,包括北京越野在内的很多车企都对越野车开始了重点研发,当然北京越野作为中国越野的经典品牌,更应该担负起重塑经典的责任。北京越野设计大赛之后还公布了决赛“彩蛋”:邀请5位参赛选手,担纲北京越野首批“经典再创官”,共同打造下一代经典越野车。作为 “经典再创官”,5名决赛选手将受邀到北汽造型中心实习,与北京越野专业设计师一起工作、学习和生活,希望北京越野在塑造经典之后,从初心启程,拥抱年轻用户,传播越野文化,推动下一代产品设计,助力实现产品年轻化、品牌年轻化、用户年轻化,并在年轻人心目中,开启中国越野车C2B造车新模式,中国风采的越野品牌,诚心构筑中国力量,共创梦想之车。
2023-08-19 18:13:231

zookeeper java watcher 在哪个包

就在zookeeper包下,org.apache.zookeeper.Watcher
2023-08-19 18:14:441

《暗黑血统Darksiders》攻略第六章(终章)

天堂地狱间的末日之战以及随之而来的人界灭亡,是由天使所一手促成的。天使对宇宙的混乱已无法容忍,于是Abaddon找来Azrael,密谋向地狱宣战:他们隐瞒焦灼议会而打破末日七封印当中的六个,以此引诱地狱集结兵力准备末日之战。趁恶魔争夺大战领导权的时候,天堂的地狱戍卫(Hellguard)则先发制人、趁此时机将恶魔的领袖群一举歼灭。天堂发动突袭的同时将暗中重铸封印,营造出地狱不顾契约径自宣战、天堂为维护宇宙平衡不得不反击的假象。至于破坏封印的末日之剑(ArmageddonBlade),则是来自Ulthane的手上。Abaddon与Azrael出于两个原因而未破坏第七封印、唤出四骑士:首先,他们不敢惊动末日四骑,四骑一出,人界必灰飞烟灭;再者,若天堂重军不敌地狱群魔,四骑士仍可作为消灭恶魔的最后王牌。然而,最后的封印已随着保管者Abaddon消失,Azrael也被囚禁于此,天堂的计谋彻底失败,人间落入恶魔手中,万劫不复。听完了Azrael的告解,War决定自己与议会的协定已告终结,决定离开;然而Watcher以议会赋予的力量制住了War,强迫他彻底完成任务。BlackThrone第三部分Azrael解开第二道枷锁的同时,也改变了周遭场景的地形,让War得以继续前进。从西南方新开启的传送符号处利用虚空行者开窗往上移动,抵达南侧的房间。房间南端上方有个Soldier神器,从上方传送窗出来的瞬间进行滑翔就能取得。在右侧的墙边开窗后,在地上另外开个加速窗,就能从加速窗飞跃到上层。房间西侧有两截上下移动的浮游柱,两根浮游柱彼此相对的那面各有一个传送符号,这里的目标是越过浮游柱抵达对岸。这里的解法和先前两座堡垒之浮游平台的解法相同,只不过我们要先在远端的柱子上开窗,再透过远端的传送窗在近端另开一个加速窗,才能用加速窗的推力冲到对面。趁柱子移动的空隙朝西侧远端的柱子开一扇窗。在东面的墙上另开个传送窗。使用虚空行者聚气,等窗口上出现近端柱子的传送符号时抓准时机,在上面开一扇加速窗。趁浮游柱移动的空档跳进墙上的窗口,就能以高速飞行至对面。接下来玩家会抵达一处塔状的阶梯结构,阶梯底部有个红色水晶,水晶下方与旁边的墙上各有一个传送符号。可想而知,我们得利用墙边的传送符号开个窗,利用隐藏在附近的炸弹除去水晶。北侧有个不断旋转的浮游石,我们先在其中一面的传送符号上开个加速窗,再从红色水晶处的墙边开个窗户,等浮游石上的加速窗回转至对岸时跳进窗口。浮游石的西侧同样有个红色水晶,利用传送窗与炸弹将其炸开后可以取得一个宝箱。抵达对岸后在旁边的墙上开个窗,窗子对面会是阶梯区的红色水晶。用地狱锁链将一旁柱子上的炸弹扯下,再将它丢进窗口,红色水晶就会粉碎,下方的传送符号也会随之上升。以锁链将炸弹取下,趁其爆炸前丢进窗口。将水晶炸开后跟着跳进窗口、步上阶梯,在升起后的传送符号上开个加速窗,再从旁边另外开个窗户跳进去,就能飞到高塔的上层,取得一把钥匙。有了这把钥匙后回到Azrael所在处的回旋平台一路往上走,将顶端的蓝色结界打开,就能朝最后一座堡垒迈进。结界之后是一道大型电梯,启动开关上升后同样会有大量的敌人从上方袭来,将它们全部扫光之后就能顺利抵达顶端。将顶端的闸门打开,War会来到一个圆形的平台,登上平台后又是一场恶战。这场战斗中会出现Conscript的上级版,一手持锤另一手持盾的ShieldLord。ShieldLord除了会以大盾抵挡War的攻击,右手的巨锤也拥有非常惊人之威力,看到它将锤子举高或拉到背后时要尽快拉开距离以免受创,趁它巨锤挥空插地、无法反应的时候再加以反击。另外,ShieldLord会将左手的大盾插地后再挥起,同样也要小心别被击中。打倒所有敌人后,西侧的浮游通路会升起,门后就是最后一座堡垒。通往堡垒的路上有三座浮游平台,这边的解法和前一座堡垒相同,在浮游平台上的传送符号上开窗后传送过去,只不过这次多了第三座浮游平台和其上的红色水晶:我们得从墙边扯下炸弹算准时间往窗里丢,把红色水晶炸开后才能从第二座浮游平台上的窗口跳到最后一座平台,再从平台上跳往堡垒。循通过前一座堡垒的方式,在墙上和两座浮游平台上开启窗户(最后的状态是墙上与第二座平台上各一扇窗)。待第二座平台与第三座平台回旋至正确位置时,玩家可以从墙边的传送窗里看到第三座平台上的红色水晶。预先估算平台的回转时间,从墙上用锁链抓起炸弹。将炸弹丢进平台内,就能把水晶炸开。观察窗口的状况,跳到第三座平台上,就能抵达对面的堡垒。到了堡垒以后会有数波敌人的攻势,包括ShieldLord与RotMauler等大型敌人,将它们全数铲除后才能步入堡垒大门。堡垒内部的大厅正中央有个巨大的圆柱,圆柱前方有个开关,但目前启动后仍无作用。大厅的西北角有个积水的小隔间(水里有个Soldier神器),上头有个传送符号和剑型机关;大厅的西南角有另一个小隔间,隔间的对面有个开关,但隔间高度的落差使得War无法抵达对面。如果我们在西南角的房间墙上开一扇传送窗,再回到西北角的传送符号处另开一扇窗,并且用十字刃启动机关把传送窗降到水里,原本西北角隔间里的水就会流过窗户,把西南角的隔间里充满水,这么一来,War就能游过水洼,启动开关。在西南与西北两处分别启动传送窗,再启动西北角的剑型机关......就能让积水移动到西南侧的隔间。启动开关后,大厅的圆柱两侧会被巨大的卡榫给固定住,回到大厅门口的圆柱前启动先前没有作用的开关,就能把圆柱旋转180度,并在柱子西侧露出一个传送符号。在柱子上开个加速窗,再跳进西北角原本积水处的窗子,就能借冲力飞进东侧的电梯平台,启动开关往上移动,对上最后一台Guardian。头目战:Guardian这次是最后一台Guardian了,对付它的方法和前面两台相同,一样是要跳到头顶关闭护盾后才能攻击。这一次,传送符号从地面上搬到了场地两侧的墙上,两座墙上各有三个传送符号,玩家只要在高低处各开一扇窗,趁Guardian接近时从上空的窗口飞出就可以踏到它的头上,关闭其护盾。打倒Guardian之后,能源束将会投射到入口上方的传送窗处。在下图的两个符号处开启传送窗,就能将电梯旁的闸门打破。把电梯开关上的窗口关闭,再移动到走道底端的灵魂球前方另开一扇窗,就能导引光束将灵魂球充满能量。搭乘电梯下降的同时,大厅会升起数枚反射镜。用十字刃赏右手边的反射镜一镖,就能把能源传到大厅的出口处。离开堡垒回到三座回旋平台处,藉由先前的方法在头两座平台的传送符号上开启窗户,把最后的能源送回BlackThrone内部去。随传送窗回到BlackThrone并走进圆形大厅,正上方会降下一枚浮游石,同时东侧还有个Chronosphere,我们的目标是将能源送到北侧门后的灵魂球上。先在浮游石侧面的两个传送号上开窗,再启动Chronosphere,趁时间减缓时先用十字刃射击浮游石上的开关让它旋转,再赶紧锁定北侧门口左右的两个剑型开关,待时间流逝恢复正常后就能将能源导至门后的灵魂球。#p#副标题#e#启动Chronosphere后先射击浮游石上的开关。跑到北侧的闸门,同时锁定两个开关后再发射十字刃。如此一来就能成功解开这里的谜题。搭乘电梯回到Azrael的所在,和先前相同,在光束投射的路线上开启传送窗,将其引导至最下层的巨大骷髅处,解放Azrael。Azrael表示Straga与BlackThrone这座高塔乃是一体,War想离开此处必得打败Straga,但同时也会永远被困在此处──只有Azrael才能带领他与Watcher平安离开这里。Azrael被囚之处的下方就是通往Straga居所的通道,启动通道底部的电梯沉降至黑塔深处,准备与Straga决一死战。头目战:StragaWar与Straga第二次对上,这次Straga手上多了一根巨锤,上面还有个传送符号;玩家的目标是在巨锤与地面上的传送符号各开一扇窗,趁Straga高举锤子的时候利用传送窗移动到它背上的弱点所在,并予以痛击。先在锤子上开个窗户。再往地上开扇窗。趁Straga高举锤子的时候跳进地上的窗里。降落在它背后的平台上。对准背上弱点按下B键,将浑吞剑狠狠插进去。跳回正面朝Straga的脑袋海扁一顿。赏Straga一顿粗饱之后,它会召唤小兵攻击War,并且用拳头或锤子朝War狠敲。一般的纵向锤打很好闪躲,只要侧闪就能避开,麻烦的是锤子敲地后的横扫攻击,需要抓准时机两段跳才能躲开。玩家可以在场景左右两端的传送符号上各开一扇窗,然后趁巨锤扫来的时候跳进窗子里,就能利用出入传送窗的无敌时间避开攻击。看到Straga手中的锤子发出红光时,表示它即将使用横扫攻击,要赶紧做好逃难的准备。清完一轮敌人并等待Straga的反击结束,Straga会再度将锤子举起,趁这时重复先前的动作利用传送窗移动到他脑后的弱点,重复数轮后就能打倒Straga。打倒了Straga,BlackThrone即将崩毁。Azrael指示War与Watcher穿越灵魂之井,一行人来到了依甸(Eden)。Eden亘古以来早应消灭的Eden,如今竟完整地出现在众人面前。Azrael当初不忍天堂最初之赠礼就此湮灭,故将Eden与其上的知识树(TreeofKnowledge)隐藏了起来。知识树可赋予War对抗Destroyer的方法,然而另一件值得担心的事,是Abaddon死后又出现在Azrael面前,不明所以的Azrael竟将他带来此地,并接触了知识树。没人知道知识树究竟给了Abaddon什么...。谒见知识树之前,长久以来的战斗使得War的身上缠绕着无数的黑影,他得面对自己的黑暗面,才能继续往前。Azrael给了War暗影面具(MaskofShadows),让他能得以发现平时所不能见的幽暗阴影。戴上面具,War的面前出现了另一个自己。头目战:ShadowWar...虽然Azrael说得煞有其事,但War的黑暗面弱得不得了,只要避开他的跳砍与小型剑阵就能轻松打败他。他受到相当的损伤后会变身为浑沌型态,这时玩家只要按下LB键与RT右发射键跟着变身,狂砍一阵就能解决掉他。从此之后,War只要装备并启动暗影面具(按下RT键)就能看见各种隐藏的通路或机关(浮游光球、锁链点等等),如果玩家先前有在BlackThrone取得Fury"sEmbrace的话,离开Eden之后就可以开始尽情nbao4682/">寻宝,解除各种收集类的成就。启动暗影面具越过前方的桥梁,登上前方的山坡就能找到知识树。步上台阶,War接触了世界树,眼前浮现出过去的景象。他看到大战之前Abaddon拉拢了Uriel,却仍败在Straga的手中。一个不明的女声嘲弄着战败的Abaddon,表示自己早就知道并利用了Abaddon的计画。她煽动着Abaddon,一旦议会知道他的所作所为,Abaddon将万劫不复;现在她将给Abaddon一个选择,是要在天堂为奴、还是要在地狱为王──也就是成为Destroyer。接着,War看到了焦灼议会。议会发觉了Abaddon的计画,但由于封印未解,议会没有实据可证明Abaddon的叛心。没有证据,就无从判定正义与否,若让四骑士直接降临人间只会造成无谓的杀戮。于是,议会决定只派出一名骑士,并且赋予他复仇的动力...然后,War看到了未来。Abaddon化成的恶龙Destroyer直攻天堂,War跪倒在地,Watcher夺走了他前方的第七封印。最后,War看见自己的身体被末日之剑给贯穿。在幻象中,War走向自己的尸身,将末日之剑抽起。末日之剑发出令人目眩的光芒,待War醒来时,人已回到Eden,手中不知何时出现了早已粉碎之末日之剑的剑柄。回到Azrael与Watcher等候的地方,War拿出了末日之剑的剑柄,并告诉他们世界树所透露的景象(但隐瞒了自己死于末日之剑),Abaddon/Destroyer将袭击天堂白门,Uriel与地狱戍卫将会败在它的手下。重回人界离开Eden回到人界,Azrael告诉War,Abaddon将末日之剑的碎片分散在世界各处,以免光明力量有机会将其重组。Azrael要War透过暗影面具找出所有的碎片,请Ulthane重新铸成末日之剑。离开之前,War问Azrael为何不在blackThrone或Eden抛下他,Azrael很清楚War将会杀掉所有与Abaddon共谋的人。Azrael幽幽答道:「骑士,我们都得对自己的罪愆负责。当审判的时刻到来,我会欣然迎接。」启动暗影面具度过桥梁,玩家可取得末日之剑的第一块碎片。剩下的六块碎片分布在各个区域,玩家必须启动暗影面具才能看到碎片的所在,不过如果玩家先前取得了Fury"sEmbrace,可以直接在地图上看到它的位置。要是还没拿到,玩家可以回到ScaldingGallow,从Samael原本位置旁边的传送点进入,就能重回BlackThrone拿取。#p#副标题#e#剩下的六个碎片位置分别在:Drownedpass场景中央沉没建筑的顶端,启动暗影面具后用地狱锁链勾住隐藏的锁链点即可取得。theCrossroads在Vulgrim传送点的对面(东南侧)有个建筑物,启动暗影面具后用影翼滑翔配合地狱锁链可以移动到建筑物上,取得碎片。theChokingGrounds以唤土号角叫醒TormentedGate的位置左方有个小洞,从里面可以一路爬上一旁建筑物的顶端,末日之剑的碎片就在里面。这个位置需要用地狱锁链把War拉上墙面。theBrokenStair这个场景的末日之剑碎片就在当初强夺狮鹫兽的建筑上方。theAshLands从Vulgrim的传送点出来左转,沿着山壁走可以发现一个洞穴。进入洞穴后往左侧岔路前进,启动暗影面具后可以发现墙上多了一个炸弹的放置点,用地狱锁链将炸弹扯下来丢到旁边的红色水晶上。回到洞穴入口的分岔点,再度启动暗影面具找出隐藏锁链点的位置,换成锁链往上爬之后就能找到末日之剑的碎片。这里的炸弹放置点需要启动暗影面具才看得见。这里的隐藏锁链点同样需要启动暗影面具。theDryRoad回到Vulgrim传送点悬崖对面的位置,Uriel出乎意料之外地现身于此。她只身来此,依天界戒律向War提出决死之誓(DeathOath),以命相搏。头目战:Uriel这次是玩家第二次对上Uriel,她同样会施展远距离剑气、上升后急降之冲击波与冲刺攻击等先前用过的招式,只要循先前的打法、注意冲击波与冲刺攻击发动前的动作即可。当Uriel受到一定程度的损伤后,她会使用剑雨攻击,不断召唤长剑从空中落下;这招看来虽然吓人,但只要避开长剑落地前的光线轨迹就能轻松躲过。看来很吓人的剑雨攻击,其实只要注意长剑落地前的光线提示就能闪过。War打倒了Uriel,并告诉她Destroyer的真身就是Abaddon。决死之誓已定,War表示自己很快就会讨去Uriel的命,但不是现在。打倒Uriel之后,玩家可以在附近的断墙后找到最后一块碎片。回到Anvil"sFord,Ulthane为War重铸了末日之剑,黑锤落在砧上的响声回荡于人世,有了这柄剑,最终之战就在眼前。终章回到Azrael所在之处,他悲伤地告诉War,正如他的预言,地狱戍卫终将败亡。War要求Azrael助他最后一回,将他送往天堂的白门(WhiteGate)。"一枚陨星从高空直坠白门,从烟尘中现身的不是别人,正是手持新铸末日之剑的War。看见War的到来,天界战士无言地让开了路。Destroyer就在War的面前,右掌抓着Uriel:「她把我...误认为别人了。她爱着那个人。而我相信他也曾爱着她...在很久以前,在这一切发生之前...他愚昧地将责任置于一切之上,并因此而死。」「你会作出同样的决定吗?天堂追捕你,而地狱憎恨你。万物无视你的生死。」Destroyer引诱着War。「...我要给你一个选择,War。你要在天堂为奴,还是要在地狱为王?」「我选择懦弱之人未能选择之道。」这是War的答案。最终战:DestroyerWar与Destroyer的最后决战以天堂之门为舞台,首先对上的是Destroyer的巨龙型态。这场对决的关键在于毁灭天驹的速度,开战时赶紧叫出天驹上马狂奔,才能追击场上飞驰的Destroyer。巨龙型态Destroyer会在场中奔跑,玩家可以趁它正面突击或是停步的空档赏它一剑,只要一剑就能将它砍倒在地(骑乘天驹时),并持续追加攻击。Destroyer起身后会展开还击,其中最危险的是从高空急降的重压攻击,骑乘天驹时抓准时机按下RB键加速就能躲开。简单地说,只要别离开马背就能轻松对付Destroyer的巨龙型态,而砍倒它数次后就能启动过场。高空急降是Destroyer唯一有威胁性的攻击。天使形态抓着Destoryer的War被拖上空中,但他从Destroyer的右翼下方将末日之剑狠狠刺入,使得它从高空坠落地面,穿过地板。War跟着跳入缺口,与变回原形的Abaddon/Destoryer交手。人形的Abaddon主要使用跳纵斩(包括高跳后的重压斩)与回旋斩两种攻击,发现出招动作时以侧闪或拉开距离就能轻松闪避。对他造成一定程度的伤害后,War与Abaddon会以剑较力,此时连打X键就能对他造成重伤。接下来Abaddon会飞到远处以巨大的岩块砸向War,在他抛出岩块的瞬间进行闪避就能躲开。待Abaddon回到地面后重复前面的行动,等到双方第三次拼剑较力时就能彻底将他击败。尾声Abaddon倒地的同时,先前昏迷的Uriel已恢复了意识,来到两人身旁。War拔去了Abaddon的双翼,用末日之剑夺去其性命并拿回了第七封印。这时Watcher突然现身,用魔力制住了War与Uriel。议会很清楚War的荣誉感不会让他滥开杀戒,于是刻意设计他,在封印未破的状态下让War提前降临人界,让他担负背叛律法的罪名,再利用他的复仇心完成整个计画。如今Abaddon/Destroyer已死,War也没了利用价值,正当Watcher要了结War的性命时,Uriel突然捡起末日之剑贯穿了War的身体,并顺势打碎了Watcher手中的封印。封印一碎,War的尸身充满了金色的能量。正当愤怒的Watcher打算杀掉Uriel时,War站了起来,掐住Watcher的左手。死过一次的War完全摆脱了Watcher的控制,无视他的任何哀求与威胁,活活掐碎了他的首级。Uriel的身侧多了数名天使,她质问War是否早已知道事情的发展,当初一战才饶她不死。War却说,他不取她性命的原因并非如此,而是不希望天堂的最后一丝尊严随其英雄逝去而消失。Uriel表示两人恩怨一笔勾销,他日两人若再度为敌,将不会手下留情。话虽如此,当War不发一语而转身离去时,Uriel仍急切地追问:「你会被追捕的!白城肯定会...焦灼议会...还有...还有其他人!你要独自一人向他们宣战吗?!」「不。我并非一人。」War开口的同时,天边有三枚陨星急坠而下。〈全剧终〉#p#副标题#e#
2023-08-19 18:14:581

js技巧之十几行的代码实现vue.watch代码

第一个参数,被构造的属性的this指向的对象 第二个参数,被构造的属性名 第三个参数,构造的规则(上面的文字链接最后面有介绍)(function () { var o = { a : 1}//声明一个对象,包含一个 a 属性,值为1 Object.defineProperty(o,"b",{ get: function () { return this.a; }, set : function (val) { this.a = val; }, configurable : true }); console.log(o.b);//==> 1 o.b = 2; console.log(o.b);//==> 2})();configurable是指 "b" 是否可以被再配置,默认是false。false的话Object.defineProperty(o,"a",{set : function(val){}} );再修改时会不起作用或者报错,一般默认false。构造我们的vue.watch目标实现,以下是我们想要的达到的效果import watcher from "./watcher.js";let wm = new watcher({ data:{ a: 0 }, watch:{ a(newVal,oldVal){ console.log("newVal:"+newVal); console.log("oldVal:"+oldVal); } }})vm.a = 1 // newVal:1// oldVal:0创建构造对象class watcher{ constructor(opts){ this.$data = opts.data; for(let key in opts.data){ this.setData(key,opts.data[key]) } } setData(_key,_val){ Object.defineProperty(this,_key,{ get: function () { return this.$data[_key]; }, set : function (val) { const oldVal = this.$data[_key]; if(oldVal === val)return val; this.$data[_key] = val; return val; }, }); }}export default watcher;添加 watch事件触发/** * @desc 属性改变监听,属性被set时出发watch的方法,类似vue的watch * @author Jason * @date 2018-04-27 * @constructor * @param {object} opts - 构造参数. @default {data:{},watch:{}}; * @argument {object} data - 要绑定的属性 * @argument {object} watch - 要监听的属性的回调 * watch @callback (newVal,oldVal) - 新值与旧值 */class watcher{ constructor(opts){ this.$data = this.getBaseType(opts.data) === "Object" ? opts.data : {}; this.$watch = this.getBaseType(opts.watch) === "Object" ? opts.watch : {}; for(let key in opts.data){ this.setData(key) } } getBaseType(target) { const typeStr = Object.prototype.toString.apply(target); return typeStr.slice(8, -1); } setData(_key){ Object.defineProperty(this,_key,{ get: function () { return this.$data[_key]; }, set : function (val) { const oldVal = this.$data[_key]; if(oldVal === val)return val; this.$data[_key] = val; this.$watch[_key] && typeof this.$watch[_key] === "function" && ( this.$watch[_key].call(this,val,oldVal) ); return val; }, }); }}export default watcher; 为了函数内部的健壮性,getBaseType是用来做类型校验的。 Object.defineProperty(this),this把上下文指向当前对象。 this.$watch[_key].call(this,val,oldVal),把监听事件的上下文页绑定到当前对象,方便在watch内通过this获取对象内的值,如下let wm = new watcher({ data:{ a: 0, b: "hello" }, watch:{ a(newVal,oldVal){ console.log(this.b); } }})总结有人可能会问为什么不直接用vue呢。你也知道vue是一个工程级别的框架,做比较大的项目当然是用vue,react;但是单单做一个展示性的官网或者做个移动端的H5宣传页也用上vue吗?那当然是没有必要的。用上这一个watcher类,可以让你页面的状态控制有条理、有迹可循。比如几个按钮联动一个或几个视图的改变和动效的时候,你就不用在每个按钮的click时都触发一下修改 btn1.onclick=function(){ var a = "haha"; document.getElementById("id").innerHTML = a; } btn2.onclick=function(){ var a = "xixi"; document.getElementById("id").innerHTML = a; }let wm = new watcher({ data:{ a: "", }, watch:{ a(newVal,oldVal){ document.getElementById("id").innerHTML = newVal; } }})btn1.onclick=function(){ wm.a = "haha"; } btn2.onclick=function(){ wm.a = "xixi"; }但是如果你的视图不被2个以上动作联动的话,也未必会用上。
2023-08-19 18:15:251

中国十大望远镜品牌(中国十大望远镜品牌熊猫)

导语:望远镜就是人们水的千里镜是一种能够放大远处物体让你看清远处的美景的一种光学仪器。现在很多人出门旅行喜欢带这些东西,那么大家知道什么牌子的望远镜好用吗?下面网为大家盘点了中国十大望远镜品牌,一起来看看。中国十大望远镜品牌一、博冠BOSMA博冠BOSMA是广州博冠光电科技股份有限公司旗下的一个著名的额望远镜品牌企业,专业从事双筒望远镜和枪用瞄准镜以及天文望远镜等光电仪器的研发和生产销售的高新技术企业,成立于2000年,总部位于诡案组在北京和美国等地区有营销中心。发源地:广东省广州市创立时间:2000年二、熊猫牌PANDABRAND熊猫牌PANDABRAND望远镜是云南省昆明市知名的望远镜品牌,成立于1936年在中国市场的口碑还不错,从事夜视产品科研和生产销售服务,在中国十大望远镜品牌中是一个老牌望远镜品牌企业,公司业务涉及夜视仪器和眼镜以及房地产和建筑工程等多个领域。创立时间:1936年排行榜,品牌排行榜发源地:云南省昆明市三、星达Sky-Watcher星达Sky-Watcher是中国台湾知名望远镜品牌,成立于1988年是一家专业从事高端高精度望远镜产品的研发和销售服务的品牌企业,发展30年不断创新发展目前业务遍及世界50多个国家和地区,称为国际知名望远镜品牌。创立时间:1988年发源地:中国台湾四、立可达NIKULA立可达NIKULA是广东省佛山市知名的望远镜品牌企业,成立于1996年专业从事望远镜和零配件等产品的研发和设计以及销售。在中国十大望远镜品牌中深受广大望远镜品牌企业的肯定和认可,赢得国内消费者的喜爱。创立时间:1996年发源地:广东省佛山市五、耐尔思NAIRC耐尔思是中科院南京光电仪器公司企业的一个从事天文仪器产品的高新技术企业。成立于1958年,在中国十大望远镜品牌中排名第五,产品包括大中小型天文仪器和望远镜以及恒星观测仪器、人造卫星观测仪器等多个产品的销售服务。创立时间:1958年发源地:江苏省南京市六、天狼TIANLANG天狼是北京北京天狼深空光电科技公司企业的一个从事望远镜产品的生产和销售的企业,在中国市场有很好的口碑和良好的企业形象,享誉国内。成立于2000年,产品包括望远镜以及天文仪器设备等,高性价比和良好的质量赢得各大学校的和用户的认可。创立时间:2000年发源地:北京市七、湛京ZHANJING湛京是浙江省宁波市湛京光学仪器公司旗下的一个知名望远镜品牌企业,从事照相机以及影视设备和望远镜产品的大型企业,这个牌子的产品款式新颖质量很好,操作很方便赢得很多用户的好评。创立时间:2002年八、远达YD远达YD是云南昆明一个从事望远镜生产的大型企业,拥有自己的生产基地,从事各种望远镜和高级透镜等产品的研发和销售,品牌产品种类齐全质量可靠,产品远销到美国和欧洲等国家,是一个实力雄厚的外向型企业。创立时间:1994年发源地:云南省昆明市九、波斯猫CATOPTICS波斯猫CATOPTICS是广州一个从事光电仪器的品牌公司,这个品牌在北京和美国等地区设有营销中心,是中国十大望远镜品牌之一,从事双筒望远镜和红外夜视仪以及天文望远镜等多个产品的企业,业务涉及到医疗健康和个人消费等多个领域。创立时间:2014年发源地:广东省广州市十、威信Vixen威信Vixen是上海一个实力雄厚的远镜企业,从事天文望远镜以及夜视仪等产品的研发和销售的企业,成立于1949年,产品质量可靠远销到世各地,这个公司规模庞大,专业销售各种进口品牌望远镜产品以及配件等。创立时间:1949年
2023-08-19 18:15:331

李臬因食道癌去世,他生前有过哪些优秀作品?

李臬是韩国资深男演员,他生前的优秀作品有Stove League ,Live,虽然是精神病但没关系等。他留给大家的最后一部作品是无间对决,很多熟悉他的观众都觉得他的去世挺可惜的。李臬曾经在虽然是精神病但没关系中扮演徐睿知的爸爸高大焕 ,高大焕是一名建筑师,他患了脑瘤,最后变成了老年痴呆,这个角色很难演,可是李臬把他演活了。很多观众称他为徐爸爸,李臬就是一个演技派,入道多年,演戏经验丰富,得到了同行和观众的认可。有一些演员虽然长得不帅,但是演技好,所以他的资源也不错,直到他去世前还在拍戏,也算是一个非常敬业的演员。李臬在Live里饰演警卫李三宝 ,这部剧被观众称为疗愈剧,李臬的演技绝对是实力派,他扮演的李三宝这个人物看哭很多观众。Live这部剧也是韩国的人气剧,大家对这位实力派演员也是大加赞赏。李臬还在Stove League 中饰演重要角色,还演过Watcher,Move to Heaven:我是遗物整理师,Voice 4 ,82年生的金智英 ,再次十八岁 等。58岁的李臬的演艺事业一直很好,非常可惜在拍完Voice 4后就检查出了癌症,他面对癌症一直很乐观,在积极地配合医生治疗,很可惜还是难敌病魔,从发现到去世只有10个月的时间,真是太可惜了。娱乐圈的明星因为癌症去世的人也不少,比如我们熟悉的达叔,廖启智,李媛媛,傅彪等。生活充满了太多无奈,虽然演员看上去很光彩照人,但是他们的生活没有规律,还要注意节食,经常熬夜拍片,时间长了就会生病。希望这些老戏骨,实力派能好好保重身体,给我们带来更多精彩的影视剧作品。
2023-08-19 18:15:414

zkwatch数量与什么有关

zkWatcher的数量与Zookeeper集群中注册在一个节点上的客户端的数目有关。因为zkWatcher指的是客户端和ZooKeeper服务器之间的通信,当客户端在ZooKeeper的节点上注册watcher时会与ZooKeeper服务器保持连接,从而导致zkWatcher的数量增加。如果ZooKeeper集群中注册的客户端数量很多,那么zkWatcher的数量也会相应地增加。这可能会导致ZooKeeper服务器的性能问题,因为服务器必须同时处理所有客户端的请求,包括watcher的事件通知。因此,需要合理控制客户端的请求量和watcher的数量,以避免ZooKeeper服务器性能的问题。
2023-08-19 18:16:311

推荐几首欧美的气势澎湃的纯音乐

the mass听听这个,百度下。。。
2023-08-19 18:16:413

birdwatcher是什么意思

birdwatcher鸟类观察家,野鸟观察者
2023-08-19 18:16:482

《暗黑血统》第一部剧情什么意思啊?结局怎么样的?为什么war会一个人出来?

第七封印没有解开,但WAR却被召唤了过来,然后力量就被封印了,最后杀了哑巴吨,然后第七封印解开,其余三位也来到了人间
2023-08-19 18:16:572

《Watcher》这部剧评价如何?

剧情精彩,剧情精彩
2023-08-19 18:17:1910

The "Watcher" 歌词

歌曲名:The "Watcher"歌手:Fringe专辑:Believe...Dr.Dre - The WatcherThings just ain"t the same for gangstas.Times is changing, young niggas is aging,Becoming old gees in the game and changing,To make way for these new names and faces, butThe strangest things can happen from rappin, whenNiggas get wrapped up in image and acting,Niggas get capped up and wrapped in plastic,Zipped up in bags when it happens, that"s it.I"ve seen "em come; I"ve watched "em go,Watched "em rise, witnessed it and watched "em blow.Watched "em all blossom and watched "em grow.Watched the lawsuits when they lost the dough.Best friends and money: I lost them both.Went, visited niggas in the hospital.It"s all the same shit all across the globe.I just sit back and watch the show. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)I moved out of the hood for good, you blame me?Niggas aim mainly at niggas they can"t be.But niggas can"t hit niggas they can"t see.I"m out of sight, now I"m out of they dang reach.How would you feel if niggas wanted you killed?You"d probably move to a new house on a new hill.And choose a new spot if niggas wanted you shot,I ain"t a thug, how much Tupac in you, you gotI ain"t no bitch neither.It"s either my life or your life,And I ain"t leaving, I like breathing.Nigga we can go round for round,Clip for clip, shit, fo"-pound for pound.Nigga if you really want to take it there we can,Just remember that you fucking with a family man.I got a lot more to lose than you, remember that,When you wanna come and fill these shoes. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)Things just ain"t the same for gangstas,Cops is anxious to put niggas in handcuffs.They wanna hang us, see us dead, enslave us,Keep us trapped in the same place we"re raised in.Then they wonder why we act so outrageous,Run around stressed out and pull out gauges.Cause everytime you let the animal out cages,It"s dangerous to people who look like strangers.But now we got a new era of gangstas,Hustlers and youngsters living amongst us.Lookin at us, now calling us busters,Can"t help but reminisce back when it was us.Nigga we started this gangsta shit.And this the motherfucking thanks I get?It"s funny how time fly,I"m just having fun, just watching it fly by. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)(The watcher)EndDr.Dre - The Watcherhttp://music.baidu.com/song/15091810
2023-08-19 18:18:211

守夜人英文

守夜人英文:night watcher;night-watcher。守夜人英文例句:1、自由放任和守夜人的说法,或者完士是一种理想,或者纯属虚构的神话。The dogma of laissez-faire and night watcher is either a pure ideal or a myth。2、任何国家要想永保军事优势,纯属幻想。自由放任和守夜人的说法,或者完士是一种理想,或者纯属虚构的神话。Any country on permanent military supremacy has become illusory. The dogma of laissez-faire and night watcher is either a pure ideal or a myth。守夜人相关介绍:守夜人军团,是乔治·马丁系列作品《冰与火之歌》中一个组织,专职防御维斯特洛的领土。守夜人军团是北境长城上的守备军,为阻挡长城以北的野人以及传说生物而存在,古时是被称为“黑骑士”的高贵军团,现时是七大王国流放者和罪犯的收容所,依旧守卫着北方。
2023-08-19 18:18:291

The Watcher 歌词

歌曲名:The Watcher歌手:The Guess Who专辑:Artificial ParadiseDr.Dre - The WatcherThings just ain"t the same for gangstas.Times is changing, young niggas is aging,Becoming old gees in the game and changing,To make way for these new names and faces, butThe strangest things can happen from rappin, whenNiggas get wrapped up in image and acting,Niggas get capped up and wrapped in plastic,Zipped up in bags when it happens, that"s it.I"ve seen "em come; I"ve watched "em go,Watched "em rise, witnessed it and watched "em blow.Watched "em all blossom and watched "em grow.Watched the lawsuits when they lost the dough.Best friends and money: I lost them both.Went, visited niggas in the hospital.It"s all the same shit all across the globe.I just sit back and watch the show. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)I moved out of the hood for good, you blame me?Niggas aim mainly at niggas they can"t be.But niggas can"t hit niggas they can"t see.I"m out of sight, now I"m out of they dang reach.How would you feel if niggas wanted you killed?You"d probably move to a new house on a new hill.And choose a new spot if niggas wanted you shot,I ain"t a thug, how much Tupac in you, you gotI ain"t no bitch neither.It"s either my life or your life,And I ain"t leaving, I like breathing.Nigga we can go round for round,Clip for clip, shit, fo"-pound for pound.Nigga if you really want to take it there we can,Just remember that you fucking with a family man.I got a lot more to lose than you, remember that,When you wanna come and fill these shoes. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)Things just ain"t the same for gangstas,Cops is anxious to put niggas in handcuffs.They wanna hang us, see us dead, enslave us,Keep us trapped in the same place we"re raised in.Then they wonder why we act so outrageous,Run around stressed out and pull out gauges.Cause everytime you let the animal out cages,It"s dangerous to people who look like strangers.But now we got a new era of gangstas,Hustlers and youngsters living amongst us.Lookin at us, now calling us busters,Can"t help but reminisce back when it was us.Nigga we started this gangsta shit.And this the motherfucking thanks I get?It"s funny how time fly,I"m just having fun, just watching it fly by. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)(The watcher)EndDr.Dre - The Watcherhttp://music.baidu.com/song/9105269
2023-08-19 18:18:491

如何使用vue数据控制视图

这次给大家带来如何使用vue数据控制视图,使用vue数据控制视图的注意事项有哪些,下面就是实战案例,一起来看一下。前记三个月前看了vue源码来分析如何做到响应式数据的, 文章名字叫vue源码之响应式数据, 最后分析到, 数据变化后会调用Watcher的update()方法. 那么时隔三月让我们继续看看update()做了什么. (这三个月用react-native做了个项目, 也无心总结了, 因为好像太简单了).本文叙事方式为树藤摸瓜, 顺着看源码的逻辑走一遍, 查看的vue的版本为2.5.2. 我fork了一份源码用来记录注释.目的明确调查方向才能直至目标, 先说一下目标行为: 数据变化以后执行了什么方法来更新视图的. 那么准备开始以这个方向为目标从vue源码的入口开始找答案.从之前的结论开始先来复习一下之前的结论:vue构造的时候会在data(和一些别的字段)上建立Observer对象, getter和setter被做了拦截, getter触发依赖收集, setter触发notify.另一个对象是Watcher, 注册watch的时候会调用一次watch的对象, 这样触发了watch对象的getter, 把依赖收集到当前Watcher的deps里, 当任何dep的setter被触发就会notify当前Watcher来调用Watcher的update()方法.那么这里就从注册渲染相关的Watcher开始.找到了文件在src/core/instance/lifecycle.js中.new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */)mountComponent渲染相关的Watcher是在mountComponent()这个方法中调用的, 那么我们搜一下这个方法是在哪里调用的. 只有2处, 分别是src/platforms/web/runtime/index.js和src/platforms/weex/runtime/index.js, 以web为例:Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean): Component { el = el && inBrowser ? query(el) : undefined return mountComponent(this, el, hydrating)}原来如此, 是$mount()方法调用了mountComponent(), (或者在vue构造时指定el字段也会自动调用$mount()方法), 因为web和weex(什么是weex?之前别的文章介绍过)渲染的标的物不同, 所以在发布的时候应该引入了不同的文件最后发不成不同的dist(这个问题留给之后来研究vue的整个流程).下面是mountComponent方法:export function mountComponent ( vm: Component, el: ?Element, hydrating?: boolean): Component { vm.$el = el // 放一份el到自己的属性里 if (!vm.$options.render) { // render应该经过处理了, 因为我们经常都是用template或者vue文件 // 判断是否存在render函数, 如果没有就把render函数写成空VNode来避免红错, 并报出黄错 vm.$options.render = createEmptyVNode if (process.env.NODE_ENV !== "production") { /* istanbul ignore if */ if ((vm.$options.template && vm.$options.template.charAt(0) !== "#") || vm.$options.el || el) { warn( "You are using the runtime-only build of Vue where the template " + "compiler is not available. Either pre-compile the templates into " + "render functions, or use the compiler-included build.", vm ) } else { warn( "Failed to mount component: template or render function not defined.", vm ) } } } callHook(vm, "beforeMount") let updateComponent /* istanbul ignore if */ if (process.env.NODE_ENV !== "production" && config.performance && mark) { // 不看这里的代码了, 直接看else里的, 行为是一样的 updateComponent = () => { const name = vm._name const id = vm._uid const startTag = `vue-perf-start:${id}` const endTag = `vue-perf-end:${id}` mark(startTag) const vnode = vm._render() mark(endTag) measure(`vue ${name} render`, startTag, endTag) mark(startTag) vm._update(vnode, hydrating) mark(endTag) measure(`vue ${name} patch`, startTag, endTag) } } else { updateComponent = () => { vm._update(vm._render(), hydrating) } } // we set this to vm._watcher inside the watcher"s constructor // since the watcher"s initial patch may call $forceUpdate (e.g. inside child // component"s mounted hook), which relies on vm._watcher being already defined // 注册一个Watcher new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */) hydrating = false // manually mounted instance, call mounted on self // mounted is called for render-created child components in its inserted hook if (vm.$vnode == null) { vm._isMounted = true callHook(vm, "mounted") } return vm}这段代码其实只做了3件事:调用beforeMount钩子建立Watcher调用mounted钩子(哈哈哈)那么其实核心就是建立Watcher了.看一下Watcher的参数: vm是this, updateComponent是一个函数, noop是空, null是空, true代表是RenderWatcher.在Watcher里看了isRenderWatcher:if (isRenderWatcher) { vm._watcher = this }是的, 只是复制了一份用来在watcher第一次patch的时候判断一些东西(从注释里看的, 我现在还不知道是干嘛的).那么只有一个问题没解决就是updateComponent是个什么东西.updateComponent在Watcher的构造函数的第二个参数传了function, 那么这个函数就成了watcher的getter. 聪明的你应该已经猜到, 在这个updateComponent里一定调用了视图中所有的数据的getter, 才能在watcher中建立依赖从而让视图响应数据的变化.updateComponent = () => { vm._update(vm._render(), hydrating) }那么就去找vm._update()和vm._render().在src/core/instance/render.js找到了._render()方法.Vue.prototype._render = function (): VNode { const vm: Component = this const { render, _parentVnode } = vm.$options // todo: render和_parentVnode的由来 // reset _rendered flag on slots for duplicate slot check if (process.env.NODE_ENV !== "production") { for (const key in vm.$slots) { // $flow-disable-line vm.$slots[key]._rendered = false } } if (_parentVnode) { vm.$scopedSlots = _parentVnode.data.scopedSlots || emptyObject } // set parent vnode. this allows render functions to have access // to the data on the placeholder node. vm.$vnode = _parentVnode // render self let vnode try { vnode = render.call(vm._renderProxy, vm.$createElement) } catch (e) { // catch其实不需要看了, 都是做异常处理, _vnode是在vm._update的时候保存的, 也就是上次的状态或是null(init的时候给的) handleError(e, vm, `render`) // return error render result, // or previous vnode to prevent render error causing blank component /* istanbul ignore else */ if (process.env.NODE_ENV !== "production") { if (vm.$options.renderError) { try { vnode = vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e) } catch (e) { handleError(e, vm, `renderError`) vnode = vm._vnode } } else { vnode = vm._vnode } } else { vnode = vm._vnode } } // return empty vnode in case the render function errored out if (!(vnode instanceof VNode)) { if (process.env.NODE_ENV !== "production" && Array.isArray(vnode)) { warn( "Multiple root nodes returned from render function. Render function " + "should return a single root node.", vm ) } vnode = createEmptyVNode() } // set parent vnode.parent = _parentVnode return vnode }}这个方法做了:根据当前vm的render方法来生成VNode. (render方法可能是根据template或vue文件编译而来, 所以推论直接写render方法效率最高)如果render方法有问题, 那么首先调用renderError方法, 再不行就读取上次的vnode或是null.如果有父节点就放到自己的.parent属性里.最后返回VNode所以核心是这句:vnode = render.call(vm._renderProxy, vm.$createElement)其中的render(), vm._renderProxy, vm.$createElement都不知道是什么.先看vm._renderProxy: 是initMixin()的时候设置的, 在生产环境返回vm, 开发环境返回代理, 那么我们认为他是一个可以debug的vm(就是vm), 细节之后再看.vm.$createElement的代码在vdom文件夹下, 看了下是一个方法, 返回值一个VNode.render有点复杂, 能不能以后研究, 总之就是把template或者vue单文件和mount目标parse成render函数.小总结: vm._render()的返回值是VNode, 根据当前vm的render函数接下来看vm._update()Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) { const vm: Component = this if (vm._isMounted) { callHook(vm, "beforeUpdate") } // 记录update之前的状态 const prevEl = vm.$el const prevVnode = vm._vnode const prevActiveInstance = activeInstance activeInstance = vm vm._vnode = vnode // Vue.prototype.patch is injected in entry points // based on the rendering backend used. if (!prevVnode) { // 初次加载, 只有_update方法更新vm._vnode, 初始化是null // initial render vm.$el = vm.patch( // patch创建新dom vm.$el, vnode, hydrating, false /* removeOnly */, vm.$options._parentElm, vm.$options._refElm ) // no need for the ref nodes after initial patch // this prevents keeping a detached DOM tree in memory (#5851) vm.$options._parentElm = vm.$options._refElm = null } else { // updates vm.$el = vm.patch(prevVnode, vnode) // patch更新dom } activeInstance = prevActiveInstance // update vue reference if (prevEl) { prevEl.vue = null } if (vm.$el) { vm.$el.vue = vm } // if parent is an HOC, update its $el as well if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { vm.$parent.$el = vm.$el } // updated hook is called by the scheduler to ensure that children are // updated in a parent"s updated hook. }我们关心的部分其实就是patch()的部分, patch()做了对dom的操作, 在_update()里判断了是否是初次调用, 如果是的话创建新dom, 不是的话传入新旧node进行比较再操作.结论vue的视图渲染是一种特殊的Watcher, watch的内容是一个函数, 函数运行的过程调用了render函数, render又是由template或者el的dom编译成的(template中含有一些被observe的数据). 所以template中被observe的数据有变化触发Watcher的update()方法就会重新渲染视图.相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!推荐阅读:如何正确解决Vue 项目中遇到跨域问题怎样使用React高阶组件
2023-08-19 18:18:561

C#的FileSystemWatcher监视没有反应,请问是为什么,代码如下

wpf的文件监视参照网页链接
2023-08-19 18:19:041

The Watcher (1996 Digital Remaster) 歌词

歌曲名:The Watcher (1996 Digital Remaster)歌手:Hawkwind专辑:Doremi Fasol LatidoDr.Dre - The WatcherThings just ain"t the same for gangstas.Times is changing, young niggas is aging,Becoming old gees in the game and changing,To make way for these new names and faces, butThe strangest things can happen from rappin, whenNiggas get wrapped up in image and acting,Niggas get capped up and wrapped in plastic,Zipped up in bags when it happens, that"s it.I"ve seen "em come; I"ve watched "em go,Watched "em rise, witnessed it and watched "em blow.Watched "em all blossom and watched "em grow.Watched the lawsuits when they lost the dough.Best friends and money: I lost them both.Went, visited niggas in the hospital.It"s all the same shit all across the globe.I just sit back and watch the show. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)I moved out of the hood for good, you blame me?Niggas aim mainly at niggas they can"t be.But niggas can"t hit niggas they can"t see.I"m out of sight, now I"m out of they dang reach.How would you feel if niggas wanted you killed?You"d probably move to a new house on a new hill.And choose a new spot if niggas wanted you shot,I ain"t a thug, how much Tupac in you, you gotI ain"t no bitch neither.It"s either my life or your life,And I ain"t leaving, I like breathing.Nigga we can go round for round,Clip for clip, shit, fo"-pound for pound.Nigga if you really want to take it there we can,Just remember that you fucking with a family man.I got a lot more to lose than you, remember that,When you wanna come and fill these shoes. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)Things just ain"t the same for gangstas,Cops is anxious to put niggas in handcuffs.They wanna hang us, see us dead, enslave us,Keep us trapped in the same place we"re raised in.Then they wonder why we act so outrageous,Run around stressed out and pull out gauges.Cause everytime you let the animal out cages,It"s dangerous to people who look like strangers.But now we got a new era of gangstas,Hustlers and youngsters living amongst us.Lookin at us, now calling us busters,Can"t help but reminisce back when it was us.Nigga we started this gangsta shit.And this the motherfucking thanks I get?It"s funny how time fly,I"m just having fun, just watching it fly by. (The watcher)Chorus:Everywhere that I goAin"t the same as befo" (The watcher)People I used to knowJust don"t know me no more (The watcher)But everywhere that I goI got people I know (The watcher)Who got people they knowSo I suggest you lay low (I watch)(The watcher)EndDr.Dre - The Watcherhttp://music.baidu.com/song/2755970
2023-08-19 18:19:231

为什么我一进火线就出来一个方框,上面写着cf file watcher d/穿越火线.

重新安装一下,或者去腾讯那里检查一下游戏
2023-08-19 18:20:0810

空洞骑士守望者骑士怎么打

空洞骑士boss暴怒守卫打法嗨嗨嗨,弟兄们好,我是奕臣,今日又来更新文章了!上期刚打完残旧器皿,拿了二段跳,我马上就想到了水晶山峰也有一个boss没有打完,那便是水晶守护的加强版——愤怒守护。这个家伙上次没有彻底击败,他逃往了二楼,当时的我们都还没二段跳(帝王之翼),打不了他。因此,我一取得二段跳后,马上就来到水晶山峰处理他。(愤怒守护:作者这个老六,我真的是服了嗷!)那么这个boss与以前相比,又有什么变化呢,大家一起来看看吧。首先最大的变化便是他的损害,这从他发激光的颜色转变就能看出,颜色由原先的偏紫色变成了偏黄色,损害也从原本的伤一滴血变成几滴,这就要求我们应该降低失误频次;此外便是他的攻速有所提高,但是他的攻击方式还是没有转变,仍然是那三板斧。下面正式说一下他的三板斧,额,是攻击方式:一、发送激光。他会看准大家,随后蓄气传出激光。躲法很简单,大家只要等他蓄气时,随后高跳,便是长按跳跃键,随后就能躲过。二、招唤激光。他会传出叫声,随后招唤四道小一点的激光,从上边贯彻到下面,呈不同的角度,可是每一道激光都会略微错开,进而有间隙使我们避开。三、跳跃。他会随机跳起,跳跃间距可远可近,加强版的他一般是长距离跳跃,从一边跳至另一边。打进他们的概率大大提高了。此外,他在招唤激光后,是会直接进行下一招的,会发送激光或是跳跃,四道激光可能遮挡他们的去向。如下图:推荐玩法是少冲刺,只在关键时候冲刺避开损害,总是冲刺容易被激光打进。此外,最好不要加血,争取一次打了,因为他会不停地进攻,找不着回血的机遇。总要玩法还是和水晶守护差不多,但是我们要减少失误的频次,毕竟大家挨不了两下他的进攻,总之,理智打就行了,总之椅子就在下面,打不了失败了接着来便是了。打过他,大家就能取得一个生命残片,接着去水晶山峰的最高点圣巢之冠,在浮光的雕像下面取得一块惨白矿石,那样大家骨钉升级伟业又进了一步。回播播放00:00/00:00正在直播00:00进到全屏点击按着可拖拽视频这里是奕臣爱游戏,感觉文章还不错,就为我点赞吧!感谢大家的阅读收看,下期见,再见。。。空洞骑士空洞骑士怎么打?空洞骑士发动进攻时会有一个起手动作,会有短暂的停顿,这个时候可以用二段跳或是二段跳躲过去,随后伺机打两刀,在空洞骑士自虐时能够多砍两刀或是加血,那样就可以打过了空洞骑士守望者尖塔完美过关方法介绍空洞骑士守望者尖塔极致过关方法介绍,守望者尖塔其实没有想象中的那么难,下面小编为大家讲解一下迅速过关的方法,都还没过关的玩家不妨来参考一下,相信对大家会有所协助。方法一:带无脑毒胞子加血就和负伤无敌时间延长再带个速斩。武器最终两阶段都可以打。方法二:黑暗冲刺有损害加蜂蜜血加螳螂刀,变为滚球就用冲刺正面穿方法三:在戴蓝耗降低,法强提升,负伤回蓝。在两基佬同处一边时三变黑吼能够同时灭掉2个。方法四:左侧开战前有暗道能够上来做掉台灯砸死一个。空洞骑士守望者骑士吊灯怎么打?进来前先从左侧上来,做掉一个吊灯,就会打烂一个骑士,剩余五个骑士,先用梦之钉打一下,补充法术能量,开战后,利用下冲的无敌,在2个骑士中间持续下冲,反复几回以后就能打过去了。空洞骑士守望者的尖塔怎么进?守望者的尖塔要去打那个得要有二段跳二段跳,从远古盆地做掉残破溶剂拿空洞骑士人物详解?该作叙述是指一个名叫德特茅斯的没落小镇下埋藏着一个古老的废弃帝国,名叫圣巢。这个帝国被疫情所腐蚀而废弃,废弃的原因则是由于名叫辐光的光之古神,她能通过观念来传播瘟疫,被疫情腐蚀的虫子都会被本能所支配,丧失心智。这个王国的主人——惨白之王,自然不会坐视不管,他在圣巢范畴下的谷底,运用另一种远古能量“虚空”能够抑制光辉的特点,制造了器皿一族。其中一位被选定的器皿用于封印疫情,并被命名为空洞骑士。为了封印的牢固,白王找寻了三个守梦人来进一步巩固封印,三位守梦人的名字各自为守望者-卢瑞恩,导师-莫诺蒙,猛兽-赫拉。但以后惨白之王去向不明,不完美的器皿的能量的也变得慢慢孱弱,最后被辐光控制。主角就要越过圣巢的各地,在长眠之地中,大家遭受以前辐光的教徒和眷族——飞蛾族唯一留下的族人的协助,得到了和辐光能量同源的梦之武器——梦之钉。梦之钉能够读取生物内心的想法,并能够打破守梦人的维护,进到到其梦镜当中杀死守梦人。杀死了三位守梦人并解除封印后,可选的结果有抵达十字路里的黑卵圣殿击败空洞骑士或去到在“寻神者”升级中新添加的地点“神居”并挑战圣巢万神殿。空洞骑士全成就?BossFalsehood虚假-假骑士Strength(隐)健壮-失败冠军TestofResolve决心测试-在苍绿之径打败大黄蜂ProofofResolve(隐)决心证实-在帝国边境打败大黄蜂Respect尊重-螳螂领主Illumination照明-灵魂大师Mortality(隐)身亡-灵魂暴君Release释放-残旧器皿Peace(隐)和平-失望血亲Honour荣誉-粪虫防御者(芬达)Obsession(隐)痴迷-收藏者Execution处死-反贼君主Rivalry(隐)恩怨-在试炼场1里打败佐特Teacher-老师Watcher-守望者Beast-猛兽
2023-08-19 18:20:391

C#中如何获得被复制文件的文件名和路径?

foreach (string s in Clipboard.GetFileDropList()) { Console.WriteLine(s); } Console.ReadLine();
2023-08-19 18:20:492

CF CF File Watcher是什么意思 到底怎么了

你丢失了一个 东西 、重下CF吧
2023-08-19 18:21:006

跪求好心人分享USBwatcher(U盘监视工具) V1.0 绿色中文版软件免费百度云资源

链接:提取码:2w6n软件名称:USBwatcher(U盘监视工具)V1.0绿色中文版语言:简体中文大小:10.27MB类别:系统工具介绍:USBwatcher是一款强大实用的监听U盘的软件。它可以检测插入电脑中的U盘,并查看U盘当中的文件,自带防检测功能,防止自己的U盘被检测,还可以后台复制U盘的文件。
2023-08-19 18:21:161

c# 一调用到textbox.text赋值就会自动退出

退出的错误是什么呢?
2023-08-19 18:21:368

C#编写控制台程序,实时监测某个文件夹内是否有文件增加

做个定时器,程序启动的时候获取一次文件列表,记录下来,下次扫描的时候和本地保存的列表进行比对,有新的就更新下来。
2023-08-19 18:21:542

如何查看是否有人正在使用我的无线网络——Wireless Network Watcher

现在有一个更好的方法来检测您的无线网络连接的计算机——Wireless Network Watcher。Wireless Network Watcher使用起来非常简单,只需安装启动,它会自动开始扫描您的IP范围,显示你的IP地址,设备名称,MAC地址,网?络适配器公司,设备信息,用户的文本和检测与计数日期。在高级选项,您可以选择使用哪个网络适配器进行扫描,也可手动指定IP范围。
2023-08-19 18:22:021

file watcher什么意思

file watcher文件监视器;案监控程式;档案接取监控例句1.One file system watcher event provider and one custom, non-hosted event provider.一个文件系统观察器事件提供程序和一个自定义、非宿主事件提供程序。2.The file system watcher event provider might fail if the performance counters on the server become corrupted .如果服务器上的性能计数器损坏,则可能导致文件系统观察器事件提供程序失败。3.Events submitted to the file system watcher event provider must be in XML format .提交到文件系统观察器事件提供程序的事件必须采用XML格式。
2023-08-19 18:22:181

如何进行Vue数据双向绑定实现

这次给大家带来如何进行Vue数据双向绑定实现,进行Vue数据双向绑定实现的注意事项有哪些,下面就是实战案例,一起来看一下。一、示例var vm = new Vue({ data: { obj: { a: 1 } }, created: function () { console.log(this.obj); } });二、实现原理vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的.1)数据劫持、vue是通过Object.defineProperty()来实现数据劫持,其中会有getter()和setter方法;当读取属性值时,就会触发getter()方法,在view中如果数据发生了变化,就会通过Object.defineProperty( )对属性设置一个setter函数,当数据改变了就会来触发这个函数;三、实现步骤1、实现Observerok, 思路已经整理完毕,也已经比较明确相关逻辑和模块功能了,let"s do it我们知道可以利用Obeject.defineProperty()来监听属性变动那么将需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化。相关代码可以是这样:var data = {name: "kindeng"};observe(data);data.name = "dmq"; // 哈哈哈,监听到值变化了 kindeng --> dmqfunction observe(data) { if (!data || typeof data !== "object") { return; } // 取出所有属性遍历 Object.keys(data).forEach(function(key) { defineReactive(data, key, data[key]); });};function defineReactive(data, key, val) { observe(val); // 监听子属性 Object.defineProperty(data, key, { enumerable: true, // 可枚举 configurable: false, // 不能再define get: function() { return val; }, set: function(newVal) { console.log("哈哈哈,监听到值变化了 ", val, " --> ", newVal); val = newVal; } });}这样我们已经可以监听每个数据的变化了,那么监听到变化之后就是怎么通知订阅者了,所以接下来我们需要实现一个消息订阅器,很简单,维护一个数组,用来收集订阅者,数据变动触发notify,再调用订阅者的update方法,代码改善之后是这样:// ... 省略function defineReactive(data, key, val) { var dep = new Dep(); observe(val); // 监听子属性 Object.defineProperty(data, key, { // ... 省略 set: function(newVal) { if (val === newVal) return; console.log("哈哈哈,监听到值变化了 ", val, " --> ", newVal); val = newVal; dep.notify(); // 通知所有订阅者 } });}function Dep() { this.subs = [];}Dep.prototype = { addSub: function(sub) { this.subs.push(sub); }, notify: function() { this.subs.forEach(function(sub) { sub.update(); }); }};那么问题来了,谁是订阅者?怎么往订阅器添加订阅者?没错,上面的思路整理中我们已经明确订阅者应该是Watcher, 而且var dep = new Dep();是在 defineReactive方法内部定义的,所以想通过dep添加订阅者,就必须要在闭包内操作,所以我们可以在 getter里面动手脚:// Observer.js// ...省略Object.defineProperty(data, key, { get: function() { // 由于需要在闭包内添加watcher,所以通过Dep定义一个全局target属性,暂存watcher, 添加完移除 Dep.target && dep.addDep(Dep.target); return val; } // ... 省略});// Watcher.jsWatcher.prototype = { get: function(key) { Dep.target = this; this.value = data[key]; // 这里会触发属性的getter,从而添加订阅者 Dep.target = null; }}这里已经实现了一个Observer了,已经具备了监听数据和数据变化通知订阅者的功能,完整代码。那么接下来就是实现Compile了2、实现Compilecompile主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图,如图所示:图片描述因为遍历解析的过程有多次操作dom节点,为提高性能和效率,会先将跟节点el转换成文档碎片fragment进行解析编译操作,解析完成,再将fragment添加回原来的真实dom节点中function Compile(el) { this.$el = this.isElementNode(el) ? el : document.querySelector(el); if (this.$el) { this.$fragment = this.node2Fragment(this.$el); this.init(); this.$el.appendChild(this.$fragment); }}Compile.prototype = { init: function() { this.compileElement(this.$fragment); }, node2Fragment: function(el) { var fragment = document.createDocumentFragment(), child; // 将原生节点拷贝到fragment while (child = el.firstChild) { fragment.appendChild(child); } return fragment; }};compileElement方法将遍历所有节点及其子节点,进行扫描解析编译,调用对应的指令渲染函数进行数据渲染,并调用对应的指令更新函数进行绑定,详看代码及注释说明:Compile.prototype = { // ... 省略 compileElement: function(el) { var childNodes = el.childNodes, me = this; [].slice.call(childNodes).forEach(function(node) { var text = node.textContent; var reg = /{{(.*)}}/; // 表达式文本 // 按元素节点方式编译 if (me.isElementNode(node)) { me.compile(node); } else if (me.isTextNode(node) && reg.test(text)) { me.compileText(node, RegExp.$1); } // 遍历编译子节点 if (node.childNodes && node.childNodes.length) { me.compileElement(node); } }); }, compile: function(node) { var nodeAttrs = node.attributes, me = this; [].slice.call(nodeAttrs).forEach(function(attr) { // 规定:指令以 v-xxx 命名 // 如 <span v-text="content"></span> 中指令为 v-text var attrName = attr.name; // v-text if (me.isDirective(attrName)) { var exp = attr.value; // content var dir = attrName.substring(2); // text if (me.isEventDirective(dir)) { // 事件指令, 如 v-on:click compileUtil.eventHandler(node, me.$vm, exp, dir); } else { // 普通指令 compileUtil[dir] && compileUtil[dir](node, me.$vm, exp); } } }); }};// 指令处理集合var compileUtil = { text: function(node, vm, exp) { this.bind(node, vm, exp, "text"); }, // ...省略 bind: function(node, vm, exp, dir) { var updaterFn = updater[dir + "Updater"]; // 第一次初始化视图 updaterFn && updaterFn(node, vm[exp]); // 实例化订阅者,此操作会在对应的属性消息订阅器中添加了该订阅者watcher new Watcher(vm, exp, function(value, oldValue) { // 一旦属性值有变化,会收到通知执行此更新函数,更新视图 updaterFn && updaterFn(node, value, oldValue); }); }};// 更新函数var updater = { textUpdater: function(node, value) { node.textContent = typeof value == "undefined" ? "" : value; } // ...省略};这里通过递归遍历保证了每个节点及子节点都会解析编译到,包括了{{}}表达式声明的文本节点。指令的声明规定是通过特定前缀的节点属性来标记,如<span v-text="content" other-attr中v-text便是指令,而other-attr不是指令,只是普通的属性。监听数据、绑定更新函数的处理是在compileUtil.bind()这个方法中,通过new Watcher()添加回调来接收数据变化的通知至此,一个简单的Compile就完成了,完整代码。接下来要看看Watcher这个订阅者的具体实现了3、实现WatcherWatcher订阅者作为Observer和Compile之间通信的桥梁,主要做的事情是:1、在自身实例化时往属性订阅器(dep)里面添加自己2、自身必须有一个update()方法3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。如果有点乱,可以回顾下前面的思路整理function Watcher(vm, exp, cb) { this.cb = cb; this.vm = vm; this.exp = exp; // 此处为了触发属性的getter,从而在dep添加自己,结合Observer更易理解 this.value = this.get(); }Watcher.prototype = { update: function() { this.run(); // 属性值变化收到通知 }, run: function() { var value = this.get(); // 取到最新值 var oldVal = this.value; if (value !== oldVal) { this.value = value; this.cb.call(this.vm, value, oldVal); // 执行Compile中绑定的回调,更新视图 } }, get: function() { Dep.target = this; // 将当前订阅者指向自己 var value = this.vm[exp]; // 触发getter,添加自己到属性订阅器中 Dep.target = null; // 添加完毕,重置 return value; }};// 这里再次列出Observer和Dep,方便理解Object.defineProperty(data, key, { get: function() { // 由于需要在闭包内添加watcher,所以可以在Dep定义一个全局target属性,暂存watcher, 添加完移除 Dep.target && dep.addDep(Dep.target); return val; } // ... 省略});Dep.prototype = { notify: function() { this.subs.forEach(function(sub) { sub.update(); // 调用订阅者的update方法,通知变化 }); }};实例化Watcher的时候,调用get()方法,通过Dep.target = watcherInstance标记订阅者是当前watcher实例,强行触发属性定义的getter方法,getter方法执行的时候,就会在属性的订阅器dep添加当前watcher实例,从而在属性值有变化的时候,watcherInstance就能收到更新通知。四、简单实现方法<body> <p id="app"> <input type="text" id="txt"> <p id="show-txt"></p> </p> <script> var obj = {} Object.defineProperty(obj, "txt", { get: function () { return obj }, set: function (newValue) { document.getElementById("txt").value = newValue document.getElementById("show-txt").innerHTML = newValue } }) document.addEventListener("keyup", function (e) { obj.txt = e.target.value }) </script></body>相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!推荐阅读:Node.js Buffer使用详解怎样使用JS实现3des+base64加密解密算法
2023-08-19 18:22:261

有没有像website watcher网页监控器的开源软件

网探——网页数据监控软件,灵活 · 简便 · 基于IE浏览器 · 轻松应对无人值守7×24小时长时间工作
2023-08-19 18:22:481

MVVM框架如何解析双向绑定

这篇文章主要介绍了MVVM 框架解析之双向绑定,现在分享给大家,也给大家做个参考。MVVM 框架近年来前端一个明显的开发趋势就是架构从传统的 MVC 模式向 MVVM 模式迁移。在传统的 MVC 下,当前前端和后端发生数据交互后会刷新整个页面,从而导致比较差的用户体验。因此我们通过 Ajax 的方式和网关 REST API 作通讯,异步的刷新页面的某个区块,来优化和提升体验。MVVM 框架基本概念在 MVVM 框架中,View(视图) 和 Model(数据) 是不可以直接通讯的,在它们之间存在着 ViewModel 这个中间介充当着观察者的角色。当用户操作 View(视图),ViewModel 感知到变化,然后通知 Model 发生相应改变;反之当 Model(数据) 发生改变,ViewModel 也能感知到变化,使 View 作出相应更新。这个一来一回的过程就是我们所熟知的双向绑定。MVVM 框架的应用场景MVVM 框架的好处显而易见:当前端对数据进行操作的时候,可以通过 Ajax 请求对数据持久化,只需改变 dom 里需要改变的那部分数据内容,而不必刷新整个页面。特别是在移动端,刷新页面的代价太昂贵。虽然有些资源会被缓存,但是页面的 dom、css、js 都会被浏览器重新解析一遍,因此移动端页面通常会被做成 SPA 单页应用。由此在这基础上诞生了很多 MVVM 框架,比如 React.js、Vue.js、Angular.js 等等。MVVM 框架的简单实现模拟 Vue 的双向绑定流,实现了一个简单的MVVM 框架,从上图中可以看出虚线方形中就是之前提到的 ViewModel 中间介层,它充当着观察者的角色。另外可以发现双向绑定流中的 View 到 Model 其实是通过 input 的事件监听函数实现的,如果换成 React(单向绑定流) 的话,它在这一步交给状态管理工具(比如 Redux)来实现。另外双向绑定流中的 Model 到 View 其实各个 MVVM 框架实现的都是大同小异的,都用到的核心方法是 Object.defineProperty(),通过这个方法可以进行数据劫持,当数据发生变化时可以捕捉到相应变化,从而进行后续的处理。Mvvm(入口文件) 的实现一般会这样调用 Mvvm 框架const vm = new Mvvm({ el: "#app", data: { title: "mvvm title", name: "mvvm name" }, })但是这样子的话,如果要得到 title 属性就要形如 vm.data.title 这样取得,为了让 vm.title 就能获得 title 属性,从而在 Mvvm 的 prototype 上加上一个代理方法,代码如下:function Mvvm (options) { this.data = options.data const self = this Object.keys(this.data).forEach(key => self.proxyKeys(key) )}Mvvm.prototype = { proxyKeys: function(key) { const self = this Object.defineProperty(this, key, { get: function () { // 这里的 get 和 set 实现了 vm.data.title 和 vm.title 的值同步 return self.data[key] }, set: function (newValue) { self.data[key] = newValue } }) }}实现了代理方法后,就步入主流程的实现function Mvvm (options) { this.data = options.data // ... observe(this.data) new Compile(options.el, this)}observer(观察者) 的实现observer 的职责是监听 Model(JS 对象) 的变化,最核心的部分就是用到了 Object.defineProperty() 的 get 和 set 方法,当要获取 Model(JS 对象) 的值时,会自动调用 get 方法;当改动了 Model(JS 对象) 的值时,会自动调用 set 方法;从而实现了对数据的劫持,代码如下所示。let data = { number: 0}observe(data)data.number = 1 // 值发生变化function observe(data) { if (!data || typeof(data) !== "object") { return } const self = this Object.keys(data).forEach(key => self.defineReactive(data, key, data[key]) )}function defineReactive(data, key, value) { observe(value) // 遍历嵌套对象 Object.defineProperty(data, key, { get: function() { return value }, set: function(newValue) { if (value !== newValue) { console.log("值发生变化", "newValue:" + newValue + " " + "oldValue:" + value) value = newValue } } })}运行代码,可以看到控制台输出 值发生变化 newValue:1 oldValue:0,至此就完成了 observer 的逻辑。Dep(订阅者数组) 和 watcher(订阅者) 的关系观测到变化后,我们总要通知给特定的人群,让他们做出相应的处理吧。为了更方便地理解,我们可以把订阅当成是订阅了一个微信公众号,当微信公众号的内容有更新时,那么它会把内容推送(update) 到订阅了它的人。那么订阅了同个微信公众号的人有成千上万个,那么首先想到的就是要 new Array() 去存放这些人(html 节点)吧。于是就有了如下代码:// observer.jsfunction Dep() { this.subs = [] // 存放订阅者}Dep.prototype = { addSub: function(sub) { // 添加订阅者 this.subs.push(sub) }, notify: function() { // 通知订阅者更新 this.subs.forEach(function(sub) { sub.update() }) }}function observe(data) {...}function defineReactive(data, key, value) { var dep = new Dep() observe(value) // 遍历嵌套对象 Object.defineProperty(data, key, { get: function() { if (Dep.target) { // 往订阅器添加订阅者 dep.addSub(Dep.target) } return value }, set: function(newValue) { if (value !== newValue) { console.log("值发生变化", "newValue:" + newValue + " " + "oldValue:" + value) value = newValue dep.notify() } } })}初看代码也比较顺畅了,但可能会卡在 Dep.target 和 sub.update,由此自然而然地将目光移向 watcher,// watcher.jsfunction Watcher(vm, exp, cb) { this.vm = vm this.exp = exp this.cb = cb this.value = this.get()}Watcher.prototype = { update: function() { this.run() }, run: function() { // ... if (value !== oldVal) { this.cb.call(this.vm, value) // 触发 compile 中的回调 } }, get: function() { Dep.target = this // 缓存自己 const value = this.vm.data[this.exp] // 强制执行监听器里的 get 函数 Dep.target = null // 释放自己 return value }}从代码中可以看到当构造 Watcher 实例时,会调用 get() 方法,接着重点关注 const value = this.vm.data[this.exp] 这句,前面说了当要获取 Model(JS 对象) 的值时,会自动调用 Object.defineProperty 的 get 方法,也就是当执行完这句的时候,Dep.target 的值传进了 observer.js 中的 Object.defineProperty 的 get 方法中。同时也一目了然地在 Watcher.prototype 中发现了 update 方法,其作用即触发 compile 中绑定的回调来更新界面。至此解释了 Observer 中 Dep.target 和 sub.update 的由来。来归纳下 Watcher 的作用,其充当了 observer 和 compile 的桥梁。1 在自身实例化的过程中,往订阅器(dep) 中添加自己2 当 model 发生变动,dep.notify() 通知时,其能调用自身的 update 函数,并触发 compile 绑定的回调函数实现视图更新最后再来看下生成 Watcher 实例的 compile.js 文件。compile(编译) 的实现首先遍历解析的过程有多次操作 dom 节点,为提高性能和效率,会先将跟节点 el 转换成 fragment(文档碎片) 进行解析编译,解析完成,再将 fragment 添加回原来的真实 dom 节点中。代码如下:function Compile(el, vm) { this.vm = vm this.el = document.querySelector(el) this.fragment = null this.init()}Compile.prototype = { init: function() { if (this.el) { this.fragment = this.nodeToFragment(this.el) // 将节点转为 fragment 文档碎片 this.compileElement(this.fragment) // 对 fragment 进行编译解析 this.el.appendChild(this.fragment) } }, nodeToFragment: function(el) { const fragment = document.createDocumentFragment() let child = el.firstChild // △ 第一个 firstChild 是 text while(child) { fragment.appendChild(child) child = el.firstChild } return fragment }, compileElement: function(el) {...},}这个简单的 mvvm 框架在对 fragment 编译解析的过程中对 {{}} 文本元素、v-on:click 事件指令、v-model 指令三种类型进行了相应的处理。Compile.prototype = { init: function() { if (this.el) { this.fragment = this.nodeToFragment(this.el) // 将节点转为 fragment 文档碎片 this.compileElement(this.fragment) // 对 fragment 进行编译解析 this.el.appendChild(this.fragment) } }, nodeToFragment: function(el) {...}, compileElement: function(el) {...}, compileText: function (node, exp) { // 对文本类型进行处理,将 {{abc}} 替换掉 const self = this const initText = this.vm[exp] this.updateText(node, initText) // 初始化 new Watcher(this.vm, exp, function(value) { // 实例化订阅者 self.updateText(node, value) }) }, compileEvent: function (node, vm, exp, dir) { // 对事件指令进行处理 const eventType = dir.split(":")[1] const cb = vm.methods && vm.methods[exp] if (eventType && cb) { node.addEventListener(eventType, cb.bind(vm), false) } }, compileModel: function (node, vm, exp) { // 对 v-model 进行处理 let val = vm[exp] const self = this this.modelUpdater(node, val) node.addEventListener("input", function (e) { const newValue = e.target.value self.vm[exp] = newValue // 实现 view 到 model 的绑定 }) },}在上述代码的 compileTest 函数中看到了期盼已久的 Watcher 实例化,对 Watcher 作用模糊的朋友可以往上回顾下 Watcher 的作用。另外在 compileModel 函数中看到了本文最开始提到的双向绑定流中的 View 到 Model 是借助 input 监听事件变化实现的。项目地址本文记录了些阅读 mvvm 框架源码关于双向绑定的心得,并动手实践了一个简版的 mvvm 框架,不足之处在所难免,欢迎指正。上面是我整理给大家的,希望今后会对大家有帮助。相关文章:通过微信小程序如何实现验证码获取倒计时效果ES6 迭代器和 for.of循环(详细教程)在vue中使用better-scroll滚动插件在VUE + UEditor中如何实现单图片跨域上传功能
2023-08-19 18:22:561

vue和react的区别之我见

react和vue都是做组件化的,整体的功能都类似,但是他们的设计思路是有很多不同的。使用react和vue,主要是理解他们的设计思路的不同。 react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流,推崇结合immutable来实现数据不可变。react在setState之后会重新走渲染的流程,如果shouldComponentUpdate返回的是true,就继续渲染,如果返回了false,就不会重新渲染,PureComponent就是重写了shouldComponentUpdate,然后在里面作了props和state的浅层对比。 而vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。 总之,react的性能优化需要手动去做,而vue的性能优化是自动的,但是vue的响应式机制也有问题,就是当state特别多的时候,Watcher也会很多,会导致卡顿,所以大型应用(状态特别多的)一般用react,更加可控。 react的思路是all in js,通过js来生成html,所以设计了jsx,还有通过js来操作css,社区的styled-component、jss等, vue是把html,css,js组合到一起,用各自的处理方式,vue有单文件组件,可以把html、css、js写到一个文件中,html提供了模板引擎来处理。 react是类式的写法,api很少, 而vue是声明式的写法,通过传入各种options,api和参数都很多。所以react结合typescript更容易一起写,vue稍微复杂。 react可以通过高阶组件(Higher Order Components--HOC)来扩展,而vue需要通过mixins来扩展 一个react高阶组件的例子:react做的事情很少,很多都交给社区去做,vue很多东西都是内置的,写起来确实方便一些, 比如 redux的combineReducer就对应vuex的modules, 比如reselect就对应vuex的getter和vue组件的computed, vuex的mutation是直接改变的原始数据,而redux的reducer是返回一个全新的state,所以redux结合immutable来优化性能,vue不需要。 上面主要梳理了react和vue的4点不同: (其中第3点在vue3.0支持类式写法之后就可以去掉了) react整体的思路就是函数式,所以推崇纯组件,数据不可变,单向数据流,当然需要双向的地方也可以做到,比如结合redux-form,而vue是基于可变数据的,支持双向绑定。react组件的扩展一般是通过高阶组件,而vue组件会使用mixin。vue内置了很多功能,而react做的很少,很多都是由社区来完成的,vue追求的是开发的简单,而react更在乎方式是否正确。
2023-08-19 18:23:031

用c#的fileSystemWatcher监控目录,复制图片能触发created事件,相机照像后新建的图片文件却无法触发

有子文件夹的话,把IncludeSubdirectories设置为true
2023-08-19 18:23:192

watcher in the sky 歌词

歌曲名:watcher in the sky歌手:gamma ray专辑:somewhere out in spaceI"m watching the mountains, I"m watching the seaObserving the creatures I am lost - set me freeAcross the heavens I made my wayI"ve seen empires rise and blown awayI have arrived at my destiny but after allThere"s just emptiness in meOut in the darkness - I am going madWhere are the others - there"s a silence in my headCHORUS"Cause I"m a watcher in the skyI"ve seen universes dieGamma RayOut in the cold my systems overloadI"m here lost in time - watcher in the skyI"m trapped in this nightmareEndless tortures and pain, milleniums have gone byUhhh, it drives me insaneWho am I now?I"m not man - I"m not machineI gave my life away for the Iron Savior dreamCHORUSSOLO: KaiLost in a world of artificial meansRipped out of my bodyI"ll stand the test of timeAm I perpetual? - am I divine?SOLO: Piet / Kai"Cause I"m a watcher in the skyMy souls has drowned in the tears I cannot cryI"m the watcher, the chosen one, but I am lost in timeI"m a watcher in the skyI"ve seen the years go byI am the chosen oneOut in the cold my systems overload and I am lost in timeWatcher in the skyWatching the mountains, watching the sea, watching the creaturesYou"ll never be freeWatcher in the skyhttp://music.baidu.com/song/14496424
2023-08-19 18:23:261

谁有暗黑血统的详细剧情啊

人间遭到恶魔的攻击,此时天使出现消灭恶魔。但此时启示录4骑士中的war(战神)独自降临人间。(启示录4骑士,在人类已经有能力面对最终审判时,7个封印将会破裂,此时4骑士降临来做最后的审判。人类是灭亡,还是取代恶魔和天使)。由于最后封印仍未完全破坏,另大天使长aboddon深感意外。与此同时,天使不敌恶魔军团,aboddon战死,而war同时瞬间失去自身力量而同样被straga所杀。由于是战神,其重新回到神界。面对焦灼议会(与天使和恶魔订立审判的第3方,有其全权掌握3界的命运)的审判,被判定因为其擅自降临而导致审判提前进行,导致人间沦为炼狱,遭到恶魔统治。war深感自己蒙冤,请求议会让其返回人间复仇并查清真相。议会因而派遣watcher(war手里的东西)监视war的举动防止其做出背叛议会的举动,并让war回去杀死现在的统治者destroyer。war重返人间,此时人间早已是恶魔的乐园。(忘记那个商人叫什么了)作为接应者。告诉war原地狱统治者之一sameal遭到地狱之王destroyer囚禁。而destroyer是在审判后统治的地狱。war认定是destroyer策划的阴谋,因而决定释放sameal以获取情报。而在释放sameal后,sameal说destroyer为保证统治人间,选出4个chosen来代替其统治人间。而sameal希望war能够杀死他们并带回他们的心脏,既可清除自己的阻碍,也可方便war以后对抗destroyer。在此过程中,war的力量不断回复,而且sameal也帮助其解放其原有的力量。当war杀死最后一个chosen时,才得知chosen只是用于封印sameal的力量,并非用于控制人间。尽管如此,war将所有心脏交给sameal。sameal恢复所有力量,并且对于war也存有敌意。但作为交易,sameal仍然帮助war通往黑暗王座寻找destroyer。来到黑暗王座,war却发现眼前的是被囚禁的死亡天使。他恳求war帮助他,并许诺帮助war,告诉其事件真相。原来大天使长aboddon劝说死亡天使和***(就是和war比赛杀天使的那个)给予其末日之刃以破坏封印一同破坏7个封印中的6个,以此营造审判降临的假象,让恶魔为此准备最终决战,并乘其讨论领导者时,天使再出其不意杀死所有地狱首领,一举击败地狱恶魔,引导人类走上和平与秩序之路。但同时保留最后封印,一是不让4骑士降临毁灭人间,二是防止如果战争败于地狱后仍可有4骑士清除恶魔。可惜事与愿违,天使无力与恶魔一战,而且war莫名降临人间,打乱天使的计划。而且aboddon战死,最后封印与其一同消失。导致人间沦落至恶魔手中,人类就此灭亡。war了解真相后,决定放弃任务,返回议会澄清。但watcher动用议会赋予的力量命令war完成任务。在war杀死straga复仇后,死亡天使带领其来到早已灭亡的伊甸园。并在其除去自身邪气后面见世界之树。war从世界之树中了解到事件全部真相:议会早已得知aboddon的计划,但苦于没有证据审判aboddon,因而设计陷害war降临人间,并同时剥夺其力量,让蒙受冤屈的war以复仇为动力追查,惩罚所有违背议会的人。同时其发现destroyer就是原来的aboddon,在其死后死亡天使带领其灵魂也见过世界之树,其中有人说道:就算你是为了天堂付出自己的生命,当议会追查清楚后,你也将万劫不复。现在,你有一个选择,是在天堂为奴,还是在地狱为王?destroyer还将攻上天堂。而war将在最后与aboddon的战争中被末日之刃刺杀,watcher则获得了最后封印而在这段片段中,war获得了末日之刃的剑柄。在收集起末日之刃碎片后并重铸后,war来到天堂与destroyer对战。最终war杀死aboddon。但watcher使用议会的力量抢得封印,并声称war对于议会已毫无用处,准备处置war。但炽天使(就是那个女的)用末日之刃刺穿war并顺势打碎最后封印。由于最后封印破碎,war完全获得力量并以此重生,watcher无法再使用议会的力量再杀死war,因而被war杀死。war也从此背叛议会此时war遭到天堂的追击,又被地狱憎恨,同时也背叛了议会。议会一定会追杀他。但同时,4骑士全部降临人间.......(待续)话说这是我过去回答的另外,我只是按照剧情流程介绍的,3l自己研究一下去。我又没说不是天使先动的手?从开场开始阶段的确天使失败了。只是先下手处理掉了恶魔的大部分首领。但恶魔同时间也开始攻击人间。2l那位说是世界树所解释的事实(sgamer的翻译我没看过?笑),但Abaddon在进入地狱后并非臣服于地狱而是重新统治地狱,不同的是有谁赋予Abaddon力量,不一定是恶魔。你没自己研究过就不要乱说。
2023-08-19 18:24:024

cf出现cf file watcher怎么解决

具体的是什么?是安装时,还是下载时?什么时候弹出的信息框?有相同问题的,传送门http://zhidao.baidu.com/question/68174233.html
2023-08-19 18:24:145

vue是怎么将数据绑定到组件的原理

目前几种主流的mvc(vm)框架都实现了单向数据绑定,而我所理解的双向数据绑定无非就是在单向绑定的基础上给可输入元素(input、textare等)添加了change(input)事件,来动态修改model和 view,并没有多高深。所以无需太过介怀是实现的单向或双向绑定。实现数据绑定的做法有大致如下几种:发布者-订阅者模式(backbone.js)脏值检查(angular.js)数据劫持(vue.js)
2023-08-19 18:25:531

C#编程中怎么对文件目录进行实时监控

http://www.cnblogs.com/scottckt/archive/2008/05/09/1189366.html
2023-08-19 18:26:112