基于vue-cli理解render函数

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

内容简介:下面的方法都是基于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 选项,则该对象包含了应当被注入的属性。

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

查看所有标签

猜你喜欢:

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

The Information

The Information

James Gleick / Vintage / 2012-3-6 / USD 16.95

James Gleick, the author of the best sellers Chaos and Genius, now brings us a work just as astonishing and masterly: a revelatory chronicle and meditation that shows how information has become th......一起来看看 《The Information》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器