Search code examples
vue.jssvgnpmvue-cli

Vue Uncaught TypeError: _c is not a function


I use Vue-cli + vue-svg-loader to create an icon Library and then export it as package.

When I use it like this

<template>
  <div>
    <MyIcon />
  </div>
</template>

<script>
import { MyIcon } from 'package'

export default {
  components: {
    MyIcon
  }
}
</script>

I got this console.log error

Uncaught TypeError: _c is not a function

Then I inspect the souce code


module.exports = {
  functional: true,
  render: function render(_h, _vm) {
    console.log('_h', _h) // _h ƒ (a, b, c, d) { return createElement(_context, a, b, c, d, true); }
    console.log('_vm', _vm)
    // =>
    //     {props: {…}, data: {…}, parent: VueComponent, children: undefined, slots: ƒ}
    // props: {}
    // data: {}
    // parent: VueComponent {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
    // children: undefined
    // slots: ƒ ()
    // __proto__: Object
    var _c = _vm._c,
        _v = _vm._v,
        data = _vm.data,
        _vm$children = _vm.children,
        children = _vm$children === void 0 ? [] : _vm$children;

    var classNames = data.class,
        staticClass = data.staticClass,
        style = data.style,
        staticStyle = data.staticStyle,
        _data$attrs = data.attrs,
        attrs = _data$attrs === void 0 ? {} : _data$attrs,
        rest = _objectWithoutProperties(data, ["class", "staticClass", "style", "staticStyle", "attrs"]);

    return _c('svg', _objectSpread({
      class: [classNames, staticClass],
      style: [style, staticStyle],
      attrs: Object.assign({
        "xmlns": "http://www.w3.org/2000/svg",
        "width": "28",
        "height": "28",
        "viewBox": "0 0 28 28"
      }, attrs)
    }, rest), children.concat([_c('path', {
      attrs: {
        "d": "M151.406,139.047a1.136,1.136,0,0,0-.328-.839l-1.659-1.641a1.145,1.145,0,0,0-1.641,0l-7.437,7.419-4.12-4.12a1.145,1.145,0,0,0-1.641,0l-1.659,1.641a1.136,1.136,0,0,0-.328.839,1.113,1.113,0,0,0,.328.82l6.6,6.6a1.121,1.121,0,0,0,.82.346,1.142,1.142,0,0,0,.839-.346l9.9-9.9A1.113,1.113,0,0,0,151.406,139.047ZM156,142a13.7,13.7,0,0,1-1.878,7.027,13.937,13.937,0,0,1-5.1,5.1,14.089,14.089,0,0,1-14.055,0,13.937,13.937,0,0,1-5.1-5.1,14.09,14.09,0,0,1,0-14.055,13.937,13.937,0,0,1,5.1-5.1,14.09,14.09,0,0,1,14.055,0,13.937,13.937,0,0,1,5.1,5.1A13.7,13.7,0,0,1,156,142Z",
        "transform": "translate(-128 -128)",
        "fill": "currentColor"
      }
    })]));
  }
};

How can I fix this?


Solution

  • In functional component, second argument for render is context, not vm. Functional components has not own vm. See https://v2.vuejs.org/v2/guide/render-function.html#Functional-Components, first argument is createElement and is analog to vm._c for normal components. In your case you must use _h instead of vm._c

    It must not be so complex:

    const MyIcon = {
      functional: true,
      render: function render(_h, ctx) {
        return _h('svg', Object.assign({}, ctx.data,
          {attrs: Object.assign({
            "xmlns": "http://www.w3.org/2000/svg",
            "width": "28",
            "height": "28",
            "viewBox": "0 0 28 28"
          }, ctx.data.attrs ||{})}),
        [_h('path', {
          attrs: {
            "d": "M151.406,139.047a1.136,1.136,0,0,0-.328-.839l-1.659-1.641a1.145,1.145,0,0,0-1.641,0l-7.437,7.419-4.12-4.12a1.145,1.145,0,0,0-1.641,0l-1.659,1.641a1.136,1.136,0,0,0-.328.839,1.113,1.113,0,0,0,.328.82l6.6,6.6a1.121,1.121,0,0,0,.82.346,1.142,1.142,0,0,0,.839-.346l9.9-9.9A1.113,1.113,0,0,0,151.406,139.047ZM156,142a13.7,13.7,0,0,1-1.878,7.027,13.937,13.937,0,0,1-5.1,5.1,14.089,14.089,0,0,1-14.055,0,13.937,13.937,0,0,1-5.1-5.1,14.09,14.09,0,0,1,0-14.055,13.937,13.937,0,0,1,5.1-5.1,14.09,14.09,0,0,1,14.055,0,13.937,13.937,0,0,1,5.1,5.1A13.7,13.7,0,0,1,156,142Z",
            "transform": "translate(-128 -128)",
            "fill": "currentColor"
          }
        }), ctx.children]);
      }
    };
    
    new Vue({components:{MyIcon}}).$mount('div')
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div>
      <my-icon style='background:red'></my-icon>
      <my-icon><rect x="10" y="10" width="10" height="10" fill="lime" stroke="black" /></my-icon>
    </div>