我有一个名为商品的表名
id parent_id title
1 0 Profile
2 1 About Us
3 1 Why Us?
4 0 Kbow Us
现在我想在vue laravel上创建下拉菜单,以使其在父类别下以适当的缩进或-标记深度递归地显示子类别。例如:
<select>
<option value="1">Profile</option>
<option value="2">-About Us</option>
<option value="3">--Why Us</option>
<option value="4">Kbow Us</option>
</select>
我想为vue js中子类别的任何深度递归生成动态结构,就像上面一样。
答案 0 :(得分:0)
我将使用过滤器和递归函数将每个选项返回,直到未找到任何父项,从而跟踪深度并使用该深度附加缩进标记。
由于您可能会将文章传递到视图文件(在PHP数组或集合中),因此可以将数据传递到vue组件,例如:
<my-nested-select :articles='{!! json_encode($articles) !!}'></my-nested-select>
以下是使用生成的数据的示例,过滤器是重要的部分:
new Vue({
el: '#app',
data: () => ({
items: [],
selected: null
}),
created () {
// 1. Create some dummy data where each option has an increasing chance of being nested.
const tmp = []
for (let i = 1; i <= 50; i++) {
let isChild = !!tmp.length ? Math.random() < ((i / 50) * tmp.length || 1) : null
let parent_id = isChild ? Math.ceil(Math.random() * tmp.length - 1) : null
tmp.push({
id: i,
parent_id,
text: `Option ${i}`
})
}
// 2. Sort the generated data so child options are in order following their parent option.
this.items = tmp.reduce((items, item) => {
if (!items.length || !item.parent_id) {
items.unshift(item)
} else {
const index = items.findIndex(({ id }) => id === item.parent_id)
if (index) {
items.splice(index, 0, item)
}
}
return items
}, []).reverse()
},
filters: {
depth (option, items) {
let depth = 0
// 3. The magic happens here with a recursive function to find the depth to which each option is nested.
const pad = ({ parent_id }) => {
if (!!parent_id) {
depth += 1
let parent = items.find(({ id }) => id === parent_id)
if (!parent) {
return depth
}
return pad(parent)
}
return depth
}
// 4. Call the recursive function above, create an array of hyphens and concat them together with the option's text.
return Array(pad(option)).fill('-').concat([' ', option.text]).join('')
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select v-model="selected">
<option v-for="option in items" :value="option.id" :key="option.id">{{ option | depth(items) }}</option>
</select>
<h4>Data</h4>
<ul>
<li v-for="item in items" :key="item.id"><pre><code>{{ item }}</code></pre></li>
</ul>
</div>