在很多前端开发的项目中,都会遇到需要选择多级联动数据的情况。例如,选择省市区、选择品牌系列型号等。Vue.js 是一款流行的前端框架,其强大的数据绑定和响应式能力使得实现无限级联选择器变得非常容易。
接下来,本文将介绍如何通过 Vue.js 实现无限级联选择器。我们将从原理分析、编写代码、优化性能等方面一步步引导读者完成这项任务。
原理分析
首先我们需要明确,无限级联选择器的核心就是数据。而多级的数据并不是规定的,往往不同的需求数据结构也不一样。例如,我们需要实现选择地址的功能,那么数据结构就应该像这样:
-- -------------------- ---- ------- - - ------ ------ ------ --------- --------- - - ------ ------ ------ --------- --------- - - ------ ------ ------ -------- -- -- --- - -- -- --- - -- -- --- -
每一级数据都有自己的 label
和 value
属性,这用于显示和选中某个选项。而 children
属性则表示该级别下面的子级数据,用于级联显示。
接下来,我们将分析实现无限级联选择器的核心原理:
- 定义一个组件用来显示级别的选项
- 使用组件递归渲染每一级别的选项
第一步中,我们需要定义一个 CascadeItem
组件,该组件需要根据传入的数据渲染自己的选项并且能够激活下一级选择器。我们可以用以下代码作为 CascadeItem
的基础:
-- -------------------- ---- ------- ---------- ----- ---- ---------------- ------ --- ----- ---------------- ---------- ----------------------- ----- --------- ---- --------- --- ------------ ------------ -- --------- ------------------ ------------- ------------- - -- -------------------- ----------------- -- ------ ----------- -------- ------ ------- - ----- -------------- ------ - ----- - ----- ------- --------- ---- -- ------ - ----- ------- --------- ---- -- --------- - ----- ------- --------- ---- - -- --------- - ------- - ------ ---------------- -- ------- - ------ ---------------- -- ---------- - ------ ------------------ -- --- -- ---------- - ------ ------------------------------------ --- ----------- - -- -------- - ------------- - -- --------- ---------- - ------------------------ ---------------------- ------------ -- ----------------------- ------------------------ ------------------- - ---- ----------- - - - --------- ------ ------- ------- - ------ ---- - --------
其中,我们在 isActive
方法中判断当前级别的值是否等于 selected
中的选中值,并在 handleClick
方法中更新 selected
,并清空下级的值,达到级联选择的效果。
接下来我们需要将递归逻辑写成 Cascade
组件。只需要给其一个数组作为初始数据,并且将初始的 selected
置空即可。
-- -------------------- ---- ------- ---------- ----- ------------ ----------- -- ----- ----------------- ------------ ---------- -------------------- -- ------ ----------- -------- ------ ----------- ---- -------------------- ------ ------- - ----- ---------- ----------- - ----------- -- ------ - ----- - ----- ------ --------- ---- - -- ------ - ------ - --------- -- - - - ---------
最后,我们只需要在使用 Cascade
时传入相应的数据结构即可实现无限级联选择器。
-- -------------------- ---- ------- ---------- ----- -------- --------------- -- ------ ----------- -------- ------ ------- ---- ---------------- ------ ------- - ----- ------ ----------- - ------- -- ------ - ------ - -------- - -- --- - - - - ---------
示例代码
为了更好地理解上面的原理分析,这里提供了一个完整的示例代码:
CascadeItem.vue
-- -------------------- ---- ------- ---------- ----- ---- ---------------- ------ --- ----- ---------------- ---------- ----------------------- ----- --------- ---- --------- --- ------------ ------------ -- --------- ------------------ ------------- ------------- - -- -------------------- ----------------- -- ------ ----------- -------- ------ ------- - ----- -------------- ------ - ----- - ----- ------- --------- ---- -- ------ - ----- ------- --------- ---- -- --------- - ----- ------- --------- ---- - -- --------- - ------- - ------ ---------------- -- ------- - ------ ---------------- -- ---------- - ------ ------------------ -- --- -- ---------- - ------ ------------------------------------ --- ----------- - -- -------- - ------------- - -- --------- ---------- - ------------------------ ---------------------- ------------ -- ----------------------- ------------------------ ------------------- - ---- ----------- - - - --------- ------ ------- ------- - ------ ---- - --------
Cascade.vue
-- -------------------- ---- ------- ---------- ----- ------------ ----------- -- ----- ----------------- ------------ ---------- -------------------- -- ------ ----------- -------- ------ ----------- ---- -------------------- ------ ------- - ----- ---------- ----------- - ----------- -- ------ - ----- - ----- ------ --------- ---- - -- ------ - ------ - --------- -- - - - ---------
App.vue
-- -------------------- ---- ------- ---------- ----- -------- --------------- -- ------ ----------- -------- ------ ------- ---- ---------------- ------ ------- - ----- ------ ----------- - ------- -- ------ - ------ - -------- - - ------ ------ ------ --------- --------- - - ------ ------ ------ --------- --------- - - ------ ------ ------ -------- -- - ------ ------ ------ -------- -- - ------ ------ ------ -------- -- - ------ ------ ------ -------- -- - ------ ------ ------ -------- -- - ------ ------ ------ -------- - - -- - ------ ------ ------ --------- --------- - - ------ ------ ------ -------- -- - ------ ------ ------ -------- -- - ------ ------ ------ -------- -- - ------ ------ ------ -------- -- - ------ ------ ------ -------- -- - ------ ------ ------ -------- - - - - - - - - - ---------
优化性能
在层级比较深的时候,我们的递归渲染容易出现组件重复渲染、频繁切换等问题。为了优化性能,我们可以使用 keep-alive
来对组件进行缓存。
为此,我们需要对 Cascade
中传入的 selected
进行一个小小的处理:
-- -------------------- ---- ------- ---------- ----- ------------ ----------- -- ----- ----------------- ------------ ---------- ---------------------------- -- ------ ----------- -------- ------ ----------- ---- -------------------- ------ ------- - ----- ---------- ----------- - ----------- -- ------ - ----- - ----- ------ --------- ---- - -- ------ - ------ - ------------ -- - -- -------- - ---------------- - ------ ---------------------------------------- - -- -- --- - -- ------ - --------- - -------- ------------- - --------------------------- -- ---------- ---- - - - ---------
将 selected
维护为一个数组,则每一项对应一个层级的选项值。每次添加新的选项值时,我们会更新数组,同时 getSelectedObj()
会返回数组中的最后一项,即当前选中层级对应的对象。
最后,我们只需在 Cascade
中加上一个 keep-alive
组件即可对 CascadeItem
进行缓存:
-- -------------------- ---- ------- ---------- ----- ------------ ------------ ----------- -- ----- ----------------- ------------ ---------- ---------------------------- -- ------------- ------ -----------
这样做既可以提高性能,又能保证递归渲染结构的正确性。
总结
Vue.js 的数据绑定和响应式机制使得实现无限级联选择器变得非常容易。通过一个递归的选择项组件,加上 selected
级联维护选项值即可实现组件间的无缝链接。在性能优化中,我们可以使用 keep-alive
来进行缓存,防止重复渲染和切换。并且,多层级的数据结构也不会成为阻挡我们写出这种组件的障碍,而是被我们巧妙地处理掉了。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651e9fb395b1f8cacd64d432