[英]Using Masonry.JS and Vue.JS
除了 vue,我知道如何使用masonry.js
。 但是,我在使其正常运行并在 vue 框架内正确调用时遇到了问题。 我在 created 或 ready 中调用它,但似乎都没有正确形成网格。 我怎样才能让它在框架内工作? 哦,我确实在这个脚本之前的 html 中调用了 jquery。 这是我在组件内部的内容:
编辑:
我可以看到砌体通过使用 JS 分配其高度并将项目更改为绝对位置来影响网格。 但是,它没有正确放置它们。 它将它们堆叠在彼此之上,而不是像应该在网格中那样并排。
<template>
<div class="projects--container">
<div class="inner-section inner--options">
<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
</div>
</div>
</template>
<script>
export default{
ready: function () {
this.mason();
},
data: function () {
return {
options: [
{
option: 'projects',
phrase: 'for clients',
slogan: 'slogan...'
},
{
option: 'sides',
phrase: 'for us',
slogan: 'we love what we make'
},
{
option: 'moments',
phrase: 'with the crew'
}
]
}
},
methods: {
revert: function () {
this.$dispatch('return-home', true)
},
mason: function () {
var $grid = $('.grid').masonry({
itemSelector: '.grid-item',
columnWidth: 250
});
$grid.masonry('layout');
}
},
events: {
'option-select': function (option) {
}
}
}
</script>
我想这样做的vue 方式是使用refs 。 只需将ref属性分配给模板内的 html 元素,并使用已 挂载回调中的vm.$ref实例属性访问它。
示例代码可能如下所示:
<template>
<div class="grid" ref="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
</template>
<script>
import Masonry from "masonry"; // or maybe use global scoped variable here
export default {
mounted: function(){
let $masonry = new Masonry(this.$refs.grid, {
// masonry options go in here
// see https://masonry.desandro.com/#initialize-with-vanilla-javascript
});
}
}
</script>
在 Vue2 中,没有ready
的生命周期钩子之类的东西。 相反,一旦实例以您想象的方式“准备就绪”,就会触发已mounted
的生命周期挂钩。
参考: https ://v2.vuejs.org/v2/guide/instance.html#Lifecycle-Diagram
正如我所看到的,大多数像 vue 这样的 mv* 框架保持 DOM 元素(视图)与 js(模型)同步,另一方面,像 masonry 这样的框架只需要有效的 DOM 就可以工作。 所以,棘手的部分是在 DOM 发生变化时告诉另一个人。
所以第一个变化是当 vue 完成渲染所有 DOM 时,正如其他答案中提到的,我们在mounted
的生命周期钩子上收到通知,这里是我们可以初始化 masonry 的地方
mounted() {
let grid = document.querySelector('.grid');
this.msnry = new Masonry(grid, {
columnWidth: 25
});
},
在对我们的视图进行任何其他更改时,还需要更新砌体,如果更改项目大小使用layout()
方法,如果添加或删除项目使用reloadItems()
方法
methods: {
toggle(item) {
item.isGigante = !item.isGigante;
Vue.nextTick(() => {
// DOM updated
this.msnry.layout();
});
},
add() {
this.items.push({
isGigante: false,
size: '' + widthClasses[Math.floor(Math.random() * widthClasses.length)] + ' ' + heightClasses[Math.floor(Math.random() * heightClasses.length)]
});
Vue.nextTick(() => {
// DOM updated
this.msnry.reloadItems();
this.msnry.layout();
});
}
}
请注意,这些方法是在 vue 使用Vue.nextTick
函数完成 DOM 更新后调用的。 这是一个工作小提琴。
可能是垂直堆栈只是表明砌体不工作(没有 codepen/plunkr 很难判断)。 @riyaz-ali 有正确的想法。
您必须在mounted()
事件中调用masonry 才能使其工作。 我在我的项目中使用它(加载了图像)它的工作完美
massonryApply (container, context, selector) {
container = $(`#${container}`)
const $grid = container.imagesLoaded(function () {
$grid.masonry({
itemSelector: `.${selector}`,
percentPosition: true,
columnWidth: `.${selector}`
})
$grid.masonry('reloadItems')
})
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.