使用vue样式的组件和动态组件

时间:2018-12-28 04:39:52

标签: vue.js vue-component styled-components

我正在尝试使用vue-styled-components npm软件包动态呈现组件。我想用单个<component>标签来渲染样式化的组件,但是到目前为止我尝试过的所有方法都失败了。

下面是我要达到的目标的示例,但是我收到错误消息TypeError: Right-hand side of 'instanceof' is not an object

<template>
  <component
    :is="getStyledIcon(component)"
    :src="iconSrc"
    :width="width"
    :height="height"
    :rounded="rounded"
    :fill="fill"
    :fill-hover="fillHover"
    :stroke="stroke"
    :stroke-hover="strokeHover"
    class="icon"
  />
</template>

<script>
import iconStyles from './iconStyles'
import styled from 'vue-styled-components'

export default {
  name: 'Icon',
  props: {
    /**
     * String or SVG icon component.
     * If icon is a string, an img tag with src will be rendered.
     * If icon is a component imported with
     *   require('-!vue-svg-loader!@sky-foundry/ui/src/assets/images/[ICON NAME].svg')
     * then the raw svg will be rendered.
     */
    icon: {
      type: [Object, String],
      required: true,
    },
    /**
     * Width of icon.
     */
    width: {
      type: String,
      default: null,
    },
    /**
     * Height of icon.
     */
    height: {
      type: String,
      default: '32px',
    },
    /**
     * Round the icon.
     */
    rounded: {
      type: String,
      default: '',
    },
    inline: {
      type: Boolean,
      default: false,
    },
    /**
     * Set the fill color of the SVG.
     */
    fill: {
      type: String,
      default: '',
    },
    /**
     * Set the fill color of the SVG on hover.
     */
    fillHover: {
      type: String,
      default: '',
    },
    /**
     * Set the stroke color of the SVG.
     */
    stroke: {
      type: String,
      default: '',
    },
    /**
     * Set the stroke color of the SVG on hover.
     */
    strokeHover: {
      type: String,
      default: '',
    },
  },
  computed: {
    component() {
      return typeof this.icon === 'string' ? 'img' : this.icon
    },
    iconSrc() {
      return typeof this.icon === 'string' ? this.icon : undefined
    },
  },
  methods: {
    getStyledIcon(component) {
      if (this.icon === 'string') {
        component.name = 'Icon'
      }

      return styled(component, this.$props)`
        ${iconStyles};
      `
    },
  },
}
</script>

iconStyles.js

import { css } from 'vue-styled-components'
import transition from '../../styles/transition'

const iconStyles = ({
  width,
  height,
  rounded,
  inline,
  fill,
  stroke,
  fillHover,
  strokeHover,
}) => css`
  ${height &&
    css`
      height: ${height};
    `}
  ${width &&
    css`
      width: ${width};
    `}
  ${rounded &&
    css`
      border-radius: ${rounded};
    `}
  ${inline &&
    css`
      display: inline-block;
    `}

  > * {
    ${transition()};

    ${fill &&
      css`
        fill: ${fill};
      `}
    ${stroke &&
      css`
        stroke: ${stroke};
      `}
  }

  &:hover > * {
    ${fillHover &&
      css`
        fill: ${fillHover};
      `}
    ${strokeHover &&
      css`
        stroke: ${strokeHover};
      `}
  }
`

export default iconStyles

0 个答案:

没有答案