首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用javascript对内容进行排序/筛选

使用javascript对内容进行排序/筛选
EN

Stack Overflow用户
提问于 2018-03-13 11:11:24
回答 1查看 489关注 0票数 0

Introduction

我为我的一个朋友编写了一个投资组合网站,作为一个大学项目。我开始学习Vue.js,并开始深入研究JavaScript。

http://janpzimmermann.com

在某些情况下,我仍然在为所有的新东西而挣扎。因此,我将Vue.js与jQuery和JavaScript混合在一起。我知道这不是最好的练习。但是,在花了很多年的时间,主要是html和css (有时还有点PHP)之后,有些东西对我来说还是很新鲜的。;)

问题

我创建了一个图库网格(内容通过Vue加载),并希望能够通过导航过滤内容。因此,我遇到了以下方法:elements.asp

代码语言:javascript
复制
    /* content filter */
filterSelection("all");

function filterSelection(c) {
  var x, i;
  x = document.getElementsByClassName("content-filter");
  if (c == "all") c = "";
  // Add the "view" class (display:block) to the filtered elements, and remove the "view" class from the elements that are not selected
  for (i = 0; i < x.length; i++) {
    w3RemoveClass(x[i], "view");
    if (x[i].className.indexOf(c) > -1) w3AddClass(x[i], "view");
  }
}

// Show filtered elements
function w3AddClass(element, name) {
  var i, arr1, arr2;
  arr1 = element.className.split(" ");
  arr2 = name.split(" ");
  for (i = 0; i < arr2.length; i++) {
    if (arr1.indexOf(arr2[i]) == -1) {
      element.className += " " + arr2[i];
    }
  }
}

// Hide elements that are not selected
function w3RemoveClass(element, name) {
  var i, arr1, arr2;
  arr1 = element.className.split(" ");
  arr2 = name.split(" ");
  for (i = 0; i < arr2.length; i++) {
    while (arr1.indexOf(arr2[i]) > -1) {
      arr1.splice(arr1.indexOf(arr2[i]), 1);
    }
  }
  element.className = arr1.join(" ");
}

不幸的是,似乎有一个bug。当我打开一个项目时,不要用“关闭”按钮关闭它,然后导航到一个新类别并在那里打开一个项目,之前打开的项目将再次添加到DOM中(即使它不属于这个类别!)。

我还没找到窃听器。我也不能确定这不是Vue的错。

但是我试着用一个JavaScript过滤器来代替jQuery过滤器(这个过滤器使用的是数据属性),遗憾的是,这并不适用于我。因为我可以在每个项目添加一个属性。但有时一个项目属于多个类别。(这个:https://jsfiddle.net/k5g6wcw3/21/)

代码语言:javascript
复制
    // Variable
var posts = $('.post');
posts.hide();


// Click function
$( ".sort" ).click(function() { 
    // Get data of category
    var customType = $( this ).data('filter'); // category
    console.log(customType);
    console.log(posts.length); // Length of articles

    posts
        .hide()
        .filter(function () {
            return $(this).data('cat') === customType;
        })
        .show();
});

// All
$( "#showAll" ).click(function() {
  $( ".post" ).show();
});

进一步思考

我知道这也应该是可能的vue路线,也许是vuex,但无法找到一个方法,如何做,这是我可以理解的。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-13 12:24:06

像这样把Vue和jQuery混合在一起会使事情变得比他们所需要的困难得多、更难。第一个过滤器遇到的问题是,Vue不知道javascript过滤器正在做的DOM修改,所以在下一个更新时重写了它们。如果你让jQuery过滤器正常工作的话,你会遇到完全相同的问题。

所以别那么做。

现在,您让Vue绘制一个完整的项目列表,然后在添加数据属性并隐藏您想要过滤掉的元素之后,尝试在DOM中爬行。这是许多额外的工作(对您和浏览器都是如此),而且每当Vue重新绘制时都会失败(因为它会吹走您在外部所做的更改)。

相反,将属性放在您要输入给Vue的数据中,并让Vue在绘制DOM之前对其进行过滤。这就是pretty simple to do in Vue

(您已经提到每个项目需要多个类别;下面是计算属性的一个快速示例:

代码语言:javascript
复制
data: {
    currentFilter: 'photo',  // set this from a route param, or a v-model, or whatever
    projects: [
        {name: "Project one", categories: ['photo', 'book']},
        {name: "Project two", categories: ['website']},
        {name: "Project 3", categories: ['photo']}
        // ...
    ]
},
computed: {
   filteredProjects() {
      return this.projects.filter(project => {
          return project.categories.indexOf(this.currentFilter) > -1
      })
   }
}

让模板v-forfilteredProjects上而不是projects上运行,您就完成了。每当data.currentFilter更改时,列表将自动重新绘制,并由新值进行筛选。)

可以在Vue内部使用jQuery,但是它需要很好地理解框架正在做什么,这样就不会在它和外部代码之间产生冲突。(我还没有找到这样一种情况,即将jQuery重写为Vue组件并不简单。)其他现代框架也是如此,比如React或Angular;这些框架的工作方式都与DOM优先策略jQuery倾向于依赖的模型非常不同。尤其是当你学习的时候,如果你一次只坚持一个框架,而不是试图把事情混合在一起,你就会有一个简单得多的时间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49254696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档