<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [toc] ## 數據初始化 明確定義的數據模型更加適合 Vue 的數據觀察模式。建議在定義組件時,在 data 選項中初始化所有需要進行動態觀察的屬性。例如,給定下面的模版: ~~~ <div id="demo"> <p v-class="green: validation.valid">{{message}}</p> <input v-model="message"> </div> ~~~ 建議像這樣初始化你的數據,而不是什么都不定義: ~~~ new Vue({ el: '#demo', data: { message: '', validation: { valid: false } } }) ~~~ 為什么要這樣做呢?因為 Vue 是通過遞歸遍歷初始數據中的所有屬性,并用 Object.defineProperty 把它們轉化為 getter 和 setter 來實現數據觀察的。如果一個屬性在實例創建時不存在于初始數據中,那么 Vue 就沒有辦法觀察這個屬性了。 當然,你也不需要對每一個可能存在的嵌套屬性都進行初始定義。在初始化的時候可以將一個屬性置為空對象,然后在后面的操作中設置為一個新的擁有嵌套結構的對象。只要這個新對象包含了應有的屬性,Vue 依然能對這個新對象進行遞歸遍歷,從而觀察其內部屬性。 ## 添加和刪除屬性 正如前面所說的, Vue 會使用 Object.defineProperty 通過轉化屬性值來觀察數據。不過,在 ECMAScript 5 中,當一個新的屬性被添加到對象或者從對象中刪除的時候,并沒有辦法可以檢測到這兩種情況。為了解決這個問題,Vue 會為被觀察的對象添加三個擴展方法: - obj.$add(key, value) - obj.$set(key, value) - obj.$delete(key) 通過調用這些方法給觀察對象中添加或者刪除屬性,就能夠觸發所對應的 DOM 更新。$add 和 $set 的區別是,假如當前對象已經含有所使用的 key, $add 會直接返回。所以當使用 $obj.$add(key) 的時候不會將已經存在的值覆蓋為 undefined。 另外需要注意的一點是,當你通過數組索引賦值來改動數組時 (比如 arr[1] = value),Vue 是無法偵測到這類操作的。類似地,你可以使用擴展方法來確保 Vue.js 收到了通知。被觀察的數組有兩個擴展方法: - arr.$set(index, value) - arr.$remove(index | value) Vue 組件實例也有相應的實例方法: - vm.$get(path) - vm.$set(path, value) - vm.$add(key, value) - vm.$delete(key, value) 注意 vm.$get 和 vm.set 都接受路徑。 > 盡管存在這些方法,但我強烈建議你只在必要的時候才動態添加可觀察屬性。為了理解你的組件狀態,將 data 選項看做一個 schema 很有幫助。假如你清晰地列出一個組件中所有可能存在的屬性,那么當你隔了幾個月再來維護這個組件的時候,就可以更容易地理解這個組件可能包含怎樣的狀態。 ## 理解異步更新 默認情況下, Vue 的 DOM 更新是異步執行的。理解這一點非常重要。當偵測到數據變化時, Vue 會打開一個隊列,然后把在同一個事件循環 (event loop) 當中觀察到數據變化的 watcher 推送進這個隊列。假如一個 watcher 在一個事件循環中被觸發了多次,它只會被推送到隊列中一次。然后,在進入下一次的事件循環時, Vue 會清空隊列并進行必要的 DOM 更新。在內部,Vue 會使用 MutationObserver 來實現隊列的異步處理,如果不支持則會回退到 setTimeout(fn, 0)。 舉例來說,當你設置 vm.someData = 'new value',DOM 并不會馬上更新,而是在異步隊列被清除,也就是下一個事件循環開始時執行更新。如果你想要根據更新的 DOM 狀態去做某些事情,就必須要留意這個細節。盡管 Vue.js 鼓勵開發者用 “數據驅動” 的方式想問題,避免直接操作 DOM ,但有時候你可能就是想要使用某個熟悉的 jQuery 插件。這種情況下怎么辦呢?你可以在數據改變后,立刻調用 Vue.nextTick(callback),并把你要做的事情放到回調函數里面。當 Vue.nextTick 的回調函數執行時,DOM 將會已經是更新后的狀態了。 示例: ~~~ <div id="example">{{msg}}</div> var vm = new Vue({ el: '#example', data: { msg: '123' } }) vm.msg = 'new message' // change data vm.$el.textContent === 'new message' // false Vue.nextTick(function () { vm.$el.textContent === 'new message' // true }) ~~~ 除此之外,也有一個實例方法 vm.$nextTick()。這個方法和全局的 Vue.nextTick 功能一樣,但更方便在組件內部使用,因為它不需要全局的 Vue 變量,另外它的回調函數的 this 上下文會自動綁定到調用它的 Vue 實例: ~~~ Vue.component('example', { template: '<span>{{msg}}</span>', data: function () { return { msg: 'not updated' } }, methods: { updateMessage: function () { this.msg = 'updated' console.log(this.$el.textContent) // => 'not updated' this.$nextTick(function () { console.log(this.$el.textContent) // => 'updated' }) } } }) ~~~ ## 組件作用域 每一個 Vue.js 組件都是一個擁有自己的獨立作用域的 Vue 實例。在使用組件的時候,理解組件作用域機制非常重要。其規則概括來說就是: > 在父模板中出現的,將在父模板作用域內編譯;在子模板中出現的,將在子模板的作用域內編譯。 一個常見的錯誤是,在父模版中嘗試將一個指令綁定到子作用域里的屬性或者方法上: ~~~ <div id="demo"> <!-- 不起作用,因為作用域不對! --> <child-component v-on="click: childMethod"></child-component> </div> ~~~ 如果需要在子組件的根節點上綁定指令,應當將指令寫在子組件的模板內: ~~~ Vue.component('child-component', { // 這次作用域對了 template: '<div v-on="click: childMethod">Child</div>', methods: { childMethod: function () { console.log('child method invoked!') } } }) ~~~ 注意,當組件和 v-repeat 一同使用時,$index 作為子作用域屬性也會受到此規則的影響。 另外,父模板里組件節點內部的 HTML 內容被看做是 “transclusion content”(插入內容)。除非子模版包含至少一個 <content>出口,不然這些插入內容不會被渲染。需要留意的是,插入內容也是在父作用域中編譯的: ~~~ <div> <child-component> <!-- 在父作用域里編譯 --> <p>{{msg}}</p> </child-component> </div> ~~~ 你可以使用 inline-template 屬性去明確內容在子模版的作用域中被編譯: ~~~ <div> <child-component inline-template> <!-- 在子作用域里編譯 --> <p>{{msg}}</p> </child-component> </div> ~~~ 更多關于內容插入的細節,請看組件一章的 內容插入 小節。 ## 在多個實例之間通訊 一種常見的在 Vue 中進行父子通訊的方法是,通過 props 傳遞一個父方法作為一個回調到子組件中。這樣使用時的回調傳遞可以被定義在父模版中,從而保持了組件之間 Javascript 實現細節上的解耦: ~~~ <div id="demo"> <p>Child says: {{msg}}</p> <child-component send-message="{{onChildMsg}}"></child-component> </div> new Vue({ el: '#demo', data: { msg: '' }, methods: { onChildMsg: function(msg) { this.msg = msg return 'Got it!' } }, components: { 'child-component': { props: [ // you can use prop assertions to ensure the // callback prop is indeed a function. { name: 'send-message', type: Function, required: true } ], // props with hyphens are auto-camelized template: '<button v-on="click:onClick">Say Yeah!</button>' + '<p>Parent responds: {{response}}</p>', // component `data` option must be a function data: function () { return { response: '' } }, methods: { onClick: function () { this.response = this.sendMessage('Yeah!') } } } } }) ~~~ **Result:** Child says: 當你需要跨越多層嵌套的組件進行通訊時,你可以使用事件系統。另外,在構建大型應用時,用 Vue 搭配類似 Flux 的架構也是完全可行的。 ##片段實例 自 0.12.2 起,replace 參數默認為 true。這意味著: >組件的模板長什么樣,渲染出來的 DOM 就是什么樣。 父模板中調用組件的元素將會被組件本身的模板取代。因此,如果組件的模板包含多個頂級元素: ~~~ Vue.component('example', { template: '<div>A</div>' + '<div>B</div>' }) ~~~ 或者模板只包含文本: ~~~ Vue.component('example', { template: 'Hello world' }) ~~~ 在這兩個情況下,實例將變成一個片段實例 (fragment instance),也即沒有根元素的實例。它的 $el 指向一個錨節點(普通模式下是空的文本節點,debug 模式下是注釋節點)。更重要的是,父模板組件元素上的指令、過渡效果和屬性綁定(props 除外)將無效,因為生成的實例并沒有根元素供它們綁定: ~~~ <!-- 指令不生效,因為沒有根元素用來綁定 --> <example v-show="ok" v-transition="fade"></example> <!-- props 還是能夠正常生效 --> <example prop="{{someData}}"></example> ~~~ 雖然片段實例也有其使用場景,但是大部分情況下,給組件模板一個根元素是推薦的做法。這樣父模板組件元素上的指令和屬性能正常運轉,并且性能也會更好一點。 ## 修改默認選項 通過修改全局的 Vue.options 對象,可以修改實例選項的默認值。例如,你可以設置 Vue.options.replace = false,使所有 Vue 實例都按照 replace: false 的規則被編譯。請謹慎使用這個功能 - 最好是只在一個項目剛開始的時候使用它,因為它會影響所有 Vue 實例的行為。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看