Vue-masonry plugin doesn't work with Vuetify - vue.js

I try to implement masonry grid via vue-masonry plugin. I use Nuxt and Vuetify. It seems like vue-masonry doesn't do work with vuetify.
I connect vue-masonry as plugin (vue-masonry.js) to my Nuxt project
import Vue from 'vue'
import {VueMasonryPlugin} from 'vue-masonry'
Vue.use(VueMasonryPlugin)
I setup the plugin in nuxt.config.js
plugins: [
{ src: '~/plugins/vue-masonry', ssr: false }
],
Next I try to use vuetify grid with vue-masonry, and here things broken
<template>
<v-container>
<v-row>
<v-col
xs="12"
sm="6"
md="4"
lg="3"
v-for="card in cards"
:key="card.id"
v-masonry
origin-left="true"
horizontal-order="true"
transition-duration="0.3s"
item-selector=".item"
>
<v-card v-masonry-tile class="item" max-width="240">
<v-card-title>{{card.title}}</v-card-title>
<v-card-text class="text-ellipsis">{{card.text}}</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
data() {
return {
cards: [
{
id: 1,
title: "title",
text:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make",
},
{
id: 2,
title: "new one",
text:
"Lorem Ipsum has when an unknown printer took a galley of type and scrambled it to make",
},
{
id: 3,
title: "title",
text:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. took a galley of type and scrambled it to make",
},
{
id: 4,
title: "title",
text:
"Lorem Ipsum is simply dummy. Lorem Ipsum has been the when an unknown printer took a galley of type and scrambled it to make",
},
{
id: 5,
title: "title",
text:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the when an unknown printer took a galley of type and scrambled it to make",
},
{
id: 6,
title: "title",
text:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. a galley of type and scrambled it to make",
},
{
id: 7,
title: "title",
text:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the when an unknown printer took a galley of type and scrambled it to make",
},
{
id: 8,
title: "title",
text:
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the when an unknown printer took a galley",
},
{
id: 9,
title: "title",
text:
"Lorem Ipsum has been the when an unknown printer took a galley of type and scrambled it to make",
},
{
id: 10,
title: "title",
text: "Lorem Ipsum is simply industry.",
},
],
};
},
};
</script>
masonry grid doesn't appear, just clear vuetify cols with cards.
How can I achieve masonry grid with vuetify? I'll be glad any suggestions and implementations masonry grid with vuetify.

I found a right grid solution for vue-masonry with vuetify! It works like a charm =)
<template>
<v-container>
<v-row
v-masonry
origin-left="true"
horizontal-order="true"
transition-duration="0.3s"
item-selector=".item"
>
<v-col
v-masonry-tile
class="item"
v-for="card in cards"
:key="card.id"
xs="3"
sm="6"
md="4"
lg="3"
>
<v-card>
<v-card-title>{{ card.title }} {{ card.id }}</v-card-title>
<v-card-text>{{ card.text }}</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>

Related

Nuxt not loading nested component

I've created a third party components library as described on this page https://nuxtjs.org/blog/improve-your-developer-experience-with-nuxt-components#third-party-component-library. Than I used the components in a new clean nuxt project. I have a BaseCard component which has 3 slots and I have a BaseImage component. Now I want to use the BaseImage component in a slot from the BaseCard component but it is not rendered. If I add an additional BaseImage component outside of the BaseCard component, than all BaseImage components are rendered (see screenshots below). Seems like that the components within a slot are not loaded.
Screenshots
without additional BaseImage
with additional BaseImage
Code
Don't work
<template>
<div>
<BaseCard>
<template v-slot:image>
<BaseImage
imgSrc="https://picsum.photos/400/400?random=1"
imgAlt="Some alt tag"
/>
</template>
<template v-slot:header>
Here might be a page title
</template>
<template v-slot:content>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum
pariatur distinctio cum. Ratione doloribus asperiores eaque
laboriosam repellendus perferendis iusto magni in necessitatibus
exercitationem eum expedita aliquam autem, tenetur itaque.
</p>
</template>
</BaseCard>
</div>
</template>
<script lang="ts">
import Vue from "vue";
export default Vue.extend({});
</script>
works
<template>
<div>
<BaseCard>
<template v-slot:image>
<BaseImage
imgSrc="https://picsum.photos/400/400?random=1"
imgAlt="Some alt tag"
/>
</template>
<template v-slot:header>
Here might be a page title
</template>
<template v-slot:content>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum
pariatur distinctio cum. Ratione doloribus asperiores eaque
laboriosam repellendus perferendis iusto magni in necessitatibus
exercitationem eum expedita aliquam autem, tenetur itaque.
</p>
</template>
</BaseCard>
<BaseImage
imgSrc="https://picsum.photos/400/400?random=1"
imgAlt="Some alt tag"
/>
</div>
</template>
<script lang="ts">
import Vue from "vue";
export default Vue.extend({});
</script>
nuxt.config.js (shared-components is my library for the components)
export default {
// Target: https://go.nuxtjs.dev/config-target
target: "static",
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: "demo",
htmlAttrs: {
lang: "en",
},
meta: [
{ charset: "utf-8" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },
{ hid: "description", name: "description", content: "" },
],
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: ["#/assets/scss/variables.scss"],
styleResources: {
scss: ["./assets/scss/*.scss"],
},
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/typescript
"#nuxt/typescript-build",
"shared-components",
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: ["#nuxtjs/style-resources"],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
};
I use nuxt 2.15.2.

why when click on an item, all item opens

I have list with an accordion, when you click on a item, all items opens, I need to open just one,
I understand that a loop is needed to iterate over all the items and apply the class to a specific one, but how to do this, please help
component:
<ul class="accordion accordion__trigger"
:class="{'accordion__trigger_active': visible}"
#click="open">
<li class="accordion__item" v-for="category in MAIN_CATS">
<nuxt-link exact no-prefetch active-class="link-active"
:to="`/category/${category.id}`"
class="menu-button">
{{ category.title }}
</nuxt-link>
<div class="accordion__content">
<div class="menu-sub-list" v-show="visible">
<ul class="sub-list">
<li class="menu-item"
v-for="sub in SUB_CATS(category.id)"
:key="sub.id">
<nuxt-link :to="`/category/${sub.id}`" class="menu-button">
{{ sub.title }}
</nuxt-link>
</li>
</ul>
</div>
</div>
</li>
</ul>
code:
name: "acc",
data() {
return {
index: null,
Accordion: {
count: 0,
active: null
}
};
},
computed: {
...mapGetters([
'MAIN_CATS',
'SUB_CATS'
]),
visible() {
return this.index === this.Accordion.active;
}
},
methods: {
...mapActions([
'GET_CATEGORIES_LIST',
]),
open() {
if (this.visible) {
this.Accordion.active = null;
} else {
this.Accordion.active = this.index;
}
},
start(el) {
el.style.height = el.scrollHeight + "px";
},
end(el) {
el.style.height = "";
}
},
created() {
this.index = this.Accordion.count++;
},
mounted() {
this.GET_CATEGORIES_LIST()
},
I have list with an accordion, when you click on a item, all items opens, I need to open just one,
I understand that a loop is needed to iterate over all the items and apply the class to a specific one, but how to do this, please help
There are multiple differences between your code and code from the answer that you referred to.
You can notice that #click is placed in the same line as v-for.
The main reason for that is to be able to easily access index of each element in a loop.
Not to overcomplicate it for you, I created a basic use case scenario:
<template>
<div id="accordion" class="accordion-container">
<ul
v-for="(category, index) in items"
:key="index"
class="accordion accordion__trigger"
:class="{'accordion__trigger_active': visible===index}"
#click="visible=index"
>
<li class="accordion__item">
{{ category.title }}
<div class="accordion__content">
<div class="menu-sub-list" v-show="visible===index">
<ul class="sub-list">
<li class="menu-item">{{ category.sub }}</li>
</ul>
</div>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "trial-page",
data() {
return {
items: [
{
title: "Accordion 1",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
sub: "Pellentesque risus mi"
},
{
title: "Accordion 2",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
sub: "Pellentesque risus mi"
},
{
title: "Accordion 3",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
sub: "Pellentesque risus mi"
}
],
visible: null
};
}
};
</script>
<style>
.accordion__trigger_active {
background-color: blue;
color: white;
}
</style>
You can see that the idea is to operate with index value that is assigned to visible data property in this case.
We simply check if the visible is equal to the currently pressed item with the value of index.
With that we conditionally v-show element and trigger the class :class="{'accordion__trigger_active': visible===index}".
Note that if you had more v-for loops in the same component then you would need to make sure the value used for visible is always unique, for that you could simply add some string to it like:
#click="visible=index+'category'"
Also remember to assign a :key when using v-for.
Example:
v-for="(category, index) in items" :key="index"

How to route dynamic content?

I'm front end designer and trying to figure out how to use VueJS.
My github: https://github.com/soraname/mangarou
Here is my problem:
User click Soraname page
Route to Soraname page - (soraname.vue)
Load component Autor.vue - send prop or parameter
Load Soraname content
Basically, Page A route to Page A View, load Component with Page A content.
Valid if click Page B, C, D. Everyone use the same Component but change the content data.
I don't know how to do it, pass a variable to set what Data should load.
I've tried this:
soraname.vue (View)
<template>
<div class="soraname content-box">
<Autor v-bind="soraname"></Autor>
</div>
</template>
Load the Component Autor.vue
<template>
<div id="Autor">
<div class="row">
<div class="col s12 autor-header">
<img :src="pageautor.Logo" width="128"> <h1>{{pageautor.Nome}}</h1>
</div>
</div>
<div class="row">
<div class="col s12 autor-header">
<h3>Bio</h3>
<p>{{pageautor.Bio}}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'autor',
components: {
},
data() {
return {
pageautor: {
Nome: "Soraname3333",
Bio: '/soraname',
Logo: '/assets/media/logos/soraname.png',
Color: 'purple accent-3',
links: [
{
Item: 'LINKSoraname',
Elo: '/soraname',
Text: 'lorem ipsum lorem ipsum lorem ipsum lorem ipsum ',
Img: '/autores/soraname/link01.png'
}
],
mangas: [
{
Titulo: 'MANGASoraname',
Elo: '/soraname',
Sinopse: 'lorem ipsum lorem ipsum lorem ipsum lorem ipsum ',
Img: '/assets/media/logos/soraname.png'
}
]
},
soraname: {
Nome: "SoranamDDDe",
Bio: '/soraname',
Logo: '/assets/media/logos/soraname.png',
Color: 'purple accent-3',
links: [
{
Item: 'LINKSoraname',
Elo: '/soraname',
Text: 'lorem ipsum lorem ipsum lorem ipsum lorem ipsum ',
Img: '/autores/soraname/link01.png'
}
],
mangas: [
{
Titulo: 'MANGASoraname',
Elo: '/soraname',
Sinopse: 'lorem ipsum lorem ipsum lorem ipsum lorem ipsum ',
Img: '/assets/media/logos/soraname.png'
}
]
}
}
},
methods: {
}
};
</script>
Router: https://github.com/soraname/mangarou/blob/master/src/router.js
Soraname View (Page A): https://github.com/soraname/mangarou/blob/master/src/views/soraname.vue
Autor.vue (Component): https://github.com/soraname/mangarou/blob/master/src/components/Autores/Autor.vue
Thank you!
In most cases, the data comes from a remote server, you can use your component to make an AJAX call and store the result however a better approach will be to use VUEX as a centralized state - with this approach you will also be able to use the author data across multiple components without the need to pass it over and over.
To make it clear, your route should have a parameter to identify the selected author (surname, id, whatever) - you do that with :surname when specifying the route. Then your component is loaded and read the parameter from the route this.$route.params.surname then use it to load the data from a remote server / vuex
In my opinion you don't need vuex you need a parent component (maybe layout) that gets the data has a computed property which it passes to the child component, the computed property is the data you want, it will update when your child component emits a change that triggers an event to change one of it's dependencies.
So basically parent handles data passes down to child and changes based on events emitted from child.

Odoo11 TypeError: this.pos is undefined with a screen widget triggered by a button action

Create a screen "custom-screen" extended from screen widget with a template show a paragraph of lorem and return object of screen widget so it can be called from other widgets.
This screen I want to trigger this screen widget from a button. The screen showed but I got this error "this.pos is undefined" when the button clicked
TypeError: this.pos is undefined
TypeError: this.pos is undefined
http://localhost:8069/web/content/1394-95d31f5/point_of_sale.assets.js:337
Traceback:
show#http://localhost:8069/web/content/1394-95d31f5/point_of_sale.assets.js:337:1
show_screen#http://localhost:8069/web/content/1394-95d31f5/point_of_sale.assets.js:316:28
button_click#http://localhost:8069/web/content/1394-95d31f5/point_of_sale.assets.js:572:385
renderElement/<#http://localhost:8069/web/content/1394-95d31f5/point_of_sale.assets.js:362:203
dispatch#http://localhost:8069/web/content/941-9a091d9/web.assets_common.js:892:378
$event.dispatch#http://localhost:8069/web/content/1394-95d31f5/point_of_sale.assets.js:480:8
add/elemData.handle#http://localhost:8069/web/content/941-9a091d9/web.assets_common.js:865:151
__mainfest__.py
{
'name': "custom-screen",
'summary': """
Short (1 phrase/line) summary of the module's purpose, used as
subtitle on modules listing or apps.openerp.com""",
'description': """
Long description of module's purpose
""",
'author': "My Company",
'website': "http://www.yourcompany.com",
'category': 'Uncategorized',
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['base'],
# always loaded
'data': [
'views/templates.xml',
],
'demo': [
'demo/demo.xml',
],
'qweb': [
'static/src/xml/custom-screen.xml',
],
}
views/templates
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<script type="text/javascript" src="/custom-screen/static/src/js/custom.js"></script>
</xpath>
</template>
</odoo>
> custom.js
odoo.define('custom-screen.custom-screen', function (require) {
"use strict";
var screens = require('point_of_sale.screens');
var gui = require('point_of_sale.gui');
var Button = screens.ActionButtonWidget.extend({
template: 'Button',
button_click: function () {
var self = this;
console.log('Button Clicked');
self.gui.show_screen('custom-screen');
},
});
screens.define_action_button({
'name': 'button',
'widget': Button,
});
var CustomScreenWidget = screens.ScreenWidget.extend({
template: 'CustomScreenWidget',
init: function () {
console.log("Initialize the custom screen");
}
});
gui.define_screen({
'name': 'custom-screen',
'widget': CustomScreenWidget,
});
return {
Button: Button,
CustomScreenWidget: CustomScreenWidget
};
});
static/src/xml/custom-screen.xml
<t t-name="Button">
<span class="control-button">
<!--<i class="fa fa-print"></i>-->
Open Custom Screen
</span>
</t>
<t t-name="CustomScreenWidget">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus alias, aliquid cupiditate dignissimos, doloribus, enim error eum fugiat id nisi odit quibusdam quo repellat repellendus sed vitae voluptatem. Distinctio, nemo.</p>
</div>
</t>
Can you provide whole traceback of error stack here. Also this error is raised because you try to access current value of 'pos' object but it is not defined so this error is getting raised.

vuejs : how to set link to popover block in for circle

In my laravel5.5/vuejs2.5 application I need to show list of buttons with popover text using vue-js-popover ( https://github.com/euvl/vue-js-popover ) library
But I failed the valid syntax. I tried as :
<ul>
<li v-for="popoverData, index in popoverDataArray">
<button :v-popover="'hint_'+popoverData.id">Toggle popover # {{ popoverData.id }}</button>
<popover :name="'hint_'+popoverData.id">
{{ popoverData.text }}
</popover>
</li>
</ul>
...
data: function () {
return {
...
popoverDataArray:[
{id: 1, text : 'Lorem ipsum dolor sit amet, 1111' },
{id: 2, text : 'Lorem ipsum dolor sit amet, 2222.' },
...
],
}
Which is the correct syntax in button definition to set link to popover block ?
Thanks!