Skip to content

Menu 菜单

介绍

向下弹出的菜单列表

基础用法

html
<template>
  <nut-menu>
    <nut-menu-item v-model="state.value1" :options="state.options1" />
    <nut-menu-item v-model="state.value2" @change="handleChange" :options="state.options2" />
  </nut-menu>
</template>

<script>
import { reactive, ref } from 'vue';

export default {
  setup() {
    const state = reactive({
      options1: [
        { text: '全部商品', value: 0 },
        { text: '新款商品', value: 1 },
        { text: '活动商品', value: 2 }
      ],
      options2: [
        { text: '默认排序', value: 'a' },
        { text: '好评排序', value: 'b' },
        { text: '销量排序', value: 'c' },
      ],
      value1: 0,
      value2: 'a'
    });

    const handleChange = val => {
      console.log('val', val);
    }

    return {
      state,
      handleChange
    };
  }
}
</script>

滚动固定

启用 scroll-fixed 属性可以滚动一定距离后变更为 fixed 定位

1.7.13 开始,必须配合 scroll-top 属性使用,需要将 onPageScroll 的 scrollTop 传给组件 对于 1.7.12 及以下的版本,由于uniapp中组件单独声明 onPageScroll 无效,需要手动在页面中声明一次 onPageScroll 后组件内部 才能正确获取 scrollTop 的值(参考 question-136635

html
<template>
  <nut-menu :scroll-fixed="true" :scroll-top="scrollTop">
    <nut-menu-item v-model="state.value1" :options="state.options1"></nut-menu-item>

    <nut-menu-item v-model="state.value2" :options="state.options2"></nut-menu-item>
  </nut-menu>

  <!-- 可以通过CSS变量修改 fixed 状态的 top -->
  <nut-menu custom-style="--nut-menu-scroll-fixed-top: 44px"
            :scroll-fixed="true"
            :scroll-top="scrollTop">
    <!--  ...  -->
  </nut-menu>

  <!-- 也可以传数字类型的值修改固定的阈值(单位:px) -->
  <nut-menu :scroll-fixed="100" :scroll-top="scrollTop">
    <!--  ...  -->
  </nut-menu>
</template>
typescript
const scrollTop = ref(0)

onPageScroll((res) => {
  scrollTop.value = res.scrollTop
})

自定义菜单内容

使用实例上的 toggle 方法可以手动关闭弹框。

html
<template>
  <nut-menu>
    <nut-menu-item v-model="state.value1" :options="state.options1" />
    <nut-menu-item title="筛选" ref="item">
      <div :style="{display: 'flex', flex: 1, 'justify-content': 'space-between', 'align-items': 'center'}">
        <div :style="{ marginRight: '10px'}">自定义内容</div>
        <nut-button @click="onConfirm">确认</nut-button>
      </div>
    </nut-menu-item>
  </nut-menu>
</template>

<script>
import { reactive, ref } from 'vue';

export default {
  setup() {
    const state = reactive({
      options1: [
        { text: '全部商品', value: 0 },
        { text: '新款商品', value: 1 },
        { text: '活动商品', value: 2 }
      ],
      value1: 0
    });

    const item = ref('');

    const onConfirm = () => {
      item.value.toggle();
    }

    return {
      state,
      item,
      onConfirm
    };
  }
}
</script>

一行两列

html
<template>
  <nut-menu>
    <nut-menu-item v-model="state.value3" :cols="2" :options="state.options3" />
  </nut-menu>
</template>

<script>
import { reactive, ref } from 'vue';

export default {
  setup() {
    const state = reactive({
      options3: [
        { text: '全部商品', value: 0 },
        { text: '家庭清洁/纸品', value: 1 },
        { text: '个人护理', value: 2 },
        { text: '美妆护肤', value: 3 },
        { text: '食品饮料', value: 4 },
        { text: '家用电器', value: 5 },
        { text: '母婴', value: 6 },
        { text: '数码', value: 7 },
        { text: '电脑、办公', value: 8 },
        { text: '运动户外', value: 9 },
        { text: '厨具', value: 10 },
        { text: '医疗保健', value: 11 },
        { text: '酒类', value: 12 },
        { text: '生鲜', value: 13 },
        { text: '家具', value: 14 },
        { text: '传统滋补', value: 15 },
        { text: '汽车用品', value: 16 },
        { text: '家居日用', value: 17 },
      ],
      value3: 0
    });

    return {
      state
    };
  }
}
</script>

自定义选中态颜色

html
<template>
  <nut-menu active-color="green">
    <nut-menu-item v-model="state.value1" :options="state.options1" />
    <nut-menu-item v-model="state.value2" @change="handleChange" :options="state.options2" />
  </nut-menu>
</template>

<script>
import { reactive, ref } from 'vue';

export default {
  setup() {
    const state = reactive({
      options1: [
        { text: '全部商品', value: 0 },
        { text: '新款商品', value: 1 },
        { text: '活动商品', value: 2 }
      ],
      options2: [
        { text: '默认排序', value: 'a' },
        { text: '好评排序', value: 'b' },
        { text: '销量排序', value: 'c' },
      ],
      value1: 0,
      value2: 'a'
    });

    const handleChange = val => {
      console.log('val', val);
    }

    return {
      state,
      handleChange
    };
  }
}
</script>

自定义图标

html
<template>
  <nut-menu>
    <template #icon>
        <nut-icon name="triangle-down" />
    </template>
    <nut-menu-item v-model="state.value1" :options="state.options1" />
    <nut-menu-item v-model="state.value2" @change="handleChange" :options="state.options2">
      <template #icon>
        <nut-icon name="checked" />
      </template>
    </nut-menu-item>
  </nut-menu>
</template>

<script>
import { reactive, ref } from 'vue';

export default {
  setup() {
    const state = reactive({
      options1: [
        { text: '全部商品', value: 0 },
        { text: '新款商品', value: 1 },
        { text: '活动商品', value: 2 }
      ],
      options2: [
        { text: '默认排序', value: 'a' },
        { text: '好评排序', value: 'b' },
        { text: '销量排序', value: 'c' },
      ],
      value1: 0,
      value2: 'a'
    });

    const handleChange = val => {
      console.log('val', val);
    }

    return {
      state,
      handleChange
    };
  }
}
</script>

向上展开

html
<template>
  <div class="blank"></div>
  <nut-menu direction="up">
    <nut-menu-item v-model="state.value1" :options="state.options1" />
    <nut-menu-item v-model="state.value2" @change="handleChange" :options="state.options2" />
  </nut-menu>
</template>

<script>
import { reactive, ref } from 'vue';

export default {
  setup() {
    const state = reactive({
      options1: [
        { text: '全部商品', value: 0 },
        { text: '新款商品', value: 1 },
        { text: '活动商品', value: 2 }
      ],
      options2: [
        { text: '默认排序', value: 'a' },
        { text: '好评排序', value: 'b' },
        { text: '销量排序', value: 'c' },
      ],
      value1: 0,
      value2: 'a'
    });

    const handleChange = val => {
      console.log('val', val);
    }

    return {
      state,
      handleChange
    };
  }
}
</script>
<style>
.blank {
  width: 200px;
  height: 200px;
}
</style>

禁用菜单

html
<template>
  <nut-menu>
    <nut-menu-item disabled v-model="state.value1" :options="state.options1" />
    <nut-menu-item disabled v-model="state.value2" :options="state.options2" />
  </nut-menu>
</template>

<script>
import { reactive } from 'vue';

export default {
  setup() {
    const state = reactive({
      options1: [
        { text: '全部商品', value: 0 },
        { text: '新款商品', value: 1 },
        { text: '活动商品', value: 2 }
      ],
      options2: [
        { text: '默认排序', value: 'a' },
        { text: '好评排序', value: 'b' },
        { text: '销量排序', value: 'c' },
      ],
      options3: [
        { text: '全部商品', value: 0 },
        { text: '家庭清洁/纸品', value: 1 },
        { text: '个人护理', value: 2 },
        { text: '美妆护肤', value: 3 },
        { text: '食品饮料', value: 4 },
        { text: '家用电器', value: 5 },
        { text: '母婴', value: 6 },
        { text: '数码', value: 7 },
        { text: '电脑、办公', value: 8 },
        { text: '运动户外', value: 9 },
        { text: '厨具', value: 10 },
        { text: '医疗保健', value: 11 },
        { text: '酒类', value: 12 },
        { text: '生鲜', value: 13 },
        { text: '家具', value: 14 },
        { text: '传统滋补', value: 15 },
        { text: '汽车用品', value: 16 },
        { text: '家居日用', value: 17 },
      ],
      value1: 0,
      value2: 'a',
      value3: 0
    });

    return {
      state
    };
  }
}
</script>

API

参数说明类型默认值
active-color选项的选中态图标颜色string#F2270C
close-on-click-overlay是否在点击遮罩层后关闭菜单booleantrue
scroll-fixed滚动后是否固定,可设置固定位置(参考 滚动固定 部分的说明)boolean | string | numberfalse
scroll-top 1.7.13页面的滚动距离,通过 onPageScroll 获取number0
title-class自定义标题样式类string-
lock-scroll H5背景是否锁定booleantrue
title-icon自定义标题图标string-
direction展开方向,可选值为up downstring-
up-icon收起的图标stringrect-up
down-icon展开的图标stringrect-down
名称说明
icon自定义标题图标 (不支持小程序,小程序建议使用 props 传递图标名称)
参数说明类型默认值
title菜单项标题string当前选中项文字
options选项数组Array-
disabled是否禁用菜单booleanfalse
cols可以设置一行展示多少列 optionsnumber1
direction菜单展开方向,可选值为 upstringdown
active-title-class选项选中时自定义标题样式类string-
inactive-title-class选项非选中时自定义标题样式类string-
名称说明
icon自定义选项图标 (不支持小程序)
事件名说明回调参数
change选择选项时触发value: number | string
open打开菜单栏时触发-
close关闭菜单栏时触发-
item-click 1.7.11点击选项时触发item: MenuItemOption

通过 ref 可以获取到 MenuItem 实例并调用实例方法

方法名说明参数返回值
toggle切换菜单展示状态,传 true 为显示,false 为隐藏,不传参为取反show?: boolean-
change 1.7.11变更选择项value: number | string-

主题定制

样式变量

组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件

名称默认值
--nut-menu-bar-line-height48px
--nut-menu-item-font-sizevar(--nut-font-size-2)
--nut-menu-item-text-colorvar(--nut-title-color)
--nut-menu-item-active-text-colorvar(--nut-primary-color)
--nut-menu-bar-border-bottom-color#eaf0fb
--nut-menu-bar-opened-z-index2001
--nut-menu-item-disabled-color#969799
--nut-menu-title-text-padding-left8px
--nut-menu-title-text-padding-right8px
--nut-menu-item-content-padding12px 24px
--nut-menu-item-content-max-height214px
--nut-menu-item-option-padding-top12px
--nut-menu-item-option-padding-bottom12px
--nut-menu-item-option-i-margin-right6px
--nut-menu-bar-box-shadow0 2px 12px rgba(89, 89, 89, 0.12)
--nut-menu-scroll-fixed-top0
--nut-menu-scroll-fixed-z-index1000
--nut-menu-active-item-font-weight500

MIT Licensed