基于vue-cli理解render函数

栏目: JavaScript · 发布时间: 7年前

内容简介:下面的方法都是基于vue-cli来阐述的,首先要理解如何通过props来进行父子组件之间传值,参考https://segmentfault.com/a/1190000010913794。更多详情查看官网:注:第一个标签参数为必填项或者也可以把内容放在外面

下面的方法都是基于vue-cli来阐述的,首先要理解如何通过props来进行父子组件之间传值,参考https://segmentfault.com/a/1190000010913794。更多详情查看官网: cn.vuejs.org/v2/guide/re…

父组件

<template>
  <div>
    <component :my-data="items" :is="currentView"></component>
  </div>
</template>

<script>
import child from './child'
export default {
  data () {
    return {
      items: [1, 2, 3, 4],
      currentView: child
    }
  }
}
</script>
复制代码

一.基本用法

子组件 child.js

export default {
  props: {
    myData: Array
  },
  render: function (createElement) {
    return createElement('h3', this.myData)
  }
}
复制代码

注:第一个标签参数为必填项

基于vue-cli理解render函数

二.添加样式、方法

子组件 child.js

export default {
  props: {
    myData: Array
  },
  return createElement('h3', {
      'class': {
        foo: true,
        bar: false
      },
      style: {
        color: 'red',
        fontSize: '18px'
      },
      attrs: {
        id: 'my-data'
      },
      on: {
        click: this.handleClick
      }
      domProps: {
        innerHTML: this.myData
      }
  }),
  methods: {
    handleClick: function() {
        console.log(' I am data! ');
    }
  }
}
复制代码
基于vue-cli理解render函数

或者也可以把内容放在外面

export default {
  props: {
    myData: Array
  },
  return createElement('h3', {
      'class': {
        foo: true,
        bar: false
      },
      style: {
        color: 'red',
        fontSize: '18px'
      }
  },this.myData)
}
复制代码
基于vue-cli理解render函数

三.数组循环输出

子组件 child.js

export default {
  let items = this.myData
  return createElement('div',
    Array.apply(null, { length: items.length }).map(function (item, index) {
        return createElement('h3', items[index])
    })
  )
}
复制代码
基于vue-cli理解render函数

四.添加子元素

子组件 child.js

export default {
  return createElement('div', [// 由createElement函数构建而成的数组
    createElement('h1', '主标'), // createElement函数返回VNode对象
    createElement('h2', '副标')
  ])
}
复制代码
基于vue-cli理解render函数

五. this.$slots用法

父组件

<template>
  <div>
    <component :my-data="items" :is="currentView">
      <h1 slot="header"><span>About Me</span></h1>
      <p>Here is some page content</p>
      <p slot="footer">Copyright 2016 Evan You</p>
      <p>If I have some content down here</p>
    </component>
  </div>
</template>

<script>
import child from './child'
export default {
  data () {
    return {
      items: [1, 2, 3, 4],
      currentView: child
    }
  }
}
</script>
复制代码

子组件 child.js

export default {
  const {header, footer} = this.$slots
  const body = this.$slots.default
  return createElement('div', [
    createElement('header', header),
    createElement('main', body),
    createElement('footer', footer)
  ])
}
复制代码
基于vue-cli理解render函数

六. v-model用法

父组件

<template>
  <div>
    <component :name="name" :is="currentView" @input="val=>name=val"></component>
    <div>你的名字是:{{name}}</div>
  </div>
</template>

<script>
import child from './child'
export default {
  data () {
    return {
      name: '',
      currentView: child
    }
  }
}
</script>
复制代码

子组件 child.js

export default {
  props: {
    name: String
  },
  render: function (createElement) {
    var self = this
    return createElement('input', {
      domProps: {
        value: this.name
      },
      on: {
        input: function (event) {
          self.$emit('input', event.target.value)
        }
      }
    })
  }
}
复制代码
基于vue-cli理解render函数

七.作用域插槽(获取子组件数据)

父组件

<template>
  <div>
    <child>
      <template scope="props">
        <span>{{props.text}}</span>
      </template>
    </child>
  </div>
</template>

<script>
import child from './child'
</script>
复制代码

子组件 child.js

export default {
  props: {
    name: String
  },
  render: function (createElement) {
    return createElement('div', [
      this.$scopedSlots.default({
        text: 'hello world!'
      })
    ])
  },
}
复制代码
基于vue-cli理解render函数

八. 子组件之间传递作用域插槽

父组件

<template>
  <div>
    <child></child>
  </div>
</template>

<script>
import child from './child'
</script>
复制代码

子组件 child.js

import Vue from 'vue'
export default {
  render: function (createElement) {
    return createElement('div', [
      createElement('children', {
        scopedSlots: {
          default: function (props) {
            return [
              createElement('span', '来自父组件'),
              createElement('span', props.text)
            ]
          }
        }
      })
    ])
  }
}
Vue.component('children', {
  render: function (createElement) {
    return createElement('b',
    this.$scopedSlots.default({
      text: '我是子组件'
    }))
  }
})
复制代码
基于vue-cli理解render函数

九. 函数化组件

父组件

<template>
  <div>
    <child :data="data"></child>
  </div>
</template>

<script>
import child from './child'
export default {
  data () {
    return {
      data: {}
    }
  },
  components: {child},
  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: '这是一段纯文本'
        }
      }
    }
  },
  mounted: function () {
    this.change('img')
  }
}
</script>
复制代码

子组件 child.js

// 图片组件
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)
    ])
  }
}
export default {
  functional: true,
  render: function (createElement, context) {
    function getComponent () {
      var data = context.props.data
      switch (data.type) {
        case 'img':
          return ImgItem
        case 'video':
          return VideoItem
        default:
          return TextItem
      }
    }
    return createElement(
      getComponent(),
      context.data
      // context.children
    )
  }
  //在 2.3.0 或以上的版本中,你可以省略 props选项,所有组件上的特性都会被自动解析为 props。
  // props:{
  //    data:Object
  //}, 
}
复制代码

注:在添加 functional: true 之后,锚点标题组件的 render 函数之间简单更新增加 context 参数,this.$slots.default 更新为 context.children,之后this.data 更新为 context.props.data

组件需要的一切都是通过上下文传递,包括:

  • props:提供所有 prop 的对象
  • children: VNode 子节点的数组
  • slots: 返回所有插槽的对象的函数
  • data:传递给组件的数据对象,作为 createElement 的第二个参数传入组件
  • parent:对父组件的引用
  • listeners: (2.3.0+) 一个包含了所有在父组件上注册的事件侦听器的对象。这只是一个指向 data.on 的别名。
  • injections: (2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的属性。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

设计原本

设计原本

Frederick P. Brooks, Jr. / InfoQ中文站、王海鹏、高博 / 机械工业出版社 / 2011-1-1 / 55.00元

无论是软件开发、工程还是建筑,有效的设计都是工作的核心。《设计原本:计算机科学巨匠Frederick P. Brooks的思考》将对设计过程进行深入分析,揭示进行有效和优雅设计的方法。 本书包含了多个行业设计者的特别领悟。Frederick P. Brooks, Jr.精确发现了所有设计项目中内在的不变因素,揭示 了进行优秀设计的过程和模式。通过与几十位优秀设计者的对话,以及他自己在几个设计......一起来看看 《设计原本》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具