当使用Vue动态加载时,HTML datalist会一直崩溃

时间:2017-12-08 18:22:21

标签: javascript filter vue.js vuejs2 html-datalist

我正在使用Vue.js加载HTML datalist。每当我输入连接到我的datalist的输入框时,我的页面就会冻结(使用Chrome)。我正在使用jQuery进行AJAX调用,最初在页面加载时获取所有用户,然后使用JavaScript过滤器函数创建一个新的数组,其中包含indexOf输入框中输入的内容,然后放入新过滤的对象数组到datalist元素中。

这是我的HTML:

<div id="my-app">
  <input list="user-search" type="text" id="find-user" name="find-user" v-model="findUser">
    <datalist id="user-search">
      <option v-for="user in findUserList">{{ user.vendorName }}</option>
    </datalist>
</div>

这是我的Vue JavaScript:

var myApp = new Vue({
  el: '#my-app',
  data: {
    users: [],
    findUser: '',
    findUserList: '',
  },
  watch: {
    findUser: function(val) {
      this.findUserResults();
    }
  },
  methods: {
    findUserResults: function() {
      var lookFor = this.findUser.toLowerCase();
      this.findUserList = this.users.filter(function(user) {
        return (user.vendorName.toLowerCase().indexOf(myApp.findUser.toLowerCase()) > -1 || user.email.toLowerCase().indexOf(myApp.findUser.toLowerCase()) > -1);
      });
    },
    loadUsers: function() {
      $.ajax({
        method: 'GET',
        url: '/users',
        success: function(data) {
          myApp.users = JSON.parse(data);
        },
        error: function() {
                console.log('error...');
        }
      });
    }
  },
  mounted: function() {
    this.loadUsers();
  }
})

页面加载时用户加载正常。没有问题。我甚至评论了v-forconsole.log'过滤器的结果也没有问题。当我在<option>中动态添加<datalist>值时,会出现此问题。我已尝试将选项包装在vue <template>标记中,并将v-for移到那里但没有成功。

我在其他页面上工作正常,但我填写的表格包含<tr><td>,而不是<datalist><option>

可能导致我的网页崩溃的原因是什么? <datalist>不足以处理所有这些问题吗?也许我错过了第二组眼睛可以帮助解决的问题。

修改

正在填充到users的数据看起来像这样(它是一个对象数组):

[{id:1, vendorName:'john'}, {id:2, vendorName:'Rachel', {id:3, vendorName:'Steve'}]

ANSWER

这实际上只是某人过度思考(我)的一个例子。 B.Fleming关于这个递归的答案让我想到了为什么我的上述方法不正确。每次用户输入时都无需继续重新加载datalist选项。这正是与<datalist>关联的<input>所做的事情;不需要JavaScript。我需要(ed)做的就是在页面加载时将所有~3,000个用户加载到<datalist>标记为<option>(或者每当我想要显示输入和数据列表时),并让其余的是datalist和输入处理。我没有在上面的示例中使用应用程序对此进行测试,因为我不在那台计算机附近,但作为一个概念证明,数据列表可以处理数千个选项元素,我写了这个并在本地运行它没有问题(不知道为什么代码段控制台一直说它有效时会出错:

window.onload = function() {
    var datalistElement = document.getElementById('datalist-test');
    var datalistString = '';
    for (var i = 0; i < 3000; i++) {
        datalistString += '<option>' + Math.random().toString(36).substring(7); + '</option>';
    }
    datalistElement.innerHTML = datalistString;
}
<!DOCTYPE html>
<html>
<head>
	<title>Datalist Test</title>
</head>

<body>
	<input list="datalist-test" type="text">
	<datalist id="datalist-test">
	</datalist>
</body>
</html>

3,000个datalist选项元素,没关系。

2 个答案:

答案 0 :(得分:1)

你有无限递归的电话。您在输入/删除搜索文本时调用myApp.findUser(),调用myApp.findUserResults(),调用myApp.findUser()等。您需要解决此问题。

要解决此问题,您所要做的就是将所有用户加载到datalist选项中一次。然后,让输入框和datalist处理剩下的事情。每次用户输入时都无需继续重新加载datalist选项。

答案 1 :(得分:1)

通常情况下,您会使用computed property。我还做了一些其他的改变。首先,从内部引用Vue本身是一种不好的做法;只需使用this。此外,datalist选项还具有您需要指定的value属性。

&#13;
&#13;
console.clear()

const users = [
  {vendorName: "Vendor One", email: "bob@example.com"},
  {vendorName: "Vendor Two", email: "mary@example.com"},
  {vendorName: "Vendor Three", email: "jim@example.com"},
  {vendorName: "Vendor Four", email: "joe@vendor.com"},
  {vendorName: "Vendor Five", email: "sara@vendor.com"},
  
]
var myApp = new Vue({
  el: '#my-app',
  data: {
    users: [],
    findUser: '',
  },
  computed:{
    vendors(){
      return this.users.filter(u => {
        return u.vendorName.toLowerCase().indexOf(this.findUser) > -1 ||
          u.email.toLowerCase().indexOf(this.findUser) > -1
      })
    }
  },
  methods: {
    loadUsers: function() {
      // obviously, this is different for example purposes
      this.users = users
    }
  },
  mounted: function() {
    this.loadUsers();
  }
})
&#13;
<script src="https://unpkg.com/vue@2.4.2"></script>
<div id="my-app">
  <h3>Type "V"</h3>
  <input list="user-search" name="find-user" v-model="findUser">
  <datalist id="user-search">
    <option v-for="user in vendors" :value="user.vendorName">
  </datalist>
</div>
&#13;
&#13;
&#13;