Vue - лучшая практика для циклов и обработчиков событий - PullRequest
0 голосов
/ 15 апреля 2020

Мне любопытно, лучше ли в циклы включать methods вместо использования v-if. Предположим, работают следующие коды (они неполные и не работают)

EX: метод

<template >
    <div>
        <div v-for="(d, i) in data" v-bind:key="i">
            <span v-on:click="insertPrompt($event)">
                {{ d }}
            </span>
        </div>
    </div>
</template>

<script>

export default {
    data() {
        data:[
            .....
        ]
    },
    methods:{
        insertPrompt(e){
            body.insertBefore(PROMPT)
        }
    }
}
</script>

DOM будет обновляться с помощью функции insertPrompt(), которая только для отображения

EX: V-IF

// Parent

<template >
    <div>
        <div v-for="(d, i) in data" v-bind:key="i">
            <child v-bind:data="d"/>

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

<script>
import child from './child'

export default {
    components:{
        child
    },
    data() {
        data:[
            .....
        ]
    },
}
</script>

// Child

<template>
    <div>
        <span v-on:click="display != display">
            {{ d }}
        </span>
        <PROMPT v-if="display"/>
    </div>
</template>

<script>
import child from './child'

export default {
    components:{
        child
    },
    data(){
        return {
            display:false
        }
    },
    props: {
        data:{
            .....
        }
    },
}
</script>

PROMPT - это базовый шаблон c, который отображается с данными из клика данных l oop.

Оба метода могут дать sh один и тот же конечный результат. Моя первоначальная мысль о том, что наличие дополнительных условий в пределах al oop может негативно повлиять на производительность?!?!

Любое руководство будет высоко оценено

Ответы [ 3 ]

3 голосов
/ 26 апреля 2020

Если вы не отображаете действительно огромное количество элементов в ваших циклах (и в большинстве случаев вы этого не делаете), вам вообще не нужно беспокоиться о производительности. Любые различия будут настолько малы, что никто не заметит / не получит выгоды от того, что он будет слегка крошечным.

Второй момент, который я хочу отметить, заключается в том, что выполнение ваших собственных манипуляций с DOM часто не лучшая идея: Почему современные JavaScript фреймворки препятствуют прямому взаимодействию с DOM

Так что я бы в любом случае остановился на v-if для условного рендеринга вещей. Если вы хотите позаботиться о производительности / скорости, вы можете подумать, как именно будет использоваться ваше приложение, и выбрать между v-if и v-show. Ссылаясь на официальную документацию:

v-if - это «реальный» условный рендеринг, поскольку он гарантирует, что прослушиватели событий и дочерние компоненты внутри условного блока должным образом уничтожаются и воссоздаются при переключениях.

v-if также ленив: если условие ложно при начальном рендеринге, оно ничего не будет делать - условный блок не будет отображаться, пока условие не станет истинным в первый раз.

По сравнению , v-show намного проще - элемент всегда отображается независимо от начального условия, с переключением на CSS.

Вообще говоря, v-if имеет более высокие затраты на переключение, в то время как v-show имеет более высокий начальный рендер расходы. Поэтому предпочитайте v-show, если вам нужно что-то переключать очень часто, и предпочитайте v-if, если условие вряд ли изменится во время выполнения.

https://vuejs.org/v2/guide/conditional.html#v -if-vs-v -show

0 голосов
/ 26 апреля 2020

Существует множество решений для решения этой проблемы, но давайте придерживаться 3. Варианты 2 и 3 - лучшие практики, но вариант 1 работает, и Vue был разработан для этого подхода, даже если хардкорные разработчики нахмурились, но придерживайтесь комфорта level.

Вариант 1: манипуляция DOM

Ваши данные из клика, asyn c, prop устанавливает условие для v-if или v-show и ваш Компонент показан. Примечание v-if удаляет элемент DOM, где v-show скрывает видимость, но элемент все еще находится в потоке. Если вы удалите элемент и добавите его полностью новый init, который иногда работает в вашу пользу, когда дело доходит до реактивности, но на практике старайтесь не манипулировать DOM, поскольку это всегда будет дороже, чем циклы, фильтры, карты и др. c.


<template >
    <div>
        <div v-for="(d, i) in getData" 
             :key="i">
            <div v-if="d.active">
                <child-one></child-one>
            </div>
            <div v-else-if="d.active">
                <child-two></child-two>
            </div>
        </div>
    </div>
</template>


<script>
    import ChildOne from "./ChildOne";
    import ChildTwo from "./ChildTwo";

    export default {
        components: {
            ChildOne,
            ChildTwo
        },
        data() {
            return {
                data: [],
            }
        },
        computed: {
            getData() {
                return this.data;
            },
        },
        mounted() {
            // assume thsi woudl come from async but for now ..
            this.data = [
                {
                    id: 1,
                    comp: 'ChildOne',
                    active: false
                },
                {
                    id: 2,
                    comp: 'ChildTwo',
                    active: true
                },
            ];
        }
    }
</script>


Опция 2: Vue * <component> компонент

Всегда лучше использовать Vue встроенный компонент компонента Vue со специальным атрибутом is: <component v-bind:is="currentTabComponent"></component>

В этом примере мы передаем слаг или какой-либо атрибут данных для активации компонента. Обратите внимание, что мы должны загружать компоненты заранее с помощью свойства components: {},, чтобы это работало, т. Е. Оно должно быть ChildOne или ChildTwo в качестве строки slug. Это часто используется с вкладками и представлениями для управления и поддержки состояний.

Преимущество этого подхода состоит в том, что если у вас есть 3 вкладки формы, и вы вводите данные на одной и переходите к следующей, а затем обратно, состояние / данные сохраняются, в отличие от v, если все будет перерисовано / потеряно .

Vue

<template >
    <div>
        <component :is="comp"/>
    </div>
</template>

<script>
    import ChildOne from "./ChildOne";
    import ChildTwo from "./ChildTwo";

    export default {
        components: {
            ChildOne,
            ChildTwo
        },
        props: ['slug'],
        data() {
            return {
                comp: 'ChildOne',
            }
        },
        methods: {
            setComponent () {
                // assume prop slug passed from component or router is one of the components e.g. 'ChildOne'
                this.comp = this.slug;
            }
        },
        mounted() {
            this.nextTick(this.setModule())
        }
    }
</script>

Опция 3: Vue и компоненты Webpack Asyn c и Dynami c.

Когда речь идет о более крупных приложениях или если вы используете Vuex и Vue Route, где у вас есть Dynami c и большое количество компонентов, тогда есть ряд подходов, но я остановлюсь на одном. Подобно варианту 2, мы используем элемент компонента, но мы используем WebPack для рекурсивного поиска всех Vue файлов с ключевым словом «модуль». Затем мы загружаем их динамически / асинхронно - это означает, что они будут загружаться только при необходимости, и вы можете увидеть это в действии в сетевой консоли браузера. Это означает, что я могу динамически создавать компоненты (фабричный шаблон) и отображать их по мере необходимости. Например, это может быть, если пользователь добавляет проекты, и вам необходимо динамически создавать и настраивать представления для проектов, созданных, например, используя маршрутизатор vue, которому вы передали ему идентификатор для нового проекта, тогда вам потребуется динамически загрузить существующий компонент или построить и загрузить заводской.

Примечание: я буду использовать v-if на элементе компонента, если у меня много компонентов, и я не уверен, что они понадобятся пользователю. Я не хочу поддерживать состояние больших коллекций компонентов, потому что у меня останется память, а при большом количестве наблюдателей / наблюдений / анимаций, скорее всего, возникнут проблемы с процессором


<template >
    <div>
        <component :is="module" v-if="module"/>
    </div>
</template>

<script>
    const requireContext = require.context('./', true, /\.module\.vue$/);
    const modules = requireContext.keys()
        .map(file =>
            [file.replace(/(.*\/(.+?)\/)|(\.module.vue$)/g, ''), requireContext(file)]
        )
        .reduce((components, [name, component]) => {
            // console.error("components", components)
            components[name] = component.default || component
            return components
        }, {});

    export default {
        data() {
            return {
                module: [],
            }
        },
        props: {
            slug: {
                type: String,
                required: true
            }
        },
        computed: {
            getData() {
                return this.data;
            },
        },
        methods: {
            setModule () {
                let module = this.slug;

                if (!module || !modules[module]) {
                    module = this.defaultLayout
                }

                this.module = modules[module]
            }
        },
        mounted() {
            this.nextTick(this.setModule())
        }
    }
</script>


0 голосов
/ 24 апреля 2020

Моя первоначальная мысль о том, что наличие дополнительных условий в пределах al oop может негативно повлиять на производительность?

Думаю, вас может смутить это правило в стиле руководство, которое гласит:

Никогда не используйте v-if на том же элементе, что и v-for.

Это проблема стиля, только если вы используете v-if и v-for на том же элементе. Например:

<div v-for="user in users" v-if="user.isActive">

Но это не проблема, если вы используете v-if в дочернем элементе v-for. Например:

<div v-for="user in users">
    <div v-if="user.isActive">

Использование v-if не окажет более негативного влияния на производительность, чем метод. И я предполагаю, что вы должны были бы также сделать некоторые условные проверки внутри вашего метода. Помните, что даже вызов метода имеет некоторое (очень небольшое) влияние на производительность.

Как только вы используете Vue, я думаю, что будет хорошей идеей не смешивать его с JavaScript методами DOM (такими как insertBefore). ). Vue поддерживает виртуальный DOM, который помогает выяснить, как лучше всего обновлять DOM при изменении данных вашего компонента. Используя JavaScript методы DOM, вы больше не будете использовать преимущества виртуального DOM Vue.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...