0👍
I think I got it, need 2 make 2 separate components, one with a flex and one with the css grid as the structure, cannot have both in one component because the structural layout of the item is different using css grid and flexbox, make a 3rd component that checks for support of CSS Grid in JS using a computed property CSS.supports(‘display’, ‘grid’)
HTML
script#flex(type="text/x-template")
.news-item2(
:key="item.feed_item_id",
:ref="item.feed_item_id",
role="listitem",
tabindex="0"
)
.news-item-pubdate-wrapper
.news-item-pubdate2 1m
.news-item-content-wrapper
.news-item-title-wrapper
.news-item-title2(:style="titleStyle") {{ item.title }}
span.news-item-link2 example.com
.news-item-votes-wrapper
.news-item-likes2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-thumbs-up
span.news-item-vote-count2 {{ item.likes }}
.news-item-dislikes2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-thumbs-down
span.news-item-vote-count2 {{ item.dislikes }}
.news-item-bullish2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-arrow-up
span.news-item-vote-count2 {{ item.bullish }}
.news-item-bearish2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-arrow-down
span.news-item-vote-count2 {{ item.bearish }}
.news-item-comments2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-comment-alt
span.news-item-vote-count2 0
.news-item-tags-wrapper
.news-item-tags2.has-text-right(:style="tagStyle")
.news-item-tag2(
v-for="(tag, i) in item.tags",
:key="item.tag",
@click.stop="updateTag(tag)"
)
a.button.is-paddingless.is-small.is-uppercase.is-text
| {{ tag }}
span(v-if="lineCountTag - 1 === i && item.tags.length > lineCountTag") ...
span(v-else)
script#grid(type="text/x-template")
.news-item(
:key="item.feed_item_id",
:ref="item.feed_item_id",
role="listitem",
tabindex="0"
)
.news-item-pubdate 1m
.news-item-title(:style="titleStyle") {{ item.title }}
span.news-item-link example.com
.news-item-likes
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-thumbs-up
span.news-item-vote-count {{ item.likes }}
.news-item-dislikes
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-thumbs-down
span.news-item-vote-count {{ item.dislikes }}
.news-item-bullish
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-arrow-up
span.news-item-vote-count {{ item.bullish }}
.news-item-bearish
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-arrow-down
span.news-item-vote-count {{ item.bearish }}
.news-item-comments
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-comment-alt
span.news-item-vote-count 0
.news-item-tags.has-text-right(:style="tagStyle")
.news-item-tag(
v-for="(tag, i) in item.tags",
:key="item.tag",
@click.stop="updateTag(tag)"
)
a.button.is-paddingless.is-small.is-uppercase.is-text
| {{ tag }}
span(v-if="lineCountTag - 1 === i && item.tags.length > lineCountTag") ...
span(v-else)
script#item(type="text/x-template")
template(v-if="supportsCssGrid", :item="item")
grid(:item="item")
template(v-else)
flex(:item="item")
body
#__nuxt
#__layout
item(:item="item")
Vue JS
const lineClamp = {
data() {
return {
lineCountTag: 2,
lineCountTitle: 2,
heightPerLineTag: 30,
heightPerLineTitle: 24
};
},
computed: {
tagStyle() {
return {
height: this.heightPerLineTag * this.lineCountTag + "px",
maxHeight: this.heightPerLineTag * this.lineCountTag + "px"
};
},
titleStyle() {
return {
height: this.heightPerLineTitle * this.lineCountTitle + "px",
maxHeight: this.heightPerLineTitle * this.lineCountTitle + "px"
};
}
}
};
Vue.component("flex", {
template: "#flex",
mixins: [lineClamp],
props: {
item: {
type: Object,
default: () => {},
required: true
}
}
});
Vue.component("grid", {
template: "#grid",
mixins: [lineClamp],
props: {
item: {
type: Object,
default: () => {},
required: true
}
}
});
Vue.component("item", {
template: "#item",
props: {
item: {
type: Object,
default: () => {},
required: true
}
},
computed: {
supportsCssGrid() {
return CSS.supports("display", "grid");
}
}
});
new Vue({
el: "#__nuxt",
data() {
return {
item: {
feed_item_id: 1,
title:
"The first one is made with a grid layout while the second one is made with a flex layout. The templates are different, how do I load the right one based on what is supported by the browser?",
tags: ["trump", "putin", "defi"],
likes: 10,
dislikes: 5,
bullish: 6,
bearish: 0
},
lineCountTag: 2,
lineCountTitle: 2,
heightPerLineTag: 30,
heightPerLineTitle: 24
};
},
computed: {
tagStyle() {
return {
height: this.heightPerLineTag * this.lineCountTag + "px",
maxHeight: this.heightPerLineTag * this.lineCountTag + "px"
};
},
titleStyle() {
return {
height: this.heightPerLineTitle * this.lineCountTitle + "px",
maxHeight: this.heightPerLineTitle * this.lineCountTitle + "px"
};
}
}
});
Source:stackexchange.com