如何理解Vue的render函数的具体用法
程序员文章站
2022-11-26 12:49:40
本文介绍了如何理解vue的render函数的具体用法,分享给大家,具体如下:
第一个参数(必须) - {string | object | function}...
本文介绍了如何理解vue的render函数的具体用法,分享给大家,具体如下:
第一个参数(必须) - {string | object | function}
<!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 id="app"> <elem></elem> </div> <script> vue.component('elem', { render: function(createelement) { return createelement('div');//一个html标签字符 /*return createelement({ template: '<div></div>'//组件选项对象 });*/ /*var func = function() { return {template: '<div></div>'} }; return createelement(func());//一个返回html标签字符或组件选项对象的函数*/ } }); new vue({ el: '#app' }); </script> </body> </html>
第二个参数(可选) - {object}
<!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 id="app"> <elem></elem> </div> <script> vue.component('elem', { render: function(createelement) { var self = this; return createelement('div', {//一个包含模板相关属性的数据对象 'class': { foo: true, bar: false }, style: { color: 'red', fontsize: '14px' }, attrs: { id: 'foo' }, domprops: { innerhtml: 'baz' } }); } }); new vue({ el: '#app' }); </script> </body> </html>
第三个参数(可选) - {string | array}
<!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 id="app"> <elem></elem> </div> <script> vue.component('elem', { render: function(createelement) { var self = this; // return createelement('div', '文本');//使用字符串生成文本节点 return createelement('div', [//由createelement函数构建而成的数组 createelement('h1', '主标'),//createelement函数返回vnode对象 createelement('h2', '副标') ]); } }); 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 id="app"> <ele></ele> </div> <script> /*vue.component('ele', { template: '<div id="elem" :class="{show: show}" @click="handleclick">文本</div>', data: function() { return { show: true } }, methods: { handleclick: function() { console.log('clicked!'); } } });*/ vue.component('ele', { render: function(createelement) { return createelement('div', { 'class': { show: this.show }, attrs: { id: 'elem' }, on: { click: this.handleclick } }, '文本'); }, data: function() { return { show: true } }, methods: { handleclick: function() { console.log('clicked!'); } } }); new vue({ el: '#app' }); </script> </body> </html>
this.$slots用法
<!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 id="app"> <blog-post> <h1 slot="header"><span>about me</span></h1> <p>here's some page content</p> <p slot="footer">copyright 2016 evan you</p> <p>if i have some content down here</p> </blog-post> </div> <script> vue.component('blog-post', { render: function(createelement) { var header = this.$slots.header,//返回由vnode组成的数组 body = this.$slots.default, footer = this.$slots.footer; return createelement('div', [ createelement('header', header), createelement('main', body), createelement('footer', footer) ]) } }); new vue({ el: '#app' }); </script> </body> </html>
使用props传递数据
<!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 id="app"> <ele :show="show"></ele> <ele :show="!show"></ele> </div> <script> vue.component('ele', { render: function(createelement) { if (this.show) { return createelement('p', 'true'); } else { return createelement('p', 'false'); } }, props: { show: { type: boolean, default: false } } }); new vue({ el: '#app', data: { show: false } }); </script> </body> </html>
vnodes必须唯一
<!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 id="app"> <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 id="app"> <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 id="app"> <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 id="app"> <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 id="app"> <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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。