Невозможно прочитать свойство «_pending» со значением NULL при использовании v-html и <transition> - PullRequest
0 голосов
/ 17 мая 2018

Я боролся с этой ошибкой в ​​течение нескольких часов и сумел сузить ее до очень простого сценария.Мне удалось воспроизвести ошибку в JSFiddle .

Я хочу отобразить цену, основанную на данной валюте.Если валюта USD, просто отобразите цену.Если это что-то еще, отобразите конвертированную цену (в данном случае EUR) с возможностью щелкнуть по ней и увидеть первоначальную цену.

Как вы можете видеть в скрипте, если вы изменитеначальное значение USD во входных данных, скажем, US, условие больше не выполняется и отображается конвертированная цена.Если вы нажмете на цену, вы увидите исходную цену.

Однако, если вы наберете D назад, чтобы валюта снова была USD, вы получите ошибку:

vue.js:1743 TypeError: Cannot read property '_pending' of null
    at performLeave (VM208 vue.js:7827)
    at leave (VM208 vue.js:7817)
    at Array.remove$$1 (VM208 vue.js:7910)
    at removeAndInvokeRemoveHook (VM208 vue.js:5771)
    at removeAndInvokeRemoveHook (VM208 vue.js:5768)
    at removeVnodes (VM208 vue.js:5745)
    at patchVnode (VM208 vue.js:5928)
    at updateChildren (VM208 vue.js:5809)
    at patchVnode (VM208 vue.js:5923)
    at Vue.patch [as __patch__] (VM208 vue.js:6083)

После проверки исходного кода Vue выясняется, что внутренний метод performLeave() пытается получить доступ к _pending из el.parentNode.Поскольку этот метод используется для перехода, и единственным элементом перехода является <span> с key="a", я предполагаю, что el является этим элементом, а необходимый родительский узел - <span> с v-if="converted".

Вероятно, это происходит потому, что у меня есть v-html в v-else проблемного родителя.Вложенный дочерний элемент пытается перейти, но HTML родительского элемента изменяется, таким образом, дочерний элемент больше не имеет родительского элемента?

Смотрите ошибку для себя либо в скрипте, либо в этом фрагменте:

new Vue({
    el: '#app',
    data: function () {
        return {
            original: '$500',
            currency: 'USD',
            show: true
        };
    },
    computed: {
        converted: function () {
            return (this.currency !== 'USD') ? '€423' : null;
        }
    }
});
.fade-enter,
.fade-leave-to {
    opacity: 0;
}

.fade-enter-active,
.fade-leave-active {
    transition: all 0.3s ease;
}
<script src="https://vuejs.org/js/vue.min.js"></script>

<div id="app">
    <input v-model="currency">
    
    <span v-if="converted" @click="show = !show">
        <transition name="fade">
            <span v-if="show" key="a" v-html="converted"></span>
            <span v-else key="b" v-html="original"></span>
        </transition>
    </span>
    <span v-else v-html="original"></span>
</div>

Вопросы

  1. Почему возникает эта ошибка?Что происходит?
  2. Как мне это исправить?

1 Ответ

0 голосов
/ 17 мая 2018

Это ошибка с Vue. Вот билет за ошибку в репозитории Vue на GitHub .

Похоже, что конкретная комбинация наличия v-if в первом диапазоне, и прослушивателя событий @click="show = !show", и тега <transition>, и рендеринг содержимого последнего <span> с v-html вместо интерполяции строк приводит к пересечению некоторых проводов и возникновению ошибки Vue. Измените любое из этих условий, и код работает.

Один простой обходной путь - использовать v-show="converted" и v-show="!converted" для двух внешних диапазонов вместо директив v-if и v-else.

Предложенный обходной путь от команды Vue заключается в добавлении уникального атрибута key к элементам внешнего диапазона, например:

new Vue({
    el: '#app',
    data: function () {
        return {
            original: '$500',
            currency: 'USD',
            show: true
        };
    },
    computed: {
        converted: function () {
            return (this.currency !== 'USD') ? '€423' : null;
        }
    }
});
.fade-enter,
.fade-leave-to {
    opacity: 0;
}

.fade-enter-active,
.fade-leave-active {
    transition: all 0.3s ease;
}
<script src="https://vuejs.org/js/vue.min.js"></script>

<div id="app">
    <input v-model="currency">
    
    <span v-if="converted" key="a" @click="show = !show">
        <transition name="fade">
            <span v-if="show" key="a" v-html="converted"></span>
            <span v-else key="b" v-html="original"></span>
        </transition>
    </span>
    <span v-else key="b" v-html="original"></span>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...