Vue组件未加载使用的值

Posted

技术标签:

【中文标题】Vue组件未加载使用的值【英文标题】:Vue Component not loading value used 【发布时间】:2020-08-18 12:08:08 【问题描述】:

我有一个使用 JS 的 Vue 应用程序。我需要使用一些 Select2 来动态加载值,等等。我为我的 Select2 制作了一个 Vue 组件,除了一个问题外,它工作得非常好。我正在使用 Ajax 来获取 Select2 的动态选项,但是当我的 Select2 安装时,它不会加载 Ajax URL 的值。这是我的代码:

<template>
    <table class="table">
        <thead>
        <tr>
            <th>Substance</th>
            <th>Tested</th>
            <th>Results</th>
            <th>Cause of Death</th>
            <th>Person Perscribed For</th>
            <th>Category</th>
            <th></th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="index in SubstanceRows" :key="index">
            <td><input type="text" class="form-control form-control-sm substance-row" /></td>
            <td><select2 class="js-example-basic-single tested-row" :apiurl="SummaryTested" style="width: 100%;"></select2></td>
            <td><select2 class="js-example-basic-single result-row" :apiurl="SummaryResult" style="width: 100%;"></select2></td>
            <td><div class="form-check"><input type="checkbox" class="form-check-input cause-of-death-row" value=""></div></td>
            <td><select2 class="js-example-basic-single obtained-for-row" :apiurl="DrugObtainedFor" style="width: 100%;"></select2></td>
            <td><div class="form-check"><input type="text" class="form-control form-control-sm category-row" /></div></td>
        </tr>
        </tbody>
    </table>
</template>
<script type="text/x-template" id="select2-template">
  <select>
    <slot></slot>
  </select>
</script>

这是我的组件:

Vue.component('select2', 
    props: ['apiurl', 'id'],
    template: '#select2-template',
    mounted: function()
        this.loadSelect2
    ,
    watch: 
        loadSelect2: function() 
            var vm = this
            var apiURL = this.apiurl
            $(this.$el).select2(
                placeholder: "Select an option",
                allowClear: true,
                templateResult: dropdownTemplate,
                templateSelection: dropSelection,
                ajax: 
                    url: function(params)
                        url = 'api/variable/' + apiURL
                        if(params.term) url = 'api/variable/' + apiURL + '/' + params.term
                        return url
                    
                
            )
            //Check if it has a value assigned
            if (vm.$root[apiURL] && vm.$root[apiURL] != '')
                $.ajax(
                    type: 'GET',
                    url: '/api/variable/' + apiURL + '/' + vm.$data[apiURL]
                ).then(function(data) 
                    var option = new Option(data.results[0].label, data.results[0].id, true, true)
                    element.append(option).trigger('change')
                    element.trigger(
                        type: 'select2:select',
                        params: 
                            data: data.results
                        ,
                        templateResult: dropdownTemplate,
                        templateSelection: dropSelection
                    )
                )
            
        
    
)

我卡住的部分是,如您所见(或未见),我使用 v-for 生成这些字段,使用我在 Vue 应用程序中声明的变量。我有一个按钮,可以根据需要添加更多这些(目前我只是将 +1 添加到变量中)。我遇到的问题是在为 select2 做 ajax 时。 /api/variable + apiURL的部分,第一次生成时,变量apiURL是未定义的。我应该提到 v-for 变量 SubstanceRows 的初始值为 3(因此加载时我有三行)。但是,当我使用按钮添加一行时,它工作得很好,并且 url 按预期加载。我猜这是异步的一些问题,但我真的没有足够的 Vue 经验来弄清楚它是什么。

另外,脚本部分id=select2-template,我按照指南进行操作,但我不知道它的作用。

【问题讨论】:

【参考方案1】:

您是否尝试将loadSelect2 函数从watch 移动到methods? 据我所知,手表是用来听道具的。如果有来自父组件的数据更新,则查看 props。

应该是这样的:

    mounted: function()
        this.loadSelect2();
    ,
    methods: 
        loadSelect2: function() 
            var vm = this
            var apiURL = this.apiurl

           // the rest of the code

        

【讨论】:

【参考方案2】:

这是因为您在 mounted 方法中没有 propspropsData,它们只是稍后才出现。放一样。观察者中的函数,以便当apiUrl 更改值(接收非空/未定义值)时,您然后调用该函数。

【讨论】:

感谢您的回答!我把所有东西都放在了watch 函数中,但我遇到了同样的问题。不过我很确定我做错了,给您带来的不便,我深表歉意。请参阅我更新的问题。【参考方案3】:

当你调用 var apiURL = this.apiURL 时是错误的。你的道具都是小写的,应该不是 var apiUrl = this.apiurl

【讨论】:

感谢您的回答!我已经用你的建议更新了我的问题。使用了 ':' 并使用了小写的 apiurl。但是,现在我在控制台上收到一个错误,说 Property or method "SummaryTested" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. 谢谢你的时间。对于每个apiurl,我都会收到此错误 我修改了我的评论并删除了关于绑定的内容,因为您只是传递了一个不需要绑定它的字符串。 我删除了绑定,但它仍然无法正常工作。是不是因为我把这个功能放在了手表里,它应该是挂载的?无论哪种方式,我都安装了它,但它也无法正常工作。真是个谜。 console.log(this.apiurl) 表明该值存在,但在执行 ajax 部分时它没有到达那里。 为什么不在模板中构建一个合适的 Vue 选择框。我认为这就是jQuery正在做的事情? jQuery 和 Vue 不能很好地结合在一起。看起来你试图为你想做的事情做很多事情?在选择框上执行 @change=yourFunctionName() ,然后每次更改选择框时都会调用您的函数并发出 Ajax 请求?这里如何做一个选择框。 vuejs.org/v2/guide/forms.html#SelectR删除底部的整个脚本类型。 设法通过在我的标签上执行&lt;select2 class="js-example-basic-single tested-row" data-apiurl="SummaryTested" style="width: 100%;"&gt;&lt;/select2&gt; 来修复它,然后在组件上我使用var apiURL = $(this.$el).data('apiurl') 获得了值。 100% 肯定必须有更好、更优雅的方法来做到这一点,但目前它是可行的。

以上是关于Vue组件未加载使用的值的主要内容,如果未能解决你的问题,请参考以下文章

Vue组件未加载

Vue组件未加载数据

Vue路由器未加载组件

vue更新或者重新加载组件方法

Vue.component vs import 加载组件

来自 Vue.js 的组件未加载到 Laravel 刀片中