Vue.js не может переключать значок с отличным шрифтом

Я пытаюсь переключить значок font awesome на основе логического значения, но кажется, что значок font-awesome остается на экране после того, как он нарисован:

https://jsfiddle.net/50wL7mdz/200312/

HTML:

<script src = "https://unpkg.com/vue"></script>
<script defer src = "https://use.fontawesome.com/releases/v5.0.8/js/all.js" integrity = "sha384-SlE991lGASHoBfWbelyBPLsUlwY1GwNDJo3jSJO04KZ33K2bwfV9YBauFfnzvynJ" crossorigin = "anonymous"></script>



<div id = "app">
  <input v-model = "marked" type = "checkbox"/>
  <i v-if = "marked" class = "far fa-check-square"></i>
</div>

JS:

new Vue({
  el: '#app',
  data: {
    marked: false
  }
})

Я что-то делаю не так или есть ошибка в font-awesome или vue.js?

Иногда это остается, а иногда нет. Вы тоже замечаете такое поведение?

acdcjunior 18.03.2018 01:47

По мне, как только он появляется, он остается.

TheOne 18.03.2018 01:48
github.com/vuetifyjs/vuetify/issues/3058
TheOne 18.03.2018 01:49

Ненавижу, когда такое случается, когда я кого-то учу этому. Это сбивает меня с толку.

chickens 18.03.2018 01:53
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
9
4
7 674
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Комментарии к тегу "i" не отображаются после перехода на svg, используйте обертку <span v-if = "marked"><i class = "far fa-check-square"></i></span>

В данном случае это не поможет: jsfiddle.net/50wL7mdz/201741 Я переключился с js на css, как указано в приведенной выше ссылке, и это устранило проблему.

TheOne 18.03.2018 20:46

Спасибо! не мог понять, почему мой SVG не удаляется из DOM

Ettore Raimondi 30.11.2020 15:58

Этот ответ относится к использованию Font Awesome с SVG.

По какой-то причине вам нужно дважды обернуть тег i. Например, вместо этого:

<div v-if = "condition">
  <i class = "fal fa-caret-left"></i>
</div>
<div v-else>
  <i class = "fas fa-caret-left"></i>
</div>

сделай это:

<template v-if = "condition">
  <div>
    <i class = "fal fa-caret-left"></i>
  </div>
</template>
<template v-else>
  <div>
    <i class = "fas fa-caret-left"></i>
  </div>
</template>

Не совсем уверен, почему вам нужно обернуть его дважды, так как я думаю, вы достаточно развязали тег i, обернув его один раз, но у меня это сработало, так что, по-видимому, происходит что-то еще.

Также имейте в виду, что внутренний div нельзя заменить на template по очевидным причинам (теги шаблона не отображаются).

Недавно я столкнулся с этой проблемой при использовании Vue.js 2.5.x с FontAwesome 5.5.x - классы значков не обновлялись должным образом.

После перехода с реализации FontAwesome Web Fonts + CSS на SVG + JS, следующий код больше не работал:

<i :class = "[sortByFirstNameAsc ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>

Что произойдет, так это то, что FontAwesome JavaScript запустит и обернет тег <i> и заменит его элементом SVG, как в следующем упрощенном примере:

<span data-v-2614dbd6 = "">
  <svg data-v-2614dbd6 = "" class = "svg-inline--fa fa-caret-up" ...">
    ...
  </svg>

  <!-- <i data-v-2614dbd6 = "" class = "fa fa-caret-up"></i> -->
</span>

К сожалению, активный класс переключался на внутренний скрытый тег <i>, а не на внешний видимый элемент SVG.

Обходной путь, который восстановил динамическое переключение активного класса, заключался в том, чтобы обернуть значки FontAwesome в диапазон и использовать Директива v-show, как показано в следующем фрагменте кода:

<span v-show = "sortByFirstNameAsc"><i class = "fa fa-caret-up"></i></span>
<span v-show = "sortByFirstNameDesc"><i class = "fa fa-caret-down"></i></span>

Документация FontAwesome теперь рекомендует, использующая их компонент Vue, чтобы избежать конфликтов в DOM:

Compatibility Heads Up! If you are using Vue you need the vue-fontawesome package or Web Fonts with CSS.

Базовый пакет SVG полезен и рекомендуется в следующих случаях:

  • чтобы разделить большое количество значков только на те, которые вы используете
  • в качестве базовых библиотек для более широкой интеграции с такими инструментами, как React, Angular, Vue или Ember (на самом деле, наши собственные компоненты используют эти пакеты)
  • как инструмент объединения модулей CommonJS / ES6, например Webpack, Rollup или Parcel
  • как библиотека загрузчика в стиле UMD, например RequireJS
  • непосредственно на сервере с помощью CommonJS (см. нашу документацию по рендерингу на стороне сервера).

Я исправил это, создав шаблон для каждого значка, а затем загрузив любой шаблон условно на основе логического значения.

Вот мой основной шаблон:

 <div v-if = "minimised">

                        <maximise-icon>
                            
                        </maximise-icon>

                    </div>

                    <div v-if = "!minimised">

                        <minimise-icon>
                        
                        </minimise-icon>
                     </div>

Затем просто создайте значки следующим образом:

FontAwesomeConfig = { autoReplaceSvg: 'nest' }//important addition!

Vue.component('minimise-icon', {

    template:
    `
        <i class = "fas fa-minus "></i>

    `

})


Vue.component('maximise-icon', {

    template:
    `
        <i class = "fas fa-plus "></i>

    `

})

Если есть более элегантный способ, я все уши!

Библиотека Font Awesome, которую вы использовали, не знает о Vue. Он берет <i>, который вы написали, и превращает его в <svg>, и в этот момент он был украден из Vue. Vue больше не контролирует это. ответ, который дал диалог был хорошим: заверните его в <span>. Но затем вы указали на другой сценарий, для которого это не работает.

Чтобы решить ваш сценарий, когда упаковка с <span> по-прежнему не работает, используйте key = "fa-sort-up". Это заставит Vue повторно отобразить оболочку, после чего Font Awesome обновит значок. Вот обновлен jsFiddle для вашего примера:

<span key = "fa-sort-up" v-if = "sort && descending"><i class = "fas fa-sort-up"></i></span>
<span key = "fa-sort-down" v-else-if = "sort"><i class = "fas fa-sort-down"></i></span>
<span key = "fa-sort" v-else><i class = "fas fa-sort"></i></span>

В качестве ключа можно использовать все, что угодно, главное, чтобы он был уникальным.

Установите флажок в vue с помощью FontAwesome

<style>
  .fa-check-square::before {
    color: green; 
  }
</style>

<script>
  Vue.component('some',
    {
      data: 
        function() {
          return{
            isclick: false
          }
        },
      methods: {
        isClicked: function() {
          this.isclick = !this.isclick;
        }
      },
      template: '<div id = "test" v-on:click = "isClicked">' +
        '<i v-if = "isclick" class = "fa fa-check-square" style = "font-size: 40px;"></i>' +
        '<i v-if = "!isclick" class = "far fa-square" style = "font-size: 40px;"></i>' +
        '</div>'
    });

</script>

<div id = "componentsDemo">
  <some></some>
  <some></some>
  <some></some>
  <some></some>
</div>

<script>
  new Vue({ el: '#componentsDemo' });
</script>

Другие вопросы по теме