我知道除了vue之外如何使用masonry.js
。但是,我有问题让它运行并在vue框架内正确调用。我在创建或准备好的内部调用它,但似乎都没有正确形成网格。我怎样才能让这个在框架内工作?哦,我确实在此脚本之前的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>
答案 0 :(得分:8)
我猜这样做的 vue-way 就是使用refs。只需将 ref 属性分配给模板中的html元素,然后使用vm.$ref中的mounted callback实例属性访问它。
示例代码可能如下所示:
<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>
答案 1 :(得分:6)
在Vue2中,没有ready
生命周期钩子这样的东西。相反,一旦实例以您认为的方式“准备好”,就会触发mounted
生命周期钩子。
参考:https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram
答案 2 :(得分:5)
正如我所看到的,大多数像vue这样的mv *框架使DOM元素(视图)与js(模型)保持同步,另一方面,像砌体这样的框架只需要有效的DOM来工作。 因此,棘手的部分是在DOM发生变化时告诉彼此。
所以第一个更改是当vue完成渲染所有DOM时,如其他答案中所述,我们会在mounted
生命周期钩子上通知我们,这里是我们可以初始化砌体的地方
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更新后调用这些方法。
这是working fiddle。
答案 3 :(得分:0)
垂直堆栈可能只是表明砌体不起作用(没有codepen / plunkr很难分辨)。 @ riyaz-ali虽然有正确的想法。
答案 4 :(得分:0)
你必须在mounted()
事件中调用砌体才能使其正常工作。
我正在我的项目(带有imagesloaded)上使用它完美的工作
massonryApply (container, context, selector) {
container = $(`#${container}`)
const $grid = container.imagesLoaded(function () {
$grid.masonry({
itemSelector: `.${selector}`,
percentPosition: true,
columnWidth: `.${selector}`
})
$grid.masonry('reloadItems')
})
}