我可以使用vue-fontawesome作为复选框选中标记吗?

时间:2018-02-13 14:05:43

标签: vue.js vuejs2 font-awesome

我正在使用vue-fontawesome和font-awesome-icon。这适用于“独立”图标,如:

<font-awesome-icon :icon="icon" size="1x" /> .

但是如何在vue组件方式中使用<input type="checkbox">的fontawesome复选标记?

3 个答案:

答案 0 :(得分:8)

有一种方法可以查找css伪元素:

FontAwesomeConfig = { searchPseudoElements: true };

不建议使用此方法,因为它会检查现有标记,并通过CSS样式为伪元素添加内联SVG,这很慢。

我不鼓励这种方法,所以我不会解释它是如何工作的,如果你有兴趣可以阅读更多关于here的信息。

不使用伪元素,而是为这些复选框创建一个组件。

我们将创建一个名为awesome-checkbox的单个文件组件。

<强> AwesomeCheckbox.vue

<template>
  <div :class="{'awesome-checkbox': true, [wrapperClassName]: !!wrapperClassName}"
       :style="{ color: isChecked ? checkedColor : uncheckedColor }">
    <input :id="id"
           :name="name"
           type="checkbox"
           class="awesome-checkbox__input"
           v-model="checkboxModel">
    <label :for="id"
           :style="{ cursor }"
           class="awesome-checkbox__label"
           @click="toggleCheck">
      <font-awesome-icon :icon="isChecked ? checkedIcon : uncheckedIcon"
                         :size="size" />
    </label>
  </div>
</template>

<script>
import FontAwesomeIcon from '@fortawesome/vue-fontawesome';
import { faSquare, faCheckSquare } from '@fortawesome/fontawesome-free-solid';

/**
 * Custom HTML <input> checkbox element using Font-Awesome-Icon 5 icons for visual effect.
 */
export default {
  name: 'awesome-checkbox',

  components: { FontAwesomeIcon },

  props: {
    /**
     * A wrapper class other than default that provides extra manipulation from parent component.
     */
    wrapperClassName: {
      type: String,
      default: null,
    },
    /**
     * The name attribute for the checkbox input.
     */
    name: {
      type: String,
      default: null,
    },
    /**
     * The id attribute for the checkbox input.
     */
    id: {
      type: String,
      default: null,
      required: true,
    },
    /**
     * The model directive value to create two-way data binding.
     */
    model: {
      type: Boolean,
      default: null,
      required: true,
    },
    /**
     * The mouse cursor to display when the mouse pointer is over the Font-Awesome-Icon 5 element.
     * Accepts any cursor CSS property value.
     */
    cursor: {
      type: String,
      default: 'pointer',
    },
    /**
     * The Font-Awesome-Icon 5 imported icon object used for the unchecked state.
     */
    uncheckedIcon: {
      type: Object,
      default: () => faSquare,
    },
    /**
     * The Font-Awesome-Icon 5 imported icon object used for the checked state.
     */
    checkedIcon: {
      type: Object,
      default: () => faCheckSquare,
    },
    /**
     * The Font-Awesome-Icon 5 icon size.
     */
    size: {
      type: String,
      default: '1x',
    },
    /**
     * The Font-Awesome-Icon 5 icon color used for the unchecked state.
     */
    uncheckedColor: {
      type: String,
      default: 'inherit',
    },
    /**
     * The Font-Awesome-Icon 5 icon color used for the checked state.
     */
    checkedColor: {
      type: String,
      default: 'inherit',
    },
  },

  data() {
    return {
      isChecked: !!this.model,
      checkboxModel: this.model,
    };
  },

  methods: {
    emitModelValueUpdate() {
      /**
       * Update event.
       *
       * @event update
       * @type {boolean}
       */
      this.$emit('update:model', this.isChecked);
    },
    /**
     * Gets called when the user clicks on the label element.
     */
    toggleCheck() {
      this.isChecked = !this.isChecked;
      this.emitModelValueUpdate();
    },
  },
};
</script>

<style lang="scss" scoped>
.awesome-checkbox {
  display: inline-flex;

  &__label {
    font-size: 1em; // Change Font-Awesome-Icon 5 icon size with css instead of predefined Font-Awesome-Icon 5 size prop.
  }

  &__input {
    display: none; // Hide the HTML <input> element.
  }
}
</style>

并在父组件中使用它,如下所示:

<template>
  <div>
    <awesome-checkbox :model.sync="acceptTerms"
                      checkedColor="#41B883"
                      uncheckedColor="#E0EAF1"
                      cursor="pointer"
                      size="1x"
                      id="my-awesome-checkbox"
                      name="acceptTerms"
                      :checkedIcon="faCheckSquare"
                      :uncheckedIcon="faSquare" />
  </div>
</template>

<script>
import { faSquare, faCheckSquare } from '@fortawesome/fontawesome-free-solid';
import AwesomeCheckbox from '@/components/path/to/AwesomeCheckbox';

export default {
  name: 'parent-component',

  components: { AwesomeCheckbox },

  data() {
    return {
      acceptTerms: false,
      faSquare,
      faCheckSquare,
    };
  },
};
</script>

<style lang="scss" scoped>
/* ... */
</style>

您可以根据需要扩展此组件,例如使model prop接受多种类型,例如Array而不是布尔值。

我刚刚为您的问题制作了这个组件,并且未对其进行全面测试,请谨慎使用。

答案 1 :(得分:1)

像我一样,使用Ricky的全部努力,但为可能正在寻找的人使用打字稿。

复选框

<template>
  <div :class="{'awesome-checkbox': true, [wrapperClassName]: !!wrapperClassName}"
       :style="{ color: checked ? checkedColor : uncheckedColor }">
    <input :id="id"
           :name="name"
           type="checkbox"
           class="awesome-checkbox__input"
           v-model="checked">
    <label :for="id"
           :style="{ cursor }"
           class="awesome-checkbox__label"
           @click="toggleCheck">
      <font-awesome-icon :icon="checked ? checkedIcon : uncheckedIcon"
                         :size="size" />
    </label>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { faSquare, faCheckSquare } from '@fortawesome/fontawesome-free-solid';

@Component

export default class Checkbox extends Vue {
  @Prop({default: null})
  wrapperClassName!: string;

  @Prop({default: null})
  name!: string;

  @Prop({default: null, required: true})
  id!: string;

  @Prop({default: null, required: true})
  model!: Boolean;

  @Prop({default: 'pointer'})
  cursor!: string;

  @Prop({default: () => faSquare})
  uncheckedIcon!: Object;

  @Prop({default: () => faCheckSquare})
  checkedIcon!: Object;

  @Prop({default: '1x'})
  size!: string;

  @Prop({default: 'inherit'})
  uncheckedColor!: string;

  @Prop({default: 'inherit'})
  ucheckedColor!: string;

  private emitModelValueUpdate() {
    /**
     * Update event.
     *
     * @event update
     * @type {boolean}
     */
    this.$emit('update:model', this.$data.checked);
  }
  private toggleCheck() {
    this.$data.checked = !this.$data.checked;
    this.emitModelValueUpdate();
  }

  constructor() {
    super();
  }

  public data() {
    return {
      checked: false,
    };
  }

}
</script>

<style lang="scss" scoped>
.awesome-checkbox {
  display: inline-flex;

  &__label {
    font-size: 1em; // Change Font-Awesome-Icon 5 icon size with css instead of predefined Font-Awesome-Icon 5 size prop.
  }

  &__input {
    display: none; // Hide the HTML <input> element.
  }
}
</style>

父母

<template>
  <div class="content">
    <b-row>      
      <b-col>
        <Checkbox />
      </b-col>
    </b-row>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import Checkbox from '@/components/forms/Checkbox.vue';

@Component({
  components: {
    Checkbox,
  },
})

export default class DevHelper extends Vue {
  @Prop() private msg!: string;
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">

</style>

希望有帮助。

答案 2 :(得分:0)

您可以通过使用css <input>隐藏display:none,然后使用css和伪<label>类设置::before样式,以典型方式执行此操作。

这是一个与Vue和Fontawesome https://jsfiddle.net/skribe/9fxsn797/3/

一起工作的Jfiddle

在你的组件中......

<input id='ckb_1' type="checkbox" v-model="ckb_1" value="checked">
<label for='ckb_1'>Check Box</label>

在你的css ......

input[type=checkbox] + label::before {
   content: '\f0c8';
   font-family: FontAwesome;
   display: inline-block;
   padding-right: 5px;
} 

input[type=checkbox]:checked + label::before {
   content: '\f14a';
}

input {
  display:none;
 }

我添加了一个v-model来使其成为Vue-esque,但这里没有任何内容特别是“vue组件方式”,而不是它在vue组件中。