简介
我为我的一个朋友编写了一个投资组合网站,作为一个大学项目。 我开始学习Vue.js并开始深入研究JavaScript。
在某些情况下,我仍然在努力解决所有新问题。因此,我将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有关,但无法找到一种方法,这对我来说是可以理解的。
感谢
答案 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倾向于依赖。特别是在学习的时候,如果你一次只坚持一个框架而不是试图将各种东西混合在一起,那么你就会有更轻松的时间。