前言:本文主要用于我的个人学习与记录,内容如有谬误欢迎各位大佬斧正。同时,如果您想要快速获取问题的解决方案,请移步至文章底部“解决方案”栏,希望我的经验能对大家有所帮助。


问题描述

由于目前我手上的项目是一个运维管理系统,所以需要实现一些基础的增删改查功能,因为想起来比较简单,我最开始也没把这当回事。说回正题,我在前端界面选用了三个互相关联下拉框,目的是实现有限制的分类搜索,效果如下:

按理想情况,用户分类选择需要搜索的内容后,下拉框内的内容会通过v-model双向绑定到vue代码里,进而进行表格的重载:

<script>
    new Vue({
        el: '#app',
        data() {
            return {
                type: '',
                distract: '',
                name: ''
            }
        },
        methods: {
            search() {
                table.reload('table_housing', {
                    url: 'http://localhost:9090/housing/search',
                    method: 'POST',
                    where: { //设定异步数据接口的额外参数,任意设
                        type: this.type
                        ,distract: this.distract
                        ,name: this.name
                    }
                    ,page: {
                        curr: 1 //重新从第 1 页开始
                    }
                });
            }
        }
    })
</script>

但按此方法查询后发现layui显示无数据:

仔细检查前端代码,无误。

于是在后端Controller层打断点看传入参数,发现传入参数只有layui重载表格自带的page和limit,我所需要传入的三个参数type、distract和name都为"":

再次检查前端代码,确定问题出在Vue没有接收到表单同步的数据。

于是尝试在另外一个网页从头开始建立基础表单,只在表格渲染时用到Layui,效果如下:

经过测试发现,此时可以正常实现查询逻辑:


原因及思路

于是可以确定问题出在Layui提供的表单上,经过多方资料的查阅,发现此问题的出现是由于Vue和Layui两个框架工作逻辑的冲突导致的:

1.Layui的实现逻辑是向html文件中添加对应组件的html片段

2.Vue的双向绑定在Layui添加组件片段前就已经完成

因此,在Layui的下拉表单中使用v-model并不能成功实现双向绑定。

所以可以得出思路:既然问题出在vue的绑定先于layui的片段添加,那么我们只需要在添加html片段后再手动进行一次数据绑定就可以解决问题(根据其他博主的测试,v-model与下拉框的数据关联未失效,失效的仅是同步到vue代码里的过程,这也可以反证上述原因成立),效果展示:


解决方案

综上,该问题解决方案如下:

  1. 使用layui.form.on()方法实现对下拉框内容变动的监测,再将值传入vue代码中即可

代码如下:

<div class="layui-col-md4">
    <div class="layui-input-inline" style="width: 98%; right:16%">
        <select name="type" v-model="type" lay-filter="form_type">
            <option value="" selected="selected">类型</option>
            <option value="查询">查询</option>
            <option value="新增">新增</option>
            <option value="修改">修改</option>
            <option value="删除">删除</option>
        </select>
    </div>
</div>
<div class="layui-col-md4">
    <div class="layui-input-inline" style="width: 98%; right:10%">
        <select name="distract" v-model="distract" lay-filter="form_distract">
            <option value="" selected="selected">地区</option>
            <option value="南岸区">南岸区</option>
            <option value="渝北区">渝北区</option>
            <option value="巴南区">巴南区</option>
            <option value="渝中区">渝中区</option>
        </select>
    </div>
</div>
<div class="layui-col-md4">
    <div class="layui-input-inline" style="width: 98%; right: 4%">
        <select name="name" v-model="name" lay-filter="form_name">
            <option value="">选择或搜索别名</option>
            <option value="南岸区新增">南岸区新增</option>
            <option value="渝北区新增">渝北区新增</option>
            <option value="巴南区新增">巴南区新增</option>
            <option value="渝中区新增">渝中区新增</option>
        </select>
    </div>
</div>
<script>
    layui.use(['form'], function () {
        layui.form.on('select(form_type)', function (data) {
            housing.type = data.value
        })
        layui.form.on('select(form_distract)', function (data) {
            housing.distract = data.value
        })
        layui.form.on('select(form_name)', function (data) {
            housing.name = data.value
        })
    })
</script>

<script>
    var housing = new Vue({
        el: '#app',
        data: {
            type: '',
            distract: '',
            name: ''
        },
        methods: {
            search() {
                table.reload('table_housing', {
                    url: 'http://localhost:9090/housing/search',
                    method: 'POST',
                    where: { //设定异步数据接口的额外参数,任意设
                        type: this.type
                        ,distract: this.distract
                        ,name: this.name
                    }
                    ,page: {
                        curr: 1 //重新从第 1 页开始
                    }
                });
            }
        }
    })
</script>

注:此方法非本人原创,引自csdn博主 風の唄を聴け 的文章,该博主在文章中还介绍了vue回绑layui 的方法,我在此就不多过赘述,有兴趣的小伙伴点击原文连接即可查看:

Logo

前往低代码交流专区

更多推荐