使用 Masonry.JS 和 Vue.JS
Posted
技术标签:
【中文标题】使用 Masonry.JS 和 Vue.JS【英文标题】:Using Masonry.JS and Vue.JS 【发布时间】:2016-10-28 00:45:11 【问题描述】:我知道除了 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>
【问题讨论】:
请澄清发生了什么。它什么都不做吗?它是否部分工作?它会抛出错误吗? 添加了更多信息和控制台图像。 【参考方案1】:我想这样做的 vue-way 是使用refs。只需将 ref 属性分配给模板内的 html 元素,然后使用 mounted callback 内的 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>
【讨论】:
【参考方案2】:在 Vue2 中,没有 ready
生命周期钩子之类的东西。相反,mounted
生命周期钩子会在实例以您所想的方式“准备就绪”时触发。
参考:https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram
【讨论】:
【参考方案3】:正如我所见,像 vue 这样的大多数 mv* 框架都让 DOM 元素(视图)与 js(模型)保持同步,另一方面,像 masonry 这样的框架只需要有效的 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。
【讨论】:
【参考方案4】:可能是垂直堆栈只是表明砌体不工作(没有 codepen/plunkr 很难判断)。不过@riyaz-ali 的想法是对的。
【讨论】:
这应该是评论而不是答案【参考方案5】:您必须在 mounted()
事件中调用 masonry 才能使其工作。
我在我的项目中使用它(加载了图像)它的工作完美
massonryApply (container, context, selector)
container = $(`#$container`)
const $grid = container.imagesLoaded(function ()
$grid.masonry(
itemSelector: `.$selector`,
percentPosition: true,
columnWidth: `.$selector`
)
$grid.masonry('reloadItems')
)
【讨论】:
我得到 .masonry 不是函数以上是关于使用 Masonry.JS 和 Vue.JS的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 php 和 mysql 使用纬度和经度进行几何搜索
Cocoa - 为啥使用 NSInteger 和 CGFloat 而不是使用 int 和 float,或者总是使用 NSNumber?