今回は、vue レンダー開発の例について詳しく説明します。vue レンダー開発の注意点は何ですか?実際の事例を見てみましょう。
はじめに
Vue を開発に使用する場合、ほとんどの場合、テンプレートを使用して開発するのが簡単で便利で高速ですが、場合によっては、テンプレートが特殊なシナリオにはあまり適していないことがあります。そこで、レンダリング機能を使いこなすために、詳しく調べてみることにしました。以下に書かれていることが間違っていると思われる場合は、私とのやり取りが執筆の最大の動機ですので、ご指摘ください。
シナリオ
公式ウェブサイトで説明されているシナリオ レベルプロパティを通じて見出しタグを動的に生成するコンポーネントを書き始めると、すぐに次のように実装することを考えるかもしれません:
<script type="text/x-template" id="anchored-heading-template"> <h1 v-if="level === 1"> <slot></slot> </h1> <h2 v-else-if="level === 2"> <slot></slot> </h2> <h3 v-else-if="level === 3"> <slot></slot> </h3> <h4 v-else-if="level === 4"> <slot></slot> </h4> <h5 v-else-if="level === 5"> <slot></slot> </h5> <h6 v-else-if="level === 6"> <slot></slot> </h6> </script>
Vue.component('anchored-heading', { template: '#anchored-heading-template', props: { level: { type: Number, required: true } } })
このシナリオでのテンプレートの使用は、最良の選択: まず、コードが冗長です。さまざまなレベルのタイトルに anchor 要素を挿入するには、
テンプレートはほとんどのコンポーネントでうまく機能しますが、ここではあまりきれいではありません。そこで、render 関数を使用して上記の例を書き直してみましょう:
Vue.component('anchored-heading', { render: function (createElement) { return createElement( 'h' + this.level, // tag name 标签名称 this.$slots.default // 子组件中的阵列 ) }, props: { level: { type: Number, required: true } } })
より単純かつ明確になります。簡単に言うと、このコードは非常に単純ですが、Vue のインスタンス プロパティに精通している必要があります。この例では、アンカー見出しの Hello world! など、slot 属性を使用せずにコンポーネントにコンテンツを渡すと、それらの子要素がコンポーネント インスタンスの $slots.default に格納されることを知っておく必要があります。
createElement パラメーターの概要
次に理解しておく必要があるのは、createElement 関数でテンプレートを生成する方法です。 createElement によって受け入れられるパラメーターは次のとおりです:
createElement( // {String | Object | Function} // 一个 HTML 标签字符串,组件选项对象,或者 // 解析上述任何一种的一个 async 异步函数,必要参数。 'p', // {Object} // 一个包含模板相关属性的数据对象 // 这样,您可以在 template 中使用这些属性。可选参数。 { // (详情见下一节) }, // {String | Array} // 子节点 (VNodes),由 `createElement()` 构建而成, // 或使用字符串来生成“文本节点”。可选参数。 [ '先写一些文字', createElement('h1', '一则头条'), createElement(MyComponent, { props: { someProp: 'foobar' } }) ] )
データ オブジェクトの詳細
注意すべき点: テンプレート構文と同様に、v-bind:class および v-bind:style は、次のように特別に扱われます。 VNode データ オブジェクトでは、次の属性名が最上位のフィールドです。このオブジェクトを使用すると、innerHTML などの DOM プロパティのような通常の HTML 属性をバインドすることもできます (これは v-html ディレクティブを置き換えます)。
{ // 和`v-bind:class`一样的 API 'class': { foo: true, bar: false }, // 和`v-bind:style`一样的 API style: { color: 'red', fontSize: '14px' }, // 正常的 HTML 特性 attrs: { id: 'foo' }, // 组件 props 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 } } ], // Scoped slots in the form of // { name: props => VNode | Array<VNode> } scopedSlots: { default: props => createElement('span', props.text) }, // 如果组件是其他组件的子组件,需为插槽指定名称 slot: 'name-of-slot', // 其他特殊顶层属性 key: 'myKey', ref: 'myRef' }
条件付きレンダリング
上記の API については理解したので、実際に戦闘をしてみましょう。
前はこう書いてました
//HTML <p id="app"> <p v-if="isShow">我被你发现啦!!!</p> </p> <vv-isshow :show="isShow"></vv-isshow> //js //组件形式 Vue.component('vv-isshow', { props:['show'], template:'<p v-if="show">我被你发现啦2!!!</p>', }); var vm = new Vue({ el: "#app", data: { isShow:true } });
renderはこう書いてました
//HTML <p id="app"> <vv-isshow :show="isShow"><slot>我被你发现啦3!!!</slot></vv-isshow> </p> //js //组件形式 Vue.component('vv-isshow', { props:{ show:{ type: Boolean, default: true } }, render:function(h){ if(this.show ) return h('p',this.$slots.default); }, }); var vm = new Vue({ el: "#app", data: { isShow:true } });
リストレンダリング
前はこう書いてましたが、v-forの場合はテンプレートをラベルで囲む必要があります
//HTML <p id="app"> <vv-aside v-bind:list="list"></vv-aside> </p> //js //组件形式 Vue.component('vv-aside', { props:['list'], methods:{ handelClick(item){ console.log(item); } }, template:'<p>\ <p v-for="item in list" @click="handelClick(item)" :class="{odd:item.odd}">{{item.txt}}</p>\ </p>', //template:'<p v-for="item in list" @click="handelClick(item)" :class="{odd:item.odd}">{{item.txt}}</p>',错误 }); var vm = new Vue({ el: "#app", data: { list: [{ id: 1, txt: 'javaScript', odd: true }, { id: 2, txt: 'Vue', odd: false }, { id: 3, txt: 'React', odd: true }] } });
renderはこう書きました
//HTML <p id="app"> <vv-aside v-bind:list="list"></vv-aside> </p> //js //侧边栏 Vue.component('vv-aside', { render: function(h) { var _this = this, ayy = this.list.map((v) => { return h('p', { 'class': { odd: v.odd }, attrs: { title: v.txt }, on: { click: function() { return _this.handelClick(v); } } }, v.txt); }); return h('p', ayy); }, props: { list: { type: Array, default: () => { return this.list || []; } } }, methods: { handelClick: function(item) { console.log(item, "item"); } } }); var vm = new Vue({ el: "#app", data: { list: [{ id: 1, txt: 'javaScript', odd: true }, { id: 2, txt: 'Vue', odd: false }, { id: 3, txt: 'React', odd: true }] } });
v-model
前の書き方
//HTML <p id="app"> <vv-models v-model="txt" :txt="txt"></vv-models> </p> //js //input Vue.component('vv-models', { props: ['txt'], template: '<p>\ <p>看官你输入的是:{{txtcout}}</p>\ <input v-model="txtcout" type="text" />\ </p>', computed: { txtcout:{ get(){ return this.txt; }, set(val){ this.$emit('input', val); } } } }); var vm = new Vue({ el: "#app", data: { txt: '', } });
renderはこう書きました
//HTML <p id="app"> <vv-models v-model="txt" :txt="txt"></vv-models> </p> //js //input Vue.component('vv-models', { props: { txt: { type: String, default: '' } }, render: function(h) { var self=this; return h('p',[h('p','你猜我输入的是啥:'+this.txt),h('input',{ on:{ input(event){ self.$emit('input', event.target.value); } } })] ); }, }); var vm = new Vue({ el: "#app", data: { txt: '', } });
の事例を読んで、方法をマスターしたと思います。この記事のさらに興味深い情報については、PHP 中国語 Web サイトの他の関連記事にご注目ください。
推奨読書:
Angular でページの部分印刷を実装する手順の詳細な説明
以上がvue render開発例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。