如何理解Vue的render函数的具体用法(2)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>render</title> <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script> </head> <body> <!-- VNode必须唯一 --> <div> <ele></ele> </div> <script> var child = { render: function(createElement) { return createElement('p', 'text'); } }; /*Vue.component('ele', { render: function(createElement) { var childNode = createElement(child); return createElement('div', [ childNode, childNode//VNodes必须唯一,渲染失败 ]); } });*/ Vue.component('ele', { render: function(createElement) { return createElement('div', Array.apply(null, { length: 2 }).map(function() { return createElement(child)//正确写法 }) ); } }); new Vue({ el: '#app' }) </script> </body> </html>

v-model指令

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>render</title> <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script> </head> <body> <div> <el-input :name="name" @input="val=>name=val"></el-input> <div>你的名字是{{name}}</div> </div> <script> Vue.component('el-input', { render: function(createElement) { var self = this; return createElement('input', { domProps: { value: self.name }, on: { input: function(event) { self.$emit('input', event.target.value); } } }) }, props: { name: String } }); new Vue({ el: '#app', data: { name: 'hdl' } }); </script> </body> </html>

作用域插槽

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>render</title> <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script> </head> <body> <div> <ele> <template scope="props"> <span>{{props.text}}</span> </template> </ele> </div> <script> Vue.component('ele', { render: function(createElement) { // 相当于<div><slot :text="msg"></slot></div> return createElement('div', [ this.$scopedSlots.default({ text: this.msg }) ]); }, data: function() { return { msg: '来自子组件' } } }); new Vue({ el: '#app' }); </script> </body> </html>

向子组件中传递作用域插槽

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>render</title> <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script> </head> <body> <div> <ele></ele> </div> <script> Vue.component('ele', { render: function(createElement) { return createElement('div', [ createElement('child', { scopedSlots: { default: function(props) { return [ createElement('span', '来自父组件'), createElement('span', props.text) ]; } } }) ]); } }); Vue.component('child', { render: function(createElement) { return createElement('b', this.$scopedSlots.default({text: '我是组件'})); } }); new Vue({ el: '#app' }); </script> </body> </html>

函数化组件

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>render</title> <script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script> </head> <body> <div> <smart-item :data="data"></smart-item> <button @click="change('img')">切换为图片为组件</button> <button @click="change('video')">切换为视频为组件</button> <button @click="change('text')">切换为文本组件</button> </div> <script> // 图片组件选项 var ImgItem = { props: ['data'], render: function(createElement) { return createElement('div', [ createElement('p', '图片组件'), createElement('img', { attrs: { src: this.data.url } }) ]); } } // 视频组件 var VideoItem = { props: ['data'], render: function(createElement) { return createElement('div', [ createElement('p', '视频组件'), createElement('video', { attrs: { src: this.data.url, controls: 'controls', autoplay: 'autoplay' } }) ]); } }; /*纯文本组件*/ var TextItem = { props: ['data'], render: function(createElement) { return createElement('div', [ createElement('p', '纯文本组件'), createElement('p', this.data.text) ]); } }; Vue.component('smart-item', { functional: true, render: function(createElement, context) { function getComponent() { var data = context.props.data; if (data.type === 'img') return ImgItem; if (data.type === 'video') return VideoItem; return TextItem; } return createElement( getComponent(), { props: { data: context.props.data } }, context.children ) }, props: { data: { type: Object, required: true } } }); new Vue({ el: '#app', data() { return { data: {} } }, methods: { change: function(type) { if (type === 'img') { this.data = { type: 'img', url: 'https://raw.githubusercontent.com/iview/iview/master/assets/logo.png' } } else if (type === 'video') { this.data = { type: 'video', url: 'http://vjs.zencdn.net/v/oceans.mp4' } } else if (type === 'text') { this.data = { type: 'text', content: '这是一段纯文本' } } } }, created: function() { this.change('img'); } }); </script> </body> </html>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wygxwy.html