使用javascript

时间:2018-03-13 11:11:25

标签: javascript jquery vue.js

简介

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

http://janpzimmermann.com

在某些情况下,我仍然在努力解决所有新问题。因此,我将Vue.js与jQuery和JavaScript混合在一起。我知道这不是最好的做法。 但是经过多年和多年的html和css(有时候还有一点点PHP),有些事情对我来说仍然是新的。 ;)

问题

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

    /* 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(" ");
}

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

我也无法找到错误。我也无法确定这不是Vue的错。

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

    // 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有关,但无法找到一种方法,这对我来说是可以理解的。

感谢

1 个答案:

答案 0 :(得分:0)

像这样混合使用Vue和jQuery会使事情变得非常多,很多比他们需要的更难。您使用第一个过滤器遇到的问题是因为Vue不知道您的javascript过滤器正在进行的DOM修改,因此在下次更新时覆盖了它们。如果让它运行起来,你将会遇到与jQuery过滤器完全相同的问题。

所以不要这样做。

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

相反,将属性放在您向Vue提供的数据中,让Vue在绘制DOM之前对其进行过滤。这是pretty simple to do in Vue

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

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-for超过filteredProjects而不是projects,并且您已完成。每当data.currentFilter更改时,列表将重新绘制,并由新值自动过滤。)

可能在Vue中使用jQuery,但它需要非常好地理解框架正在做什么,所以你不会在它和它之间产生冲突。你的外部代码。 (而且我还没有找到一个案例,即将jQuery事件重写为Vue组件并不简单。)其他现代框架如React或Angular也是如此。这些都在一个非常不同的模型上工作,而不是DOM-first策略jQuery倾向于依赖。特别是在学习的时候,如果你一次只坚持一个框架而不是试图将各种东西混合在一起,那么你就会有更轻松的时间。