日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue.js 2.x render 渲染函数 JSX

發布時間:2025/5/22 vue 151 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue.js 2.x render 渲染函数 JSX 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Vue.js 2.x render

渲染函數 & JSX

Vue絕大多數情況下使用template創建 HTML。但是比如一些重復性比較高的場景,需要運用 JavaScript 的完全編程能力,可以使用render函數。

1. 節點、樹以及虛擬DOM

每個元素都是一個節點。每片文字也是一個節點。甚至注釋也都是節點。
一個節點就是頁面的一個部分。每個節點都可以有子節點。

比如上面的節點樹就表示下面的代碼:

<div><h1>My title</h1>Some text content<!-- TODO: 添加標簽行 --> </div>

1.1 虛擬 DOM

Vue 通過建立一個虛擬 DOM 對真實 DOM 發生的變化保持追蹤。
虛擬 DOM 是對Vue組件樹建立起來的整個 VNode(Virtual Node)樹的稱呼。

1.1.1 createElement 參數
// @returns {VNode} createElement(// {String | Object | Function}// 一個 HTML 標簽字符串,組件選項對象,或者// 解析上述任何一種的一個 async 異步函數// 必須參數'div',// {Object}// 一個包含模板相關屬性的數據對象// 你可以在 template 中使用這些特性// 可選參數{ // 屬性參見 1.1.2 深入 data 對象},// {String | Array}// 子虛擬節點(VNodes) 由 createElement() 構建而成// 也可以使用字符串來生成“文本虛擬節點”// 可選參數['文字',createElement('h1', '一個標題'),createElement(MyComponent, {props: {someProp: 'foo'}})] )
1.1.2 深入 data 對象

在 VNode 數據對象中,下列屬性名是級別最高的字段。該對象也允許綁定普通的 HTML 特性,就像 DOM 屬性一樣,比如innerHTML(這會取代v-html指令)。

{// 和 v-bind:calss 一樣的API// 接收一個字符串、對象或字符串和對象組成的數組'class': {foo: true,bar: false},// 和 v-bind:style 一樣的API// 接收一個字符串、對象或對象組成的數組style: {color: 'red',fontSize: '14px'},// 普通的 HTML 特性attrs: {id: 'foo'},// 組件的 propsprops: {myProp: 'bar'},// DOM屬性domProps: {innerHTML: 'baz'},// 事件監聽器基于 on// 所以不再支持如 v-on:keyup.enter 修飾器// 需要手動匹配 keyCodeon: {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.1.3 完整示例

一個生成錨點標題的組件:

var getChildrenTextContent = function (children) {return children.map(function (node) {return node.children? getChildrenTextContent(node.children): node.text}).join('') }Vue.component('anchored-heading', {render: function (createElement) {// 創建 kebab-case 風格的IDvar headingId = getChildrenTextContent(this.$slots.default).toLowerCase().replace(/\W+/g, '-').replace(/(^-|-$)/g, '')return createElement('h' + this.level,[createElement('a', {attrs: {name: headingId,href: '#' + headingId}}, this.$slots.default)])},props: {level: {type: Number,required: true}} })

使用效果:

<div id="app"><anchored-heading :level="1">first</anchored-heading><anchored-heading :level="2">second</anchored-heading><anchored-heading :level="3">third<small>thirdSub</small></anchored-heading> </div>

1.1.4 約束

組件樹中的所有 VNodes 必須是唯一的。

比如這樣寫是錯誤的:

render: function (createElement) {var myParagraphVNode = createElement('p', 'hi')return createElement('div', [// 錯誤-重復的 VNodesmyParagraphVNode, myParagraphVNode]) }

如果需要重復多次元素/組件,可以用工廠函數來實現:

render: function(createElement) {return createElement('div',Array.apply(null, { length: 20 }.map(function() {return createElement('p', 'hello')}))); }

1.2 使用 JavaScript 代替模板功能

1.2.1 v-if 和 v-for

只要在原生的 JavaScript 中可以輕松完成的操作,Vue的render函數就不會提供專有的替代方法。
比如這里的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>

使用 render 方法重寫:

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 here.');} }
1.2.2 v-model

render 函數中沒有與 v-model直接對應的方法,需要手動實現:

props: ['value'], render: function (createElement) {var self = this;return createElement('input', {// DOM屬性domProps: {value: self.value},on: {input: function(e) {self.$emit('input', e.target.value);}}}) }

1.3 事件&按鍵修飾符

對于.passive、.capture、.once事件修飾符,Vue提供了相應的前綴可以用于on:

Modifier(s)Prefix
.passive&
.capture!
.once~
.capture.once或.once.capture~!

比如:

on: {'!click': this.doThisInCapturingMode,'~keyup': this.doThisOnce,'~!mouseover': this.doThisOnceInCapturingMode }

對于其他的修飾符,可以在事件處理函數中使用事件方法:

Modifier(s)Equivalent in Handler
.stope.stopPropagation()
.prevente.preventDefault()
.selfif (e.target !== e.currentTarget) return;
.enter, .13e.keyCode === 13

比如:

on: {keyup: function (event) {// 如果觸發事件的元素不是事件綁定的元素// 則返回if (event.target !== event.currentTarget) return// 如果按下去的不是 enter 鍵或者// 沒有同時按下 shift 鍵// 則返回if (!event.shiftKey || event.keyCode !== 13) return// 阻止 事件冒泡event.stopPropagation()// 阻止該元素默認的 keyup 事件event.preventDefault()// ...} }

1.4 插槽

可以通過this.$slots訪問靜態插槽內容,得到的是一個 VNodes 數組:

render: function(createElement) {// `<div><slot></slot></div>`return createElement('div', this.$slots.default) }

也可以通過this.$scopeSlots訪問作用域插槽,得到的是一個 VNodes 的函數:

props: ['message'], render: function(createElement) {// `<div><slot :text="message"></slot></div>`return createElement('div', [this.$scopedSlots.default({text: this.message})]) }

如果要用渲染函數句子向子組件中傳遞作用域插槽,可以利用 VNode 數據對象中的scopedSlots域:

render: function(createElement) {return createElement('div', [createElement('child', {// 在數據對象中傳遞 scopedSlots// 格式:{ name: props => VNode | Array<VNode> }scopedSlots: {default: function(props) {return createElement('span', props.text)}}})]) }

2. JSX

在Vue中使用JSX語法,可以避免書寫繁雜冗余的render代碼,Babel插件用于在Vue中使用JSX語法。

使用文檔

import AnchoredHeading from './AnchoredHeading.vue'new Vue({el: '#app',render: function(h) {return (<AnchoredHeading level={1}><span>Hello</span> world</AnchoredHeading>)} })

3. 函數式組件

一個函數是組件,意味著它是無狀態(沒有響應式數據),無實例(沒有this上下文)的:

Vue.component('my-component', {functional: true,// props可選 v2.3.0^props: {},// 為了彌補缺少的實例// 提供第二個參數作為上下文render(createElement, context) {} })

在v2.5.0^版本中,單文件組件基于模板的函數式組件可以這樣聲明:

<template functional></template>

組件需要的一切都是通過上下文來傳遞:

  • props 提供所有prop對象
  • children VNode子節點的數組
  • slots 返回所有插槽的對象的函數
  • scopedSlots 一個暴露傳入的作用域插槽以及函數形式的普通插槽的對象
  • data 傳遞給組件的數據對象,作為CreateElement的第二個參數傳入組件
  • parent 對父組件的引用
  • listeners 一個包含了所有在父組件上注冊的事件偵聽器的對象,data.on的別名
  • injections 如果使用了inject選項,該對象包含了應當被注入的屬性

之前的錨點標題組件可以改為如下的函數式組件:

...Vue.component('anchored-heading', {functional: true,render: function (createElement, context) {// 創建 kebab-case 風格的IDvar headingId = getChildrenTextContent(context.children).toLowerCase().replace(/\W+/g, '-').replace(/(^-|-$)/g, '')return createElement('h' + context.props.level,[createElement('a', {attrs: {name: headingId,href: '#' + headingId}}, context.children)])},props: {level: {type: Number,required: true}} })

3.1 想子組件或子元素傳遞特性和事件

在普通組件中,沒有被定義為 prop 的特性會自動添加到組件的根元素上,將現有的同名特性替換或智能合并。
而函數式組件要求必須顯示定義該行為:

Vue.component('my-functional-button', {functional: true,render: function(createElement, context) {return createElement('button', context.data, context.children)} })

如果使用模板的函數式組件,還需要手動添加特性和監聽器。

<template functional><buttonclass="btn btn-primary"v-bind="data.attrs"v-on="listeners"><slot/></button> </template>

3.2 slots()和children對比

slots()和children對比

總的來說個人理解,slots()可以拿到具名插槽,children拿到所有。

4. 模板編譯

模板編譯

The end
2019-8-13 15:45:59

轉載于:https://www.cnblogs.com/jehorn/p/11346358.html

總結

以上是生活随笔為你收集整理的Vue.js 2.x render 渲染函数 JSX的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本va欧美va精品发布 | 91伊人| 天天看av| 黄色欧美大片 | 亚洲精品综合在线观看 | 在线免费看黄网站 | 国产黄色a | 国产真人无遮挡作爱免费视频 | 欧美日韩国产一级片 | 亚洲高清视频在线观看 | 男女男精品视频网站 | 日韩福利电影在线观看 | 99视频免费| 欧美另类第一页 | 丰满秘书被猛烈进入高清播放在 | 午夜精品偷拍 | 深夜免费福利视频 | 青青青免费视频观看在线 | 日韩精品免费一区 | 草莓巧克力香氛动漫的观看方法 | 久久免费在线观看视频 | 久久久全国免费视频 | 美女超碰 | 特级毛片www| 国产日韩欧美二区 | 欧美老肥妇做爰bbww | 男女交性视频 | 欧美在线一区二区视频 | 天堂av中文 | 日韩欧美一区二区三区 | 色午夜婷婷 | 国产女同视频 | 免费av在线播放网址 | 久久98 | 国产传媒国产传媒 | 欧美色图在线观看 | 狠狠搞av| 免费国产区| 中出 在线 | 免费在线观看高清影视网站 | 亚洲 欧美 另类 综合 偷拍 | 夜夜嗨一区二区三区 | 精品久久久久久久久久久aⅴ | 在线观看亚洲大片短视频 | 国产高清日韩 | 婷婷在线影院 | 日穴| 天堂国产一区二区三区 | 啪啪一级片 | 少妇饥渴放荡91麻豆 | 伊人久久五月 | 成人做受视频试看60秒 | 少妇与公做了夜伦理69 | 精品网站| 国产三级一区 | 国精产品一区一区三区mba下载 | 国产欧美日韩视频 | 亚洲欧美激情另类 | 欧美亚洲精品在线观看 | 青娱网电信一区电信二区电信三区 | 黄色免费网站 | 成人7777 | 国产大屁股喷水视频在线观看 | 日本一本久久 | 99热这里都是精品 | 亚洲欧美日韩系列 | 国产在线欧美在线 | 国产女人在线 | www.亚洲天堂| 五月天亚洲综合 | 亚洲国产乱 | 亚洲欧美一区二区三 | 超能一家人电影免费喜剧在线观看 | 色成人免费网站 | 波多野一区 | 中文字幕一区二区三区在线观看 | 韩国一区二区三区在线观看 | 日本公妇乱淫免费视频一区三区 | 久色综 | av乱码| 少妇高潮一区二区三区99 | 免费观看黄色一级视频 | 精东传媒在线观看 | 天天爽夜夜爽夜夜爽精品 | 91热久久| 日本免费一区二区三区四区 | 国产精品一级 | 成人av地址 | 久久久久久久久免费 | va免费视频 | 美妇av | 日韩欧美亚洲一区二区 | 99久久久无码国产精品性波多 | 开心激情综合 | 男人的天堂在线视频 | 欧美在线视频免费观看 | 精品国产伦一区二区三 | 亚洲免费小视频 | 波多野吉衣在线视频 |