Вот что я придумала.Я немного изменил миграцию:
Schema::create('menus', function (Blueprint $table) {
$table->increments('id');
$table->tinyInteger('status')->default(1);
$table->string('name');
$table->timestamps();
});
Schema::create('sub_menus', function (Blueprint $table) {
$table->increments('id');
$table->tinyInteger('status')->default(1);
$table->unsignedInteger('menu_id');
$table->string('title');
$table->timestamps();
$table->foreign('menu_id')
->references('id')
->on('menus')
->onDelete('cascade');
});
Schema::create('pages', function (Blueprint $table) {
$table->increments('id');
$table->integer('menu_id');
$table->integer('submenu_id');
$table->integer('status')->default(1);
$table->text('description');
$table->softDeletes();
$table->timestamps();
});
Затем из контроллера
$menus = Menu::where('status', 1)->orderBy('name')->get()->map(function(Menu $menu) {
return [
'name' => $menu->name,
'value' => $menu->id,
];
});
$subMenus = SubMenu::where('status', 1)->orderBy('title')->get()->map(function(SubMenu $subMenu) {
return [
'name' => $subMenu->title,
'value' => $subMenu->id,
'menu_id' => $subMenu->menu_id,
];
})->groupBy('menu_id');
return view('menu.index')
->with('menus', $menus)
->with('subMenus', $subMenus);
Вы можете видеть, что я сгруппировал подменю, используя поле menu_id
, которое будет представлятьиндекс каждой коллекции подменю - таким образом, мы можем легко заменить их в представлении.
Я добавил 2 простых VueJs
компонента
Form.vue
<script>
export default {
props: {
inputs: {
type: Object,
required: true,
}
},
data() {
return {
fields: this.inputs
}
},
}
</script>
DependableMenu.vue
<template>
<div>
<slot :options="options"></slot>
</div>
</template>
<script>
export default {
props: {
parentValue: {
type: [Number, String],
default: null,
},
records: {
type: [Object, Array],
default: () => [],
}
},
data() {
return {
options: []
}
},
mounted() {
this.filterRecords(this.parentValue);
},
methods: {
filterRecords(parent_id) {
if (!parent_id) {
this.options = [];
}
this.options = this.records[parent_id] || [];
}
},
watch: {
parentValue(parent_id) {
this.filterRecords(parent_id);
}
}
}
</script>
Зарегистрировано их в пределах resources/assets/js/app.js
Vue.component('form-wrapper', require('./components/Form'));
Vue.component('dependable-menu', require('./components/DependableMenu'));
И наконец menu/index.blade.php
просмотреть с помощью формы
<form-wrapper :inputs="{ menu_id: '', submenu_id: '' }" inline-template>
<form action="/" method="post">
{{ csrf_field() }}
<select name="menu_id" v-model="fields.menu_id">
<option value="">Select menu</option>
@foreach($menus as $menu)
<option value="{{ $menu['value'] }}">{{ $menu['name'] }}</option>
@endforeach
</select>
<dependable-menu :parent-value="fields.menu_id" :records="{{ $subMenus }}">
<div slot-scope="props">
<select name="submenu_id">
<option value="">Select sub-menu</option>
<option v-for="option in props.options" :key="option.value" :value="option.value" v-text="option.name"></option>
</select>
</div>
</dependable-menu>
<button type="submit">SUBMIT</button>
</form>
</form-wrapper>
Локально протестировано - все работает, но попробуйте попробовать и посмотрите, как оно работает.