{"id":12527,"library":"vue-menu-aim","title":"Vue Menu Aim","description":"Vue Menu Aim is a Vue.js plugin designed to implement the 'menu-aim' functionality for improving the user experience with complex nested menus. This pattern, often popularized by Amazon, intelligently detects a user's intent to move their mouse from a parent menu item to its corresponding submenu, preventing accidental deactivation or closure of the submenu when the mouse briefly passes over other menu items. It calculates a 'forgiving triangle' area, allowing users to move diagonally without triggering hover-out events on intermediate elements. The package is currently at version 1.2.0 and has not seen updates since May 2019, making it primarily compatible with Vue 2 applications. It is particularly useful for projects requiring sophisticated dropdown or fly-out menus where standard hover delays are insufficient to provide a smooth interaction. It does not follow a regular release cadence and is no longer actively maintained.","status":"abandoned","version":"1.2.0","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","menu","aim","vue"],"install":[{"cmd":"npm install vue-menu-aim","lang":"bash","label":"npm"},{"cmd":"yarn add vue-menu-aim","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-menu-aim","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Runtime peer dependency for the Vue plugin system (Vue.use). This library is built for Vue 2.","package":"vue","optional":false},{"reason":"Often used in conjunction with Vuetify's menu components, as indicated by examples. Vuetify is an optional styling framework, but its menu components benefit from this logic.","package":"vuetify","optional":true}],"imports":[{"note":"This package exports a default plugin object, not named exports. Use Vue.use(vueMenuAim) after importing.","wrong":"import { vueMenuAim } from 'vue-menu-aim';","symbol":"vueMenuAim","correct":"import vueMenuAim from 'vue-menu-aim';"},{"note":"The global `Vue` object must be available, typically from `import Vue from 'vue'` or a global script tag.","wrong":"import { Vue } from 'vue';\nVue.use(vueMenuAim);","symbol":"Vue.use(vueMenuAim)","correct":"import vueMenuAim from 'vue-menu-aim';\nVue.use(vueMenuAim);"},{"note":"For CommonJS environments, `require` is used to import the default export.","symbol":"vueMenuAim (CommonJS)","correct":"const vueMenuAim = require('vue-menu-aim');"}],"quickstart":{"code":"import Vue from 'vue';\nimport vueMenuAim from 'vue-menu-aim';\n\nVue.use(vueMenuAim);\n\nexport default {\n  data() {\n    return {\n      catalog: [\n        { id: 1, title: 'Category 1' },\n        { id: 2, title: 'Category 2' }\n      ]\n    };\n  },\n  mounted() {\n    // Example of delayed initialization or for non-SSR scenarios\n    this.$nextTick(() => {\n      this.initializeMenuAim();\n    });\n  },\n  updated() {\n    // Re-initialize if menu structure might change, e.g., in v-for loops\n    this.initializeMenuAim();\n  },\n  methods: {\n    initializeMenuAim() {\n      const menuElements = document.querySelectorAll(\".menu-aim\");\n      if (menuElements.length === 0) return;\n\n      // Assume an activator exists for context, e.g., a Vuetify v-menu activator\n      const activator = document.querySelector(\".v-menu__activator\") || { offsetHeight: 0, offsetLeft: 0 };\n\n      menuElements.forEach(menu => {\n        this.vueMenuAim(menu, {\n          rowSelector: \".menu-li\", // Selector for individual menu items\n          top: activator.offsetHeight,\n          left: activator.offsetLeft,\n          activate: row => {\n            console.log('Activating row:', row.textContent); \n            // Logic to show a submenu for the activated row\n            // e.g., add 'active' class to row, display corresponding submenu\n          },\n          deactivate: row => {\n            console.log('Deactivating row:', row.textContent);\n            // Logic to hide the submenu\n          }\n        });\n      });\n    }\n  },\n  template: `\n    <div id=\"app\">\n      <div class=\"v-menu__activator\" style=\"position: absolute; top: 10px; left: 10px; width: 50px; height: 30px; background-color: lightblue;\">Menu Trigger</div>\n      <v-list class=\"menu-aim\" style=\"position: absolute; top: 40px; left: 10px; border: 1px solid #ccc; width: 200px;\">\n        <template v-for=\"element in catalog\">\n          <div :key=\"element.title\" class=\"menu-li\" style=\"padding: 8px; border-bottom: 1px solid #eee; cursor: pointer;\">\n            <div class=\"main-group-title\">{{ element.title }}</div>\n            <div class=\"submenu-content\" style=\"position: absolute; left: 200px; top: 0; background: #f9f9f9; border: 1px solid #ddd; padding: 10px; display: none;\">Submenu for {{ element.title }}</div>\n          </div>\n        </template>\n      </v-list>\n    </div>\n  `\n};","lang":"javascript","description":"This quickstart demonstrates how to integrate `vue-menu-aim` as a Vue 2 plugin, initializing it within `mounted` and `updated` hooks. It shows how to pass configuration options like `rowSelector`, `top`, `left`, and `activate`/`deactivate` callbacks to manage submenu visibility based on the menu-aim logic."},"warnings":[{"fix":"Do not use `vue-menu-aim` in Vue 3 projects. Consider alternative libraries or implement custom menu-aim logic using Vue 3's Composition API or directives.","message":"This package is designed for Vue 2 applications and is not compatible with Vue 3. Vue 2 reached its End of Life (EOL) on December 31, 2023, meaning it no longer receives official updates or security fixes. Using `vue-menu-aim` in a Vue 3 project will result in runtime errors due to fundamental API changes.","severity":"breaking","affected_versions":">=2.0.0 (Vue 3 projects)"},{"fix":"Inspect the rendered DOM to determine the correct `top` and `left` coordinates of your main menu element, especially when it's rendered by a third-party UI library. Pass these values explicitly to the `vueMenuAim` configuration object: `{ top: activator.offsetHeight, left: activator.offsetLeft }`.","message":"When integrating with component libraries like Vuetify, especially `v-menu` or similar components, the `top` and `left` options in the `vueMenuAim` configuration may need to be explicitly set. These values define the position of the main menu, which is crucial for calculating the 'forgiving triangle' accurately. Relying solely on default `offsetTop` and `offsetLeft` might lead to incorrect mouse tracking if the menu is positioned dynamically or is inside other transformed elements.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For new projects or applications requiring ongoing maintenance and security, it is highly recommended to seek a more actively maintained solution or implement the menu-aim logic natively. For existing projects, be aware that you are solely responsible for addressing any bugs or vulnerabilities.","message":"The package has not been updated since May 2019, indicating it is abandoned. There will be no further feature development, bug fixes, or security patches. Its reliance on Vue 2 means it is built against an unsupported framework version. Consider that any issues encountered will likely require a custom fix.","severity":"deprecated","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using `vue-menu-aim` only with Vue 2 projects. If migrating to Vue 3, this library is incompatible and needs to be replaced. For Vue 2, ensure `Vue` is globally available or correctly imported if using a build system: `import Vue from 'vue'; Vue.use(vueMenuAim);`","cause":"Attempting to use `Vue.use()` with a Vue 3 application. In Vue 3, plugins are installed directly on the app instance (`app.use(plugin)`), and the global `Vue` object no longer has a `use` method.","error":"TypeError: Vue.use is not a function"},{"fix":"Carefully inspect the `offsetTop`, `offsetLeft`, `offsetWidth`, and `offsetHeight` properties of your main menu element in the DOM at runtime. Ensure these values are accurately passed to the `vueMenuAim` configuration. Adjust `submenuDirection` if your submenu opens in a direction other than the default 'right'.","cause":"The `top`, `left`, `width`, or `height` options passed to `vueMenuAim` are incorrect, causing the 'forgiving triangle' area calculation to be misaligned with the actual menu and submenu positions.","error":"Submenu closes immediately or does not appear reliably when moving mouse to it."},{"fix":"This library does not ship with TypeScript definitions. You would need to create a declaration file (e.g., `vue-menu-aim.d.ts`) to extend the `Vue` instance type:\n```typescript\ndeclare module 'vue/types/vue' {\n  interface Vue {\n    vueMenuAim: (menuElement: HTMLElement, options: any) => void;\n  }\n}\n```\nThis explicitly tells TypeScript that `this.vueMenuAim` is available.","cause":"TypeScript error indicating that the `vueMenuAim` method injected by the plugin is not recognized on the Vue instance type, likely due to missing or incorrect type declarations.","error":"Property '$vueMenuAim' does not exist on type 'Vue'."}],"ecosystem":"npm"}