you could use EasyMenu, you basically create your menu frame using UIDropDownMenuTemplate, then create an array with your menu options and then call the EasyMenu method passing it your frame, your array, etc. It's fairly simple to work with.
https://wow.gamepedia.com/API_EasyMenu
Code:
-- EXAMPLE --
local frame = CreateFrame("Frame", "MyFrame")
local menu = CreateFrame("Frame", "MyMenuFrame", frame , "UIDropDownMenuTemplate")
menu:SetPoint("BOTTOMRIGHT")
menu:Hide()
local menu_options = {}
local function update_menu()
-- clear the menu so that it can be re-initialized
my_menu_options = {}
-- build the menu array
my_menu_options = {
{
text = "Options",
isTitle = true,
notCheckable = true,
},
{
text = "Option One",
checked = false,
func = function(self)
-- do something
end,
},
{
text = "Option Two",
checked = false,
func = function(self)
-- do something
end,
},
text = "More Options",
notCheckable = true,
hasArrow = true,
menuList =
{
{
text = "Option Three",
checked = false,
func = function(self)
-- do something
end,
},
{
text = "Option Four",
checked = true,
func = function(self)
-- do something
end,
},
},
},
}
end
-- EasyMenu(menuList, menuFrame, anchor, x, y, displayMode, autoHideDelay)
frame:SetScript("OnClick",
function(self, button)
update_menu()
EasyMenu(menu_options, menu, frame, 0, 0, "MENU", 3)
end
)
You put your options array inside a function and call that function before every call to EasyMenu which "refreshes" your options. that way, you can manipulate your options menu before it's shown, so your menu's don't have to be just static arrays, you can customize them on the fly if you need to.
Hope this helps