javascript Vue3中使用 prop 的条件模板渲染?

kmbjn2e3  于 2023-01-24  发布在  Java
关注(0)|答案(2)|浏览(204)

我正在尝试做一个切换按钮,这样一个汉堡包菜单打开时,点击。
我在“App.vue”中创建了布尔型的“clicked”属性,并将其传递给“Navbar.vue”,现在我希望能够在导航栏中单击以将“clicked”属性切换为“true”或“false”,从而使背景和抽屉显示或不显示。
我尝试使用“emit”,它似乎工作,但模板不响应“clicked”变量,即使它是假的也显示。
在下面的代码中,我哪里做错了?你如何用 prop 实现条件渲染?有人能帮忙吗?

应用程序版本

<template>
  <NavBar :clicked="clicked" @toggleDrawer="toggleMenu()" />
  <BackDrop :clicked="clicked" />
  <SideDrawer :clicked="clicked" />
  <router-view></router-view>
</template>

<script>
export default {
  name: "App",
  components: { NavBar, BackDrop, SideDrawer },

  setup() {
    const clicked = ref(false);

    const toggleMenu = () => {
      clicked.value = !clicked.value;
    };
    return { clicked, toggleMenu };
  },
};
</script>

导航栏值

<template>
  <nav class="navbar">
  /* MORE CODE */
    <div class="hamburger_menu" @click="toggleEvent">
      <div></div>
      <div></div>
      <div></div>
    </div>
  </nav>
</template>

<script setup>
import { defineEmits, defineProps } from "vue";

const props = defineProps({
  clicked: Boolean,
});

const emit = defineEmits(["toggleDrawer"]);

const toggleEvent = () => {
  console.log("toggleEvent running");
  emit("toggleDrawer", !props.clicked);
};
</script>

背景视图

<template v-if="props.clicked">
  <div class="backdrop"></div>
</template>

<script setup>
import { defineProps } from "vue";
// eslint-disable-next-line no-unused-vars
const props = defineProps({
  clicked: Boolean,
});
</script>

侧抽屉视图

<template v-if="props.clicked">
  <div class="sidedrawer"></div>
</template>
<script setup>
import { defineProps } from "vue";
const props = defineProps({
  clicked: Boolean,
});
</script>

我传入的prop是否有误?props.clicked在v-if或模板中是否不起作用?我应该如何用我的clicked属性实现v-if?

ttp71kqs

ttp71kqs1#

正如@neha-soni所说,

运行代码后,运行正常

Vue建议在模板中使用kebab大小写的事件侦听器。当您在父组件中使用toggleDrawer时,它会自动转换为kebab大小写。因此,在app.vue中,您可以像使用@toggle-drawer一样使用它。

<NavBar :clicked="clicked" @toggle-drawer="toggleMenu()" />

来自vue文档链接
事件名称提供了一个自动的大小写转换。注意,我们发出了一个camelCase事件,但是可以在父节点中使用一个kebab大小写的监听器来监听它。与props大小写一样,我们建议在模板中使用kebab大小写的事件监听器。

nwlls2ji

nwlls2ji2#

运行代码后,它工作正常。我有一些反馈来删除不必要的代码,这是造成混乱,然后你可以看到它的工作。
1.因为props在子组件中是不可变的(只读),这意味着它们的值不会改变,所以没有必要将props值传递回(通过执行emit("toggleDrawer", !props.clicked))父组件,因为父组件已经具有它们的原始状态。
1.另一点是,您通过执行emit("toggleDrawer", !props.clicked)从事件传递数据( prop 数据),但在App.vue中调用函数@toggleDrawer="toggleMenu()"时没有使用它,因此最好删除此数据传递代码。

  1. clicked属性正在父模板(App.vue)和子组件内部更新。只需控制台并打印子模板和父模板中的clicked属性(如顶部的{{ clicked }}),您就可以看到更新状态-
const toggleMenu = () => {
  console.log('Before______', clicked.value)
  clicked.value = !clicked.value;
  console.log('After______', clicked.value)
};

相关问题