繁体   English   中英

在 Vue3 中使用道具进行条件模板渲染?

[英]Conditional template rendering with props in Vue3?

我正在尝试制作一个切换按钮,以便在单击时打开汉堡包菜单。

我在“App.vue”中制作了 boolean“clicked”属性,将其传递给“Navbar.vue”,现在我希望能够在导航栏中单击以将“clicked”属性切换为“true”或“ false”使背景和抽屉显示或不显示。

我尝试使用“emit”,它似乎可以工作,但模板没有响应“clicked”变量并且显示,即使它是错误的。

在下面的代码中,我哪里出错了? 你如何使用道具实现条件渲染? 有人可以帮忙吗?


App.vue

<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>

导航栏.vue

<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>

背景.vue

<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>

侧边抽屉.vue

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

我传错道具了吗? “props.clicked”在“v-if”或模板中不起作用吗? 我应该如何使用我拥有的“clicked”属性实现“v-if”?

正如@neha-soni 所说,

运行代码后,它工作正常

Vue 推荐在模板中使用 kebab-cased 事件监听器。 当您在父组件中使用它时,您的toggleDrawer将自动转换为 kebab case。 所以在 app.vue 中你可以像@toggle-drawer一样使用它,

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

来自 vue 文档链接

事件名称提供自动大小写转换。 请注意,我们发出了一个 camelCase 事件,但可以在父级中使用 kebab-cased 侦听器来侦听它。 与 props 外壳一样,我们建议在模板中使用 kebab-cased 事件监听器。

运行代码后,它工作正常。 我有一些反馈可以删除不必要的代码,这些代码会造成混乱,然后您就可以看到它的工作原理。

  1. 因为 props 在子组件中是不可变的(只读的),这意味着它们的值不会改变,所以没有必要将 props 值传回(通过执行emit("toggleDrawer", .props.clicked) )给父组件因为父母已经有了他们的原始身份。
  2. 另一点是,您通过执行emit("toggleDrawer", .props.clicked) ) 从事件传递数据(道具数据),但在 App.vue 中调用 function @toggleDrawer="toggleMenu()" App.vue不使用它,所以最好删除此数据传递代码。
  3. clicked属性在父组件 ( App.vue ) 以及子组件中更新。 只需控制并打印子模板和父模板中的clicked属性,例如顶部的{{ clicked }} ,您就可以看到更新后的状态 -
const toggleMenu = () => {
  console.log('Before______', clicked.value)
  clicked.value = !clicked.value;
  console.log('After______', clicked.value)
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM