【问题标题】:Vue.js - Dynamic buttons with dynamic v-ifVue.js - 带有动态 v-if 的动态按钮
【发布时间】:2020-10-03 14:11:22
【问题描述】:

我正在动态生成一些菜单按钮(不确定这是否是最佳做法)

脚本

items: [
{ title: 'Dashboard', icon: 'mdi-view-dashboard', route: '/' },
{ title: 'Register', icon: 'mdi-image', route: '/register' },
{ title: 'Login', icon: 'mdi-help-box', route: '/login' },
],

html

<v-list-item v-for="(item, i) in items" :key="i" link :to="{path: item.route}">

但我想要做的是隐藏仪表板按钮,直到他们登录。用户登录的值被保存在存储中。

$store.state.user.signedIn // true/false

如何根据登录值以编程方式隐藏按钮?我正在尝试这样做

{ title: 'Dashboard', icon: 'mdi-view-dashboard', route: '/', reqAuth: true }

但不知道如何让它在 html 中顺利运行。我还想稍后在登录/注册按钮上做相反的事情,如果用户已登录,那么这些应该隐藏并且注销按钮将发挥作用。

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component vuetify.js


    【解决方案1】:

    你有两个选择:

    • A) 具有单独的菜单数组,并根据isLoggedIn 显示一个或另一个。如果您在这两种情况下都显示了任何项目,则需要将它们放在第三个数组中,并将前两个数组中的一个与第三个数组连接
    • B) 在每个菜单项上都有一个布尔属性,说明它是否应该在isLoggedIn 时显示。如果两个菜单项都显示,则每个项目都需要两个道具(showWhenLoggedInshowWhenLoggedOut - 如果太长,请更改它们),或者,您可以将 show 设为布尔数组: show: [true, false] - 第一个布尔值控制是否在注销时显示,第二个在登录时显示。

    解决方案A)示例(单独的数组):

    Vue.config.devtools = false;
    Vue.config.productionTip = false;
    new Vue({
      el: '#app',
      data: () => ({
        loggedInMenuItems: [
          { title: 'Dashboard', icon: 'mdi-view-dashboard', route: '/', show: [false, true] },
        ],
        loggedOutMenuItems: [
          { title: 'Register', icon: 'mdi-image', route: '/register', show: [true, false] },
          { title: 'Login', icon: 'mdi-help-box', route: '/login', show: [true, false] },
        ],
        permanentMenuItems: [
          { title: 'Terms and Conditions', icon: 'mdi-whatever', route: '/terms', show: [true, true] }
        ],
        isLoggedIn: false
      }),
      computed: {
        menuItems() {
          return (this.isLoggedIn
            ? this.loggedInMenuItems
            : this.loggedOutMenuItems
          ).concat(this.permanentMenuItems)
        }
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <label><input v-model="isLoggedIn" type="checkbox"> Is logged in</label>
      <pre v-html="menuItems.map(m => m.title)"></pre>
    </div>

    解决方案B)示例:

    Vue.config.devtools = false;
    Vue.config.productionTip = false;
    new Vue({
      el: '#app',
      data: () => ({
        items: [
          { title: 'Dashboard', icon: 'mdi-view-dashboard', route: '/', show: [false, true] },
          { title: 'Register', icon: 'mdi-image', route: '/register', show: [true, false] },
          { title: 'Login', icon: 'mdi-help-box', route: '/login', show: [true, false] },
          { title: 'Terms and Conditions', icon: 'mdi-whatever', route: '/terms', show: [true, true] }
        ],
        isLoggedIn: false
      }),
      computed: {
        menuItems() {
          return this.items.filter(item => item.show[Number(!!this.isLoggedIn)])
        }
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <label><input v-model="isLoggedIn" type="checkbox"> Is logged in</label>
      <pre v-html="menuItems.map(m => m.title)"></pre>
    </div>

    为了简洁起见,我个人更喜欢第二个。我也觉得它更优雅一点。

    但是,在大型团队或需要将代码复杂性保持在最低水平并最大限度提高代码可读性的项目中,通常首选第一个解决方案。

    最后,第二种解决方案为菜单项的顺序提供了更大的灵活性,尽管这不是一个真正的问题(为每个项实现 order 属性将是微不足道的)。


    注意: 显然,isLoggedIn 应该来自状态,而不是来自组件数据 fn。我把它放在data,所以你可以在这里轻松地测试它。

    【讨论】:

      【解决方案2】:

      您的items 属性应定义为计算属性,并在每个项目项中添加shown 字段,并在仪表板链接中使用状态值作为其值:

      computed :{
       items(){
      const signedIn=$store.state.user.signedIn; 
        return  [
            { title: 'Dashboard', icon: 'mdi-view-dashboard', route: '/', shown:signedIn },
            { title: 'Register', icon: 'mdi-image', route: '/register',shown:!signedIn},
            { title: 'Login', icon: 'mdi-help-box', route: '/login' , shown:!signedIn},
      ]
        }
      }
      

      在模板中添加

      <v-list-item v-for="(item, i) in items" :key="i" link v-if="item.shown" :to="{path: item.route}">
      

      【讨论】:

        猜你喜欢
        • 2020-02-23
        • 1970-01-01
        • 2018-11-03
        • 1970-01-01
        • 1970-01-01
        • 2019-04-05
        • 2017-10-12
        • 2020-08-18
        • 1970-01-01
        相关资源
        最近更新 更多