m pulling the last strand of ny hair working onto toggle functionality using vuejs the console i dont find anything
my code seems to be
<template>
<div class="wrapper">
<nav class="nav flex-column sideBar" v-show='isOpen'>
<a class="nav-link active" href="#">Home</a>
<a class="nav-link" href="#">Contact</a>
</nav>
<div class="container-fluid">
<nav>
<div class="content">
<div class="navbar navbar-expand-lg">
<button type="button" class="btn btn-info" #click='toggleSideBar'>
<i class="fas fa-align-left"></i>
</button>
</div>
</div>
</nav>
</div>
</div>
</template>
<script>
export default{
data(){
isOpen=false;
},
method(){
toggleSideBar();
},
toggleSideBar(){
console.log("==========="+this.isOpen)
this.isOpen=!this.isOpen;
}
}
</script>
button on click the togglle fuctionality doesnt work out doent work out
any help much appreciated
this is the inspect html in browser
<button type="button" class="btn btn-info">
and not
<button type="button" class="btn btn-info" onclick='toggleSidebar()'>
the click function not added to it
m using sass
.wrapper {
display: flex;
align-items: stretch;
width:100%;
}
.sideBar{
border: 1px solid;
width: 30%;
height: 100vh;
margin-left: 0;
transition: all 0.5s;
background-color: #f9f9f7;
}
.container-fluid {
padding-right: 0px;
padding-left: 0px;
}
.navbar{
#extend .navbar;
background-color: #eae9e5;
}
.sidebar.active {
margin-left: -250px;
}
first, add return then change = to : and ; to , in your data()
data(){
return{
isOpen: false,
}
},
then put the toggleSideBar() inside your method like this:
methods:{
toggleSideBar(){
console.log("================"+this.isOpen)
this.isOpen=!this.isOpen;
}
}
FINAL OUTPUT
export default{
data(){
return{
isOpen: false,
}
},
methods:{
toggleSideBar(){
console.log("================"+this.isOpen)
this.isOpen=!this.isOpen;
},
}
}
<script>
export default{
data(){
isOpen: false; //Change this line to : instead of =
},
method(){
toggleSideBar: function(){
console.log("================"+this.isOpen)
this.isOpen=!this.isOpen;
}
},
}
</script>
Related
I am trying to create dynamic columns, whenever I have 2,3,4 columns then it's not a problem because these are cards with same styles. I want to be able to have 1 item per row with completely different css than the cards. What's the best way to achieve that?
This is what I've tried so far
<script setup>
import { ref } from 'vue'
const list = ref([
{ title: 'hello', content: 'world'},
{ title: 'hello', content: 'world'},
{ title: 'hello', content: 'world'},
{ title: 'hello', content: 'world'},
{ title: 'hello', content: 'world'},
])
const itemsPerRow = ref('25%')
function toggle(e) {
itemsPerRow.value = `${e.target.value}%`
}
</script>
<template>
<select #change="toggle($event)">
<option value="25">4</option>
<option value="33">3</option>
<option value="50">2</option>
<option value="100">1</option>
</select>
<div class="container">
<div class="items">
<div v-for="item in list" class="item">
{{ item.title }}
</div>
</div>
</div>
</template>
<style>
.items {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
}
.item {
flex-basis: v-bind(itemsPerRow);
border: 1px solid black;
box-sizing: border-box;
}
</style>
Working Example
This is just one of many ways you could conditionally render the data based on the number of columns.
Per Vue documentation, you could place the v-for on a template element. And inside use v-if and v-else to render different markup. In this example we check if itemsPerRow == '100%', which indicates that one column is being displayed, and apply different Bootstrap classes.
<template v-for="item in list">
<div v-if="itemsPerRow == '100%'" class="item card mb-2">
<img class="card-image-top" src="https://loremflickr.com/320/50/dog">
<div class="card-body">
<h5 class="card-title">{{item.title}}</h5>
{{item.content}}
</div>
</div>
<div v-else class="item alert alert-primary">
{{ item.title }}
</div>
</template>
Snippet
The snippet differs from the original code since it's an app rather than a component. Selecting 1 column from the dropdown will display a different layout from multiple columns.
const {
createApp
} = Vue
createApp({
methods: {},
watch: {
itemsPerRow: function(value) {
document.querySelector(":root").style
.setProperty("--itemsPerRow", value);
}
},
data() {
return {
itemsPerRow: "25%",
list: []
}
},
mounted() {
for (let i = 1; i <= 100; i++) {
this.list.push({
title: "Title " + i,
content: "The quick brown fox jumped over the lazy dog"
});
}
}
}).mount('#app')
:root {
--itemPerRow: 25%;
}
.container {
margin: 2rem;
}
.items {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
}
.item {
flex-basis: var(--itemsPerRow);
border: 1px solid black;
box-sizing: border-box;
padding: 0.25rem;
}
<div id="app">
<div class="container">
<select v-model="itemsPerRow" class="form-control mb-2">
<option value="25%">4 columns</option>
<option value="33%">3 columns</option>
<option value="50%">2 columns</option>
<option value="100%">1 column</option>
</select>
<div class="items">
<template v-for="item in list">
<div v-if="itemsPerRow == '100%'" class="item card mb-2">
<img class="card-image-top" src="https://loremflickr.com/320/50/dog">
<div class="card-body">
<h5 class="card-title">{{item.title}}</h5>
{{item.content}}
</div>
</div>
<div v-else class="item alert alert-primary">
{{ item.title }}
</div>
</template>
</div>
</div>
</div>
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
This is the logic algorithm I'm converting and it's not working.
Popup.vue
<script>
import '../../assets/style.css'
export default {
data(){
return{
ceos: [{name_ceo:"Mr. A",
position_ceo:"CEO-GOSTREAM",
content:"Lorem."},
{name_ceo:"Mr. B",
position_ceo:"CTO-GOSTREAM",
content:"Lorem2."},
{name_ceo:"Mr. C",
position_ceo:"CGO-GOSTREAM",
content:"Lorem3."},
]
}
},
methods:{
modalCeo(i){
var modal = this.$refs.modal;
modal[0].style.display="flex";
ceos.forEach(element => {
name_ceo1.innerHTML=ceos[i].name_ceo;
position.innerHTML=ceos[i].position_ceo;
content.innerHTML=ceos[i].content;
});
},
closemodal(){
var modal = this.$refs.modal;
modal[0].style.display="none";
}
}
}
</script>
<style>
</style>
My theme:
<template>
<div class="ceo">
<div ref="modal" class="ceo-popup">
<div class="modal-content-ceo">
<div class="btn-close-popup">
<img src="../../assets/close.svg" id="btn-close-modal" type="button" #click="closemodal()">
</div>
<div class="content-main" v-for="(detail, index) in ceos" :key="index">
<h3 id="name"></h3>
<h5 id="position"></h5>
<h6 id="intro-ceo"></h6>
</div>
<img class="buiding-popup" src="../../assets/Group 226.png" alt="">
</div>
</div>
<div class="title">
<h5>Đội ngũ GoStream</h5>
<h2>Co-Founders</h2>
</div>
<div class="avatar-buiding">
<img class="buiding" src="../../assets/building-0122.png" alt="">
<div class="avatar ">
<img src="../../assets/Profile1.png" #click="modalCeo(0)">
<img src="../../assets//Profile2.png" alt="" #click="modalCeo(1)">
<img src="../../assets/Profile3.png" alt="" #click="modalCeo(2)">
</div>
</div>
</div>
</template>
I want when I click it, a pop up will appear showing the values I have given.
Can you guys give me a solution to this problem?
<div class="avatar" v-for="(item, index) in images" :key="index" >
<img :src="item.url" #click="modalCeo(index)">
</div>
Script:
images:[
{url: '../../assets/Profile1.png'},
{url: '../../assets/Profile2.png'},
{url: '../../assets/Profile3.png'},
]
Update on the code I worked on but it still can't render the image.
You can simply achieve it by using Vue Modal component.
Demo :
new Vue({
el: '#app',
data: {
showModal: false,
selectedCeo: [],
ceos: [
{name_ceo:"Mr. A",
position_ceo:"CEO-GOSTREAM",
content:"Lorem."},
{name_ceo:"Mr. B",
position_ceo:"CTO-GOSTREAM",
content:"Lorem2."},
{name_ceo:"Mr. C",
position_ceo:"CGO-GOSTREAM",
content:"Lorem3."}
]
},
methods: {
modalCeo(index) {
this.showModal = true;
this.selectedCeo = this.ceos[index];
}
}
});
.modal-vue .overlay {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
}
.modal-vue .modal {
position: relative;
width: 300px;
z-index: 9999;
margin: 0 auto;
padding: 20px 30px;
background-color: #fff;
}
.modal-vue .close{
position: absolute;
top: 10px;
right: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!-- app -->
<div id="app" class="modal-vue">
<!-- button show -->
<button v-for="(item, index) in ceos" :key="index" #click="modalCeo(index)">{{ item.name_ceo }}</button>
<!-- overlay -->
<div class="overlay" v-if="showModal" #click="showModal = false"></div>
<!-- modal -->
<div class="modal" v-if="showModal">
<button class="close" #click="showModal = false">x</button>
<p>Name : {{ selectedCeo.name_ceo }}</p>
<p>Position : {{ selectedCeo.position_ceo }}</p>
<p>Content : {{ selectedCeo.content }}</p>
</div>
</div>
Note : I updated code snippet as per your comment. Instead of the profile pictures I used buttons just for the demo.
Is there an easy way to apply masonry to grid items in Vue? I've been searching through tutorials and questions here, but I haven't been able to successfully apply Masonry to my app. I'm looking for a way to use Masonry to automatically place and size the images:
<template>
<div class="row" v-if="othersImages">
<div class="col" v-if="errors">
<div class="alert alert-danger"><p>{{ errors }}</p></div>
</div>
<div id="others-images" class="grid">
<div class="grid-item" v-for="image in othersImages" :key="image.id">
<h5>{{ image.name }}</h5>
<picture v-bind="'image' + image.id">
<img v-bind:src="image.image.path" v-bind:alt="image.description"/>
</picture>
</div>
<div class="clearfix"></div>
</div>
</div>
</template>
<script>
export default {
name: 'othersImages',
created() {
this.fetchImages();
},
data() {
return {
apiRequest: new this.$request(),
othersImages: [],
errors: '',
};
},
methods: {
fetchImages() {
const endpoint = 'images';
this.apiRequest.get(endpoint)
.then((response) => {
this.othersImages = response;
this.errors = '';
})
.catch((errors) => {
this.errors = errors;
});
},
},
};
</script>
I believe, the easiest way to handle that is applying one plugin based on npm package: https://www.npmjs.com/package/vue-masonry. That's the simple library with good supporting and small size.
<template>
<div data-masonry='{"percentPosition": true }' class="row">
<div class="full col-lg-4 half"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="half col-lg-4"></div>
<div class="full col-lg-4"></div>
<div class="full col-lg-4"></div>
</div>
</template>
<script>
export default {}
</script>
<style>
.row {
width: 80vw;
height: 600px;
background-color: green;
margin: auto;
}
.full {
height: 150px;
background-color: grey;
border: 1px solid black;
}
.half {
height: 75px;
background-color: grey;
border: 1px solid black;
}
</style>
You should add bootstrap and masonry cdn's to your projects, then simply adding
data-masonry='{"percentPosition": true }'
line to your row, masonry works automatically.
Check out this link for more info.
I am stuck making a modal component for my app in VueJS. I want to be able to put it in its own component for reusability, be able to pass custom content and have multiple modals.
I made the component and it looks like this from the VueJS docs:
Modal.vue
<template>
<div ref="modal">
<script type="text/x-template" id="modal">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
Header
</slot>
</div>
<div class="modal-body">
<slot name="body">
Body
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
Footer
</slot>
<button class="btn btn-primary" #click="$emit('close')">
Button
</button>
</div>
</div>
</div>
</div>
</transition>
</script>
</div>
</template>
<script>
export default {
components: { },
props: ['header', 'footer', 'body', 'button'],
data: () => ({
showModal: false
}),
methods: {
open () {
console.log('Opening modal')
this.showModal = true
}
}
}
</script>
<style>
#modal {
/*color: #000;*/
}
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
display: table;
transition: opacity .3s ease;
}
.modal-wrapper {
display: table-cell;
vertical-align: middle;
}
.modal-container {
width: 300px;
margin: 0px auto;
/*padding: 20px 30px;*/
background-color: #25262D;
color: #FEFEFE;
border-radius: 3px;
box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
transition: all .3s ease;
font-size: 1.2em;
}
.modal-header {
border-radius: 3px;
background-color: #202128;
border: none;
}
.modal-header h3 {
margin-top: 0;
color: #42b983;
}
.modal-body {
margin: 20px 0;
/*background-color: #202128;*/
border: none;
}
.modal-footer {
text-align: center;
border: none;
}
.modal-footer .btn {
font-size: 1.0em;
}
/*
* The following styles are auto-applied to elements with
* transition="modal" when their visibility is toggled
* by Vue.js.
*
* You can easily play with the modal transition by editing
* these styles.
*/
.modal-enter {
opacity: 0;
}
.modal-leave-active {
opacity: 0;
}
.modal-enter .modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>
I add a modal in my App.vue:
<button #click="openUpdatedModal()" type="button" class="btn btn-default" data-toggle="modal" data-target="#modal">
Launch Updated Modal
</button>
<modal ref="updatedModal" v-if="showModal" #close="showModal = false">
<!--
you can use custom content here to overwrite
default content
-->
<div slot="header">custom header</div>
</modal>
<script>
import Modal from './components/Modal'
export default {
components: { Modal },
data: () => ({
showModal: false
}),
methods: {
openUpdatedModal () {
this.$refs.updatedModal.open()
}
}
}
</script>
When I click the button I get the text in console "Opening modal" but nothing happens.
I can summon it and it works if I have ALL the code in App.vue
What am I missing?
I made it work by creating a ModalComponent.vue and removing the script tag as Phil suggested in the comments. Here's the code.
ModalComponent.vue:
<template>
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
default header
</slot>
</div>
<div class="modal-body">
<slot name="body">
default body
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
export default{
}
</script>
Here's how I defined my component:
Vue.component('modal', ModalComponent);
Modal button in markup:
<button id="show-modal" #click="showModal = true">Show Modal</button>
And the modal component being called on the page:
<modal v-if="showModal" #close="showModal = false">
<!--
you can use custom content here to overwrite
default content
-->
<h3 slot="header">custom header</h3>
</modal>
It's worth noting that I had to declare the showModal property wherever I use my modal.
Trying to build a website with some sliders.for slider i used SLICK slider.Here is my code .
<template>
<div class="homePopularVenue">
<div class="container">
<h2 class="text-center sub-headwords">POPULAR VENUE</h2>
<!--slider start-->
<div class="home-slider-popular-venue">
<div>
<div class="well">
<span class="half-image-temp">
<img class="img-rsponsive" src=" http://placehold.it/250x150" alt="">
</span>
<span class="half-content-temp">
<h3 class="title">HELLOW</h3>
<h5 class="small">Welcome to Hellow World</h5>
BOOK NOW
</span>
</div>
</div>
</div>
<div class="text-center">
VIEW ALL
</div>
</div>
</div>
</template>
<script>
export default {
name: 'homePopularVenue',
data () {
return {
posts: []
}
},
mounted() {
this.create();
this.$http.get('https://newsapi.org/v1/sources?language=en')
.then(response => {
console.log(response.data);
this.posts = response.data.source;
})
},
methods:{
create (){
$('.home-slider-popular-venue').slick({
slidesToShow: 4,
slidesToScroll: 1,
infinite: true,
dots: true,
autoplay: true,
autoplaySpeed: 2000,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: true
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 2,
slidesToScroll: 1
}
}
]
});
}
},
created: function(){
}
}
</script>
<style scoped>
.sub-headwords:after{
content:"";
width:200px;
background: #F99A13;
height: 4px;
display: block;
margin: auto;
margin-top: 15px;
margin-bottom: 30px;
}
.home-slider-popular-venue .well{
box-shadow: 2px 4px 8px 0 rgba(46,61,73,.2);
margin: 30px 10px;
transition: .2s ease-in-out;
}
.home-slider-popular-venue .well:hover{
box-shadow: 12px 15px 20px 0 rgba(46,61,73,.15);
}
.half-image-temp{
max-height: 250px;
}
.half-image-temp img{
width: 100%;
display: block;
margin: auto;
}
.half-content-temp{
}
</style>
Everything was good before i put the data dynamicaly in slider, after putting the data dynamically in slider its not working.
<template>
<div class="homePopularVenue">
<div class="container">
<h2 class="text-center sub-headwords">POPULAR VENUE</h2>
<!--slider start-->
<div class="home-slider-popular-venue">
<div v-for="post in posts">
<div class="well">
<span class="half-image-temp">
<img class="img-rsponsive" src=" http://placehold.it/250x150" alt="">
</span>
<span class="half-content-temp">
<h3 class="title">HELLOW</h3>
<h5 class="small">Welcome to Hellow World</h5>
<p> {{post.id}} </p>
BOOK NOW
</span>
</div>
</div>
</div>
<div class="text-center">
VIEW ALL
</div>
</div>
</div>
</template>
Also the same problem is happening with OWl.Carousel.