検索

Vue.js の応答原理の詳細な説明

Feb 10, 2018 pm 01:59 PM
javascriptvue.js詳しい説明

セッター🎜🎜 。時間が経つにつれて、私はこの欠けている機能を気に入るようになりました。なぜなら、Java の膨大な機能と比較して 🎜 より簡潔だからです。たとえば、次の Java コードを見てみましょう: 🎜🎜🎜
<span style="font-size: 14px;">class Person{<br/>    String firstName;<br/>    String lastName;    // 这个Demo中省略了一些构造器代码 :)    public void setFirstName(firstName) {        this.firstName = firstName;<br/>    }    public String getFirstName() {        return firstName;<br/>    }    public void setLastName(lastName) {        this.lastName = lastName;<br/>    }    public String getLastName() {        return lastName;<br/>    }<br/>}// Create instancePerson bradPitt = new Person();<br/>bradPitt.setFirstName("Brad");<br/>bradPitt.setLastName("Pitt");<br/></span>

JavaScript 開発者は決してこれを行いませんが、代わりに次のことを行います:

<span style="font-size: 14px;">var Person = function () {};var bradPitt = new Person();<br/>bradPitt.firstName = &#39;Brad&#39;;<br/>bradPitt.lastName = &#39;Pitt&#39;;<br/></span>

これははるかに簡単です。通常はシンプルな方が良いですよね。

それは本当ですが、変更可能なプロパティを取得したいことがありますが、それらのプロパティが何であるかを知る必要はありません。たとえば、Java コードで新しいメソッド <code><span style="font-size: 14px;">getFullName()</span>

<span style="font-size: 14px;">class Person{    private String firstName;    private String lastName;    // 这个Demo中省略了一些构造器代码 :)    public void setFirstName(firstName) {        this.firstName = firstName;<br/>    }    public String getFirstName() {        return firstName;<br/>    }    public void setLastName(lastName) {        this.lastName = lastName;<br/>    }    public String getLastName() {        return lastName;<br/>    }    public String getFullName() {        return firstName + " " + lastName;<br/>    }<br/>}<br/><br/>Person bradPitt = new Person();<br/>bradPitt.setFirstName("Brad");<br/>bradPitt.setLastName("Pitt");// Prints &#39;Brad Pitt&#39;System.out.println(bradPitt.getFullName());<br/></span>

在上面例子中, <span style="font-size: 14px;">fullName</span> 是一个计算过的属性,它不是私有属性,但总能返回正确的结果。

C# 和隐式的 getter/setters

我们来看看 C# 特性之一:隐式的 <code><span style="font-size: 14px;">getters</span>/<span style="font-size: 14px;">setters</span>,我真的很喜欢它。在 C# 中,如果需要,你可以定义 <code><span style="font-size: 14px;">getters</span>/<span style="font-size: 14px;">setters</span>,但是并不用这样做,但是如果你决定要这么做,调用者就不必调用函数。调用者只需要直接访问属性,<span style="font-size: 14px;">getter</span>/<span style="font-size: 14px;">setter</span> 会自动在钩子函数中运行:

<span style="font-size: 14px;">public class Foo {    public string FirstName {get; set;}    public string LastName {get; set;}    public string FullName {get { return firstName + " " + lastName }; private set;}<br/>}<br/></span>

我觉得这很酷...

现在,如果我想在JavaScript中实现类似的功能,我会浪费很多时间,比如:

<span style="font-size: 14px;">var person0 = {<br/>    firstName: &#39;Bruce&#39;,<br/>    lastName: &#39;Willis&#39;,<br/>    fullName: &#39;Bruce Willis&#39;,<br/>    setFirstName: function (firstName) {        this.firstName = firstName;        this.fullName = `${this.firstName} ${this.lastName}`;<br/>    },<br/>    setLastname: function (lastName) {        this.lastName = lastName;        this.fullName = `${this.firstName} ${this.lastName}`;<br/>    },<br/>};<br/>console.log(person0.fullName);<br/>person0.setFirstName(&#39;Peter&#39;);<br/>console.log(person0.fullName);<br/></span>

它会打印出:

<span style="font-size: 14px;">"Bruce Willis"<br/>"Peter Willis"<br/></span>

但使用 <span style="font-size: 14px;">setXXX(value)</span> 的方式并不够'JavaScripty'(是个玩笑啦)。

下面的方式可以解决这个问题:

<span style="font-size: 14px;">var person1 = {<br/>    firstName: &#39;Brad&#39;,<br/>    lastName: &#39;Pitt&#39;,<br/>    getFullName: function () {        return `${this.firstName} ${this.lastName}`;<br/>    },<br/>};<br/>console.log(person1.getFullName()); // 打印 "Brad Pitt"<br/></span>

现在我们回到被计算过的 <span style="font-size: 14px;">getter</span>。你可以设置 <span style="font-size: 14px;">first</span><span style="font-size: 14px;">last name</span>,并简单的合并它们的值:

<span style="font-size: 14px;">person1.firstName = &#39;Peter&#39;person1.getFullName(); // 返回 "Peter Pitt"<br/></span>

这的确更方便,但我还是不喜欢它,因为我们要定义一个叫<span style="font-size: 14px;">getxxx()</span>的方法,这也不够'JavaScripty'。许多年来,我一直在思考如何更好的使用 JavaScript。

然后 Vue 出现了

在我的Youtube频道,很多和Vue教程有关的视频都讲到,我习惯响应式开发,在更早的Angular1时代,我们叫它:数据绑定(Data Binding)。它看起来很简单。你只需要在Vue实例的 <span style="font-size: 14px;">data()</span> 块中定义一些数据,并绑定到HTML:

<span style="font-size: 14px;">var vm = new Vue({<br/>    data() {<br/>        return {<br/>        greeting: &#39;Hello world!&#39;,<br/>        };<br/>    }<br/>})<div>{greeting}</div><br/></span>

显然它会在用户界面打印出 <span style="font-size: 14px;">“Hello world!”</span>

现在,如果你改变<span style="font-size: 14px;">greeting</span>的值,Vue引擎会对此作出反应并相应地更新视图。

<span style="font-size: 14px;">methods: {<br/>    onSomethingClicked() {        this.greeting = "What&#39;s up";<br/>    },<br/>}<br/></span>

很长一段时间我都在想,它是如何工作的?当某个对象的属性发生变化时会触发某个事件?或者Vue不停的调用 <span style="font-size: 14px;">setInterval</span> 去检查是否更新?

通过阅读Vue官方文档,我才知道,改变一个对象属性将隐式调用<span style="font-size: 14px;">getter</span>/<span style="font-size: 14px;">setter</span>getFullName() を拡張します。

🎜
<span style="font-size: 14px;">/**<br/>* 给对象定义响应的属性<br/>*/export function defineReactive (<br/>    obj: Object,<br/>    key: string,<br/>    val: any,<br/>    customSetter?: ?Function,<br/>    shallow?: boolean<br/>) {    const dep = new Dep()    const property = Object.getOwnPropertyDescriptor(obj, key)    if (property && property.configurable === false) {        return<br/>    }    // 预定义getter/setters    const getter = property && property.get    const setter = property && property.set    let childOb = !shallow && observe(val)<br/>    Object.defineProperty(obj, key, {<br/>        enumerable: true,<br/>        configurable: true,        get: function reactiveGetter () {            const value = getter ? getter.call(obj) : val            if (Dep.target) {<br/>                dep.depend()                if (childOb) {<br/>                    childOb.dep.depend()<br/>                }                if (Array.isArray(value)) {<br/>                    dependArray(value)<br/>                }<br/>            }            return value<br/>        },        set: function reactiveSetter (newVal) {            const value = getter ? getter.call(obj) : val            /* 禁用eslint 不进行自我比较 */            if (newVal === value || (newVal !== newVal && value !== value)) {                return<br/>            }            /* 开启eslint 不进行自己比较 */            if (process.env.NODE_ENV !== &#39;production&#39; && customSetter) {<br/>                customSetter()<br/>            }            if (setter) {<br/>                setter.call(obj, newVal)<br/>            } else {<br/>                val = newVal<br/>            }<br/>            childOb = !shallow && observe(newVal)<br/>            dep.notify()<br/>        }<br/>    })<br/>}<br/></span>
🎜🎜 上の例では、🎜🎜fullName🎜🎜 は A です。プライベートではないが、常に正しい結果を返す計算プロパティ。 🎜🎜

🎜C# と暗黙的なゲッター/セッター🎜

🎜🎜C# の機能の 1 つを見てみましょう: 暗黙的な 🎜🎜getter🎜🎜/🎜 🎜setters 🎜🎜、とても気に入っています。 C# では、必要に応じて 🎜🎜getters🎜🎜/🎜🎜setters🎜🎜 を定義できますが、そうする必要はありません。ただし、そうすることにした場合は、呼び出し元は関数を呼び出す必要はありません。呼び出し元はプロパティに直接アクセスするだけで済み、🎜🎜getter🎜🎜/🎜🎜setter🎜🎜 がフック関数で自動的に実行されます: 🎜🎜
<span style="font-size: 14px;">var person2 = {<br/>    firstName: &#39;George&#39;,<br/>    lastName: &#39;Clooney&#39;,<br/>};<br/>Object.defineProperty(person2, &#39;fullName&#39;, {<br/>    get: function () {        return `${this.firstName} ${this.lastName}`;<br/>    },<br/>});<br/>console.log(person2.fullName); // 打印 "George Clooney"<br/></span>
🎜🎜 Iこれはとてもクールだと思います... 🎜🎜🎜🎜 さて、JavaScript でこのようなものを実装したいと思ったら、次のように多くの時間を無駄にするでしょう: 🎜🎜rrreee🎜🎜 これは次のように出力されます: 🎜🎜rrreee🎜🎜 ただし 🎜 を使用します 🎜setXXX(value)🎜🎜 は「JavaScript」として十分ではありません (冗談です)。 🎜🎜🎜🎜次の方法でこの問題を解決できます: 🎜🎜rrreee🎜🎜 次に、計算された 🎜🎜getter🎜🎜 に戻ります。 🎜🎜first🎜🎜 または 🎜🎜last name🎜🎜 を設定し、単にそれらの値をマージすることができます: 🎜🎜rrreee🎜🎜 これは確かに便利ですが、私はまだそうしません気に入らないのは、🎜🎜getxxx()🎜🎜 というメソッドを定義する必要があるからですが、これも「JavaScript」としては十分ではありません。私は長年、JavaScript をより良く使用する方法について考えてきました。 🎜🎜

🎜その後、Vue が登場しました🎜

🎜🎜 私の Youtube チャンネルでは、Vue チュートリアルに関連する多くのビデオが言及されています。以前の Angular1 の時代には、それを「Data Binding」と呼んでいました。見た目はシンプルです。 Vue インスタンスの 🎜🎜data()🎜🎜 ブロックでいくつかのデータを定義し、それを HTML にバインドするだけです: 🎜🎜rrreee🎜🎜明らかに、UI に出力されます 🎜 🎜「Hello world!」🎜🎜。 🎜🎜🎜🎜ここで、🎜🎜greeting🎜🎜の値を変更すると、Vue エンジンはこれに反応し、それに応じてビューを更新します。 🎜🎜rrreee🎜🎜長い間、私はそれがどのように機能するのか疑問に思っていました。オブジェクトのプロパティが変化するとイベントがトリガーされますか?それとも、Vue は更新されているかどうかを確認するために 🎜🎜setInterval🎜🎜 を呼び出し続けるのでしょうか? 🎜🎜🎜🎜Vue の公式ドキュメントを読んで、オブジェクトのプロパティを変更すると 🎜🎜getter🎜🎜/🎜🎜setter🎜🎜 が暗黙的に呼び出されることを知りました。通知してください以下に示すように、もう一度 Observer し、再レンダリングをトリガーします。この例は、Vue.js の公式ドキュメントから引用しています。

Vue.js の応答原理の詳細な説明

但我还想知道:

  • 怎么让数据自带<span style="font-size: 14px;">getter</span>/<span style="font-size: 14px;">setters</span>

  • 这些隐式调用内部是怎样的?

第一个问题很简单:Vue为我们准备好了一切。当你添加新数据,Vue将会通过其属性为其添加 <span style="font-size: 14px;">getter</span>/<span style="font-size: 14px;">setters</span>。但是我让 <span style="font-size: 14px;">foo.bar = 3</span>? 会发生什么?

这个问题的答案出现在我和SVG & Vue专家Sarah Drasner的Twitter对话中:

Vue.js の応答原理の詳細な説明

Timo: <span style="font-size: 14px;">foo.bar=value;</span>是怎么做到实时响应的?

Sarah: 这个问题很难在Twitter说清楚,可以看这篇文章

Timo: 但这篇文章并没有解释上面提到的问题。

Timo: 它们就像:分配一个值->调用<span style="font-size: 14px;">setter</span>->通知观察者,不理解为什么在不使用<span style="font-size: 14px;">setInterval</span><span style="font-size: 14px;">Event</span>的情况下,<span style="font-size: 14px;">setter</span>/<span style="font-size: 14px;">getter</span>就存在了。

Sarah: 我的理解是:你获取的所有数据都在Vue实例<span style="font-size: 14px;">data{}</span>中被代理了。

显然,她也是参考的官方文档,之前我也读过,所以我开始阅读Vue源码,以便更好的理解发生了什么。过了一会我想起在官方文档看到一个叫 <span style="font-size: 14px;">Object.defineProperty()</span> 的方法,我找到它,如下:

<span style="font-size: 14px;">/**<br/>* 给对象定义响应的属性<br/>*/export function defineReactive (<br/>    obj: Object,<br/>    key: string,<br/>    val: any,<br/>    customSetter?: ?Function,<br/>    shallow?: boolean<br/>) {    const dep = new Dep()    const property = Object.getOwnPropertyDescriptor(obj, key)    if (property && property.configurable === false) {        return<br/>    }    // 预定义getter/setters    const getter = property && property.get    const setter = property && property.set    let childOb = !shallow && observe(val)<br/>    Object.defineProperty(obj, key, {<br/>        enumerable: true,<br/>        configurable: true,        get: function reactiveGetter () {            const value = getter ? getter.call(obj) : val            if (Dep.target) {<br/>                dep.depend()                if (childOb) {<br/>                    childOb.dep.depend()<br/>                }                if (Array.isArray(value)) {<br/>                    dependArray(value)<br/>                }<br/>            }            return value<br/>        },        set: function reactiveSetter (newVal) {            const value = getter ? getter.call(obj) : val            /* 禁用eslint 不进行自我比较 */            if (newVal === value || (newVal !== newVal && value !== value)) {                return<br/>            }            /* 开启eslint 不进行自己比较 */            if (process.env.NODE_ENV !== &#39;production&#39; && customSetter) {<br/>                customSetter()<br/>            }            if (setter) {<br/>                setter.call(obj, newVal)<br/>            } else {<br/>                val = newVal<br/>            }<br/>            childOb = !shallow && observe(newVal)<br/>            dep.notify()<br/>        }<br/>    })<br/>}<br/></span>

所以答案一直存在于文档中:

把一个普通 JavaScript 对象传给 Vue 实例的 <span style="font-size: 14px;">data</span> 选项,Vue 将遍历此对象所有的属性,并使用 <span style="font-size: 14px;">Object.defineProperty</span> 把这些属性全部转为 <span style="font-size: 14px;">getter</span>/<span style="font-size: 14px;">setter</span><span style="font-size: 14px;">Object.defineProperty</span> 是仅 ES5 支持,且无法 <span style="font-size: 14px;">shim</span> 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。

我只想简单的了解 <span style="font-size: 14px;">Object.defineProperty()</span> 做了什么,所以我用一个例子简单的给你讲解一下:

<span style="font-size: 14px;">var person2 = {<br/>    firstName: &#39;George&#39;,<br/>    lastName: &#39;Clooney&#39;,<br/>};<br/>Object.defineProperty(person2, &#39;fullName&#39;, {<br/>    get: function () {        return `${this.firstName} ${this.lastName}`;<br/>    },<br/>});<br/>console.log(person2.fullName); // 打印 "George Clooney"<br/></span>

还记得文章开头C#的隐式 <span style="font-size: 14px;">getter</span> 吗?它们看起来很类似,但ES5才开始支持。你需要做的是使用 <span style="font-size: 14px;">Object.defineProperty()</span> 定义现有对象,以及何时获取这个属性,这个<span style="font-size: 14px;">getter</span>被称为响应式——这实际上就是Vue在你添加新数据时背后所做的事。

<span style="font-size: 14px;">Object.defineProperty()</span>能让Vue变的更简化吗?

学完这一切,我一直在想,<span style="font-size: 14px;">Object.defineProperty()</span> 是否能让Vue变的更简化?现今越来越多的新术语,是不是真的有必要把事情变得过于复杂,变的让初学者难以理解(Redux也是同样):

  • <span style="font-size: 14px;">Mutator</span>:或许你在说(隐式)<span style="font-size: 14px;">setter</span>

  • <span style="font-size: 14px;">Getters</span>:为什么不用 <span style="font-size: 14px;">Object.defineProperty()</span> 替换成(隐式)<span style="font-size: 14px;">getter</span>

  • <span style="font-size: 14px;">store.commit()</span>:为什么不简化成 <span style="font-size: 14px;">foo = bar</span>,而是 <span style="font-size: 14px;">store.commit("setFoo", bar);</span>

你是怎么认为的?Vuex必须是复杂的还是可以像 <span style="font-size: 14px;">Object.defineProperty()</span> 同じくらい簡単ですか?

関連する推奨事項:

レスポンシブ開発サンプル共有のためのremを使用したJavaScript

フロントエンドのレスポンシブレイアウト、レスポンシブ画像、および自家製グリッドシステムの詳細な説明

respon何をフォーミュラとアダプティブの違いは何ですか

以上がVue.js の応答原理の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptの起源:その実装言語の調査JavaScriptの起源:その実装言語の調査Apr 29, 2025 am 12:51 AM

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

舞台裏:JavaScriptをパワーする言語は何ですか?舞台裏:JavaScriptをパワーする言語は何ですか?Apr 28, 2025 am 12:01 AM

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの未来:傾向と予測PythonとJavaScriptの未来:傾向と予測Apr 27, 2025 am 12:21 AM

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。

Python vs. JavaScript:開発環境とツールPython vs. JavaScript:開発環境とツールApr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

JavaScriptはCで書かれていますか?証拠を調べるJavaScriptはCで書かれていますか?証拠を調べるApr 25, 2025 am 12:15 AM

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptの役割:WebをインタラクティブでダイナミックにするJavaScriptの役割:WebをインタラクティブでダイナミックにするApr 24, 2025 am 12:12 AM

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター