Vue的函数化组件

mac2024-06-30  54

函数化组件

Vue.js提供了一个 functional 的布尔值选项,设置为true可以使组件无状态和无实例,也就是没有 data 和 this上下文。

好处:只是一个函数,渲染开销要小很多。

使用函数化组件时,Render 函数提供了第二个参数 context 来提供临时上下文。 组件需要的data、props、slots、chidren、parent 都是通过这个上下文来传递的。

------- 这里插一段createElement的用法 ------

createElement( // {String | Object | Function} // 一个 HTML 标签,组件选项,或是一个函数 // 必须 Return 上述其中一个 'div', // {Object} // 一个对应属性的数据对象,可选 { // 比如: // attrs: {} 正常的HTML特性 // props: {} 组件props // domProps: {} DOM属性 // on: {} 自定义事件监听器“on” }, // {String | Array} [ createElement('h1', 'hello world'), createElement(MyComponent, { props: { someProps: 'foo' } }) ] )

------------- 分割线 -------------

函数化组件实例:

<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; // 判断 props: data的type字段是属于哪种类型的组件 if (data.type === 'img') return ImgItem if (data.typev === 'video') return VideoItem return TextItem; } return createElement( getComponent(), { props: { // 把 smart-item 的prop: data 传给上面智能选择的组件 data: context.props.data } }, // 即原来的 this.$slot.default context.children ) }, props: { data: { type: Object, required: true } } }); var app = new Vue({ el: '#app', data: { data: {} }, methods: { // 切换不同类型组件的数据 change: function (type) { if (type === 'img') { this.data = { type: 'img', url: '' } } else if (type === 'video') { this.data = { type: 'video', url: '' } } else if (type === 'text') { this.data = { type: 'text', context: '这是一段文本' } } } }, created: function () { this.change('img') } }) </script>

函数化组件在业务中并不是很常用,主要适用于以下两个场景:

程序化地在多个组件中选择一个。在将children, props, data 传递给子组件之前操作它们。
最新回复(0)