Vue组件条件创建

t3irkdon  于 2022-12-14  发布在  Vue.js
关注(0)|答案(3)|浏览(152)

bounty将在6天后过期。回答此问题可获得+50声望奖励。Bilal希望吸引更多人关注此问题。

如果对象变量store.plan不为空,我想有条件地创建一个动作列表(每个动作都是一个组件),我已经尝试过v-if,它在渲染时效果很好,但在创建组件时效果不好。
出现错误:
Uncaught (in promise) TypeError: action is undefined
该组件的完整代码可以在here中找到。
你能告诉我如何处理这个问题吗?提前谢谢。

<template>
    <div class="planlist" v-if="parse">
        <ul id="planOl">
        <Action
        v-for="action in store.plan"
            :action_id="action.act_id"
            :actor="action.actor"
            :color="action.color"
            :size="action.size"
            :lego_name="action.lego"
            :pick_pos="action.pick"
            :place_pos="action.place"
            :blocked="action.blocked"
            :status="action.status"
            :key="action.act_id"
        />
        </ul>
    </div>
</template>

<script>
import Action from '../components/Action.vue';
import { store } from '../js/store.js'

export default {
    name: 'Plan', 
    data() {
        return {           
            store,
        }
    },
    computed: {
        parse() { 
            if (store.plan.length > 0) { 
                return true;
            }
            return false;
        }
    },
    components: {Action}
}
</script>
lc8prwob

lc8prwob1#

是否尝试使用optional chaining

parse() { 
  return store?.plan?.length > 0 ? true : false
}

不要混合使用v-if和v-for。尝试在组件周围创建带有v-if的 Package 器div:

<ul id="planOl">
  <div v-if="parse">
    <Action
    v-for="action in store.plan"
        :action_id="action.act_id"
        :actor="action.actor"
        :color="action.color"
        :size="action.size"
        :lego_name="action.lego"
        :pick_pos="action.pick"
        :place_pos="action.place"
        :blocked="action.blocked"
        :status="action.status"
        :key="action.act_id"
    />
  </div>
</ul>
qoefvg9y

qoefvg9y2#

建议不要在同一元素上同时使用v-ifv-for指令,因为这两个指令的语法不明确。
根据您的代码,Computed属性parse用于检查数组的长度。您可以将v-if移动到container元素(例如ul)。
在模板中**:**

<ul id="planOl" v-if="parse">
 <Action v-for="action in store.plan">...</Action>
</ul>

脚本**:**

computed: {
    parse() { 
        return store.plan.length > 0 ? true : false;
    }
}
ercv8c1e

ercv8c1e3#

1.为了简化这个过程,我们可以将store.plan移到一个计算属性中,以便在模板和parse属性中使用。
1.简单地从computed属性返回store.plan.length也可以完成这项工作,而不是基于条件返回true和false。
1.如果你想在Action组件的外部使用v-if,你可以使用template来实现,不需要额外的元素。
因此,以下更改有助于解决这些问题-

<template>
    <div class="planlist">
        <ul id="planOl">
            <template v-if="parse">
                <Action
                    v-for="action in plan"
                    :key="action.act_id"
                    :action_id="action.act_id"
                    :actor="action.actor"
                    :color="action.color"
                    :size="action.size"
                    :lego_name="action.lego"
                    :pick_pos="action.pick"
                    :place_pos="action.place"
                    :blocked="action.blocked"
                    :status="action.status"
                />
            </template>
        </ul>
    </div>
</template>

<script>
import Action from "../components/Action.vue";
import { store } from "../js/store.js";

export default {
    name: "Plan",

    components: {
        Action,
    },

    computed: {
        // A computed property to access the plan ()
        plan() {
            return store.plan;
        },

        parse() {
            /**
             * 1. The plan should be available (not null or empty or undefined)
             * 2. The plan should be an array so length property can be applied
             * 3. If its an array then it should have data (length in other words)
             */
            return this.plan && Array.isArray(this.plan) && this.plan.length;
        },
    },
};
</script>

相关问题