<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                Vue 推薦在絕大多數情況下使用模板來創建你的 HTML。然而在一些場景中,你真的需要 JavaScript 的完全編程的能力。這時你可以用**渲染函數**,它比模板更接近編譯器。 > 在組件選項中有一個渲染函數`render 函數`,而`createElement`是`render 函數`的參數,它本身也是個函數,并且有三個參數。 ## **一:createElement()** >[success] **createElement()函數用于創建虛擬DOM元素** 第一個參數:**HTML標簽名`**或者**`一個組件對象`**或者**`一個 async 函數 。必填項** 第二個參數:一個與模板中屬性對應的`數據對象`。可選。 第三個參數:子元素虛擬節點 (VNodes),由 `createElement()` 構建而成, 也可以使用`字符串`來生成`文本虛擬節點`。可選 注意:有時候我們可以直接忽略第二個參數,vue會根據傳遞參數的數據類型,自動判斷傳遞的是第幾個參數,如果傳遞對象就是第二個參數,如果傳遞數組或字符串就是第三個參數。 ``` // @returns {VNode} createElement( // {String | Object | Function} // 一個 HTML 標簽名、組件選項對象,或者 // resolve 了上述任何一種的一個 async 函數。必填項。 'div', // {Object} // 一個與模板中屬性對應的數據對象。可選。 { // (詳情見下一節) }, // {String | Array} // 子虛擬節點 (VNodes),由 `createElement()` 構建而成, // 也可以使用字符串來生成“文本虛擬節點”。可選。 [ '先寫一些文字', createElement('h1', '一則頭條'), createElement(MyComponent, { props: { someProp: 'foobar' } }) ] ) ``` ## **二:createElement()的第二個參數——數據對象** 在使用模版中,我們綁定屬性使用到`v-bind:class`和`v-bind:style`這樣的語法,但在虛擬DOM元素中,這樣的語法將會寫在數據對象中。該對象可以綁定普通的 HTML 特性,也可以綁定如`innerHTML`這樣的 DOM 屬性 (這會覆蓋`v-html`指令) ### **數據對象:** ``` { // class綁定 等價于 v-bind:class // 接受一個字符串、對象或字符串和對象組成的數組 'class': { foo: true, bar: false }, // 樣式綁定,等價于 v-bind:style // 接受一個字符串、對象,或對象組成的數組 style: { color: 'red', fontSize: '14px' }, // 普通的 HTML 特性 attrs: { id: 'foo' }, // 組件 prop props: { myProp: 'bar' }, // DOM 屬性 domProps: { innerHTML: 'baz' }, // 事件監聽寫在`on`屬性中 // 但不再支持如 `v-on:keyup.enter` 這樣的修飾器。 // 需要在處理函數中手動檢查 keyCode。 on: { click: this.clickHandler }, // 僅用于組件,用于監聽原生事件,而不是組件內部使用 // `vm.$emit` 觸發的事件。 // 監聽自定義事件 nativeOn: { click: this.nativeClickHandler }, // 自定義指令。注意,你無法對 `binding` 中的 `oldValue` // 賦值,因為 Vue 已經自動為你進行了同步。 directives: [ { name: 'my-custom-directive', value: '2', expression: '1 + 1', arg: 'foo', modifiers: { bar: true } } ], // 作用域插槽的格式為 // { name: props => VNode | Array<VNode> } // 函數參數是傳遞的數據 scopedSlots: { default: props => createElement('span', props.text) }, // 如果組件是其它組件的子組件,需為插槽指定名稱 slot: 'name-of-slot', // 其它特殊頂層屬性 key: 'myKey', ref: 'myRef', // 如果你在渲染函數中給多個元素都應用了相同的 ref 名, // 那么 `$refs.myRef` 會變成一個數組。 refInFor: true } ``` 常用的數據對象選項: 1. class:控制類名 2. style :樣式 3. attrs :用來寫正常的 html 屬性 id src 等等 4. domProps :用來寫原生的dom 屬性 5. on:用來寫原生方法 >[info] 在使用時,有時候我們會省略第二個參數,只寫第一、第三個參數。那么為什么能跳過第二個參數呢?關鍵就在于參數的數據類型。第二個參數是**對象**類型,第三個參數是**字符串**或者**數組**,vue內部根據參數的類型判斷傳入的是那個參數。 實例: **HTML模版**: ``` <h1> <a name="hello-world" href="#hello-world"> Hello world! </a> </h1> ``` **使用渲染函數**: ``` Vue.component('anchored-heading', { render: function (createElement) { // 創建 kebab-case 風格的 ID var headingId = getChildrenTextContent(this.$slots.default) .toLowerCase() .replace(/\W+/g, '-') .replace(/(^-|-$)/g, '') return createElement( 'h' + this.level, //h標簽 [ createElement('a', { //h標簽內部的a標簽 attrs: { name: headingId, //a標簽的name屬性 href: '#' + headingId //a標簽的href屬性 } }, this.$slots.default) //a標簽里面的內容,這里傳入的是Hello world! ] ) }, props: { level: { type: Number, required: true } } ``` ### **約束** **虛擬節點必須唯一** 組件中的所有 VNode 必須是唯一的。例如,下面的渲染函數是不合法的: ``` render: function (createElement) { var myParagraphVNode = createElement('p', 'hi') return createElement('div', [ // 錯誤 - 重復的 VNode myParagraphVNode, myParagraphVNode ]) } ``` 如果需要渲染重復的虛擬節點,可以使用工廠函數實現: ``` render: function (createElement) { return createElement('div', Array.apply(null, { length: 20 }).map(function () { return createElement('p', 'hi') }) ) } ``` ## **三:使用 JavaScript 代替模板功能** 渲染函數本身就是一個函數,所以可以寫任意JavaScript代碼。 ### **1.`v-if`和 `v-for`** 在模板中使用的 v-if 和 v-for: ``` <ul v-if="items.length"> <li v-for="item in items">{{ item.name }}</li> </ul> <p v-else>No items found.</p> ``` 這些都可以在渲染函數中用 JavaScript 的 if/else 和 map 來重寫: ``` props: ['items'], render: function (createElement) { if (this.items.length) { return createElement('ul', this.items.map(function (item) { return createElement('li', item.name) })) } else { return createElement('p', 'No items found.') } } ``` ### **2.`v-model`** 渲染函數中沒有與`v-model`的直接對應——你必須自己實現相應的邏輯: ``` props: ['value'], render: function (createElement) { var self = this return createElement('input', { domProps: { value: self.value }, on: { input: function (event) { self.$emit('input', event.target.value) } } }) } ``` 等價于模版: ``` <input value="value" @input="$emit('input',$event.target.value)"></input> ``` 這就是深入底層的代價,但與 v-model 相比,這可以讓你更好地控制交互細節。 ### **3.事件 & 按鍵修飾符** 對于`.passive`、`.capture`和`.once`這些事件修飾符, Vue 提供了相應的前綴可以用于`on`: | 修飾符 | 前綴 | | --- | --- | | `.passive` | `&` | | `.capture` | `!` | | `.once` | `~` | | `.capture.once`或 | | | `.once.capture` | `~!` | 例如: ~~~ on: { '!click': this.doThisInCapturingMode, '~keyup': this.doThisOnce, '~!mouseover': this.doThisOnceInCapturingMode } ~~~ 對于所有其它的修飾符,私有前綴都不是必須的,因為你可以在事件處理函數中使用事件方法: | 修飾符 | 處理函數中的等價操作 | | --- | --- | | `.stop` | `event.stopPropagation()` | | `.prevent` | `event.preventDefault()` | | `.self` | `if (event.target !== event.currentTarget) return` | | 按鍵: | | | `.enter`,`.13` | `if (event.keyCode !== 13) return`(對于別的按鍵修飾符來說,可將`13`改為[另一個按鍵碼](http://keycode.info/)) | | 修飾鍵: | | | `.ctrl`,`.alt`,`.shift`,`.meta` | `if (!event.ctrlKey) return`(將`ctrlKey`分別修改為`altKey`、`shiftKey`或者`metaKey`) | 這里是一個使用所有修飾符的例子: ~~~ on: { keyup: function (event) { ? ?// 如果觸發事件的元素不是事件綁定的元素 ? ?// 則返回 ? ?if (event.target !== event.currentTarget) return ? ?// 如果按下去的不是 enter 鍵或者 ? ?// 沒有同時按下 shift 鍵 ? ?// 則返回 ? ?if (!event.shiftKey || event.keyCode !== 13) return ? ?// 阻止?事件冒泡 ? event.stopPropagation() ? ?// 阻止該元素默認的 keyup 事件 ? ?event.preventDefault() // ... } } ~~~ ### **4.插槽** 可以通過 `this.$slots` 訪問靜態插槽的內容,每個插槽都是一個`VNode` 數組 模版寫法: ``` <div><slot></slot></div> ``` 渲染函數寫法: ``` render: function (createElement) { return createElement('div', this.$slots.default) //this.$slots.default是默認插槽的內容,注意是虛擬節點數組 } ``` 也可以通過`this.$scopedSlots`訪問作用域插槽,每個作用域插槽都是一個返回若干 VNode 的函數: 模版寫法: ``` <div><slot :text="message"></slot></div> ``` 渲染函數寫法: ~~~ props: ['message'], render: function (createElement) { return createElement('div', [ this.$scopedSlots.default({ text: this.message }) ]) } ~~~ 如果要用渲染函數向子組件中傳遞作用域插槽,可以利用 VNode 數據對象中的`scopedSlots`字段: 模版寫法: ``` <div> <child slot-scope="default"> <span>{{default.text}}</span> </child> </div> ``` 渲染函數寫法: ~~~ render: function (createElement) { return createElement('div', [ createElement('child', { // 在數據對象中傳遞 `scopedSlots` // 格式為 { name: props => VNode | Array<VNode> } scopedSlots: { default: function (props) { return createElement('span', props.text) } } }) ]) } ~~~ ## **四:JSX** 如果你寫了很多`render`函數,可能會覺得下面這樣的代碼寫起來很痛苦: ~~~ createElement( 'anchored-heading', { props: { level: 1 } }, [ createElement('span', 'Hello'), ' world!' ] ) ~~~ 特別是對應的模板如此簡單的情況下: ~~~ <anchored-heading :level="1"> <span>Hello</span> world! </anchored-heading> ~~~ 這就是為什么會有一個[Babel 插件](https://github.com/vuejs/jsx),用于在 Vue 中使用 JSX 語法,它可以讓我們回到更接近于模板的語法上。 ~~~ import AnchoredHeading from './AnchoredHeading.vue' new Vue({ el: '#demo', render: function (h) { return ( <AnchoredHeading level={1}> <span>Hello</span> world! </AnchoredHeading> ) } }) ~~~ >[danger] 將`h`作為`createElement`的別名是 Vue 生態系統中的一個通用慣例,實際上也是 JSX 所要求的。從 Vue 的 Babel 插件的[3.4.0 版本](https://github.com/vuejs/babel-plugin-transform-vue-jsx#h-auto-injection)開始,我們會在以 ES5 語法聲明的含有 JSX 的任何方法和 getter 中 (不是函數或箭頭函數中) 自動注入`const h = this.$createElement`,這樣你就可以去掉`(h)`參數了。對于更早版本的插件,如果`h`在當前作用域中不可用,應用會拋錯。
                  <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>

                              哎呀哎呀视频在线观看