Vuetify, if query parameter exists, show element? - vue.js

When the form is submitted i want the second v-card to display. I want second v-card to only display if query parameter term exists..
<v-card class="logo py-4 d-flex justify-center">
<form>
<input type="search" name="term" id="term" placeholder="Search">
<input type="submit" value="Go">
</form>
</v-card>
<v-card v-if="this.$route.query.term != ''">
Test
</v-card>
When i try this, the second v-card always displays regardless of query parameter.
How do i solve?

Your code should work, I did not see any issue in that. Perhaps you could cross-check the this.$route.query.term value? Anyhow, I just created a working demo for you.
Demo :
const Foo = {
template: `<div><v-card class="green">
First Card
</v-card>
<v-card class="yellow" v-if="this.$route.query.term !== ''">
Second Card
</v-card></div>`
}
const router = new VueRouter({
routes : [
{path: '/foo', component: Foo}
]
});
new Vue({
el:'#app',
router
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.3.0/vue-router.min.js"></script>
<script src="https://unpkg.com/vuetify#0.14.8/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#0.14.8/dist/vuetify.min.css"/>
<div id="app">
<router-link :to="{path:'/foo',query:{term:'abc'}}">Show cards</router-link>
<router-view></router-view>
</div>
Right now this demo is showing both the cards as term query param value is not empty but you can play around with this code by changing the term query param value.

Related

Add animation to append-icon in v-text-field

When a new account is registered, I display login and password details on the screen. The user can copy login&passwod details to clipboard and I would like to run animation when the append-icon (scale up, increase font or replace with another icon) is clicked. What would be the right way to do that?
<template>
<v-card class="col-12 col-md-8 col-lg-6 p-6 px-16" elevation="4">
<div class="title h2 mb-10 text-uppercase text-center">
Success
<v-icon color="green" x-large>
mdi-check-circle
</v-icon>
</div>
<v-text-field
:value="newAccount.login"
label="Login"
outlined
readonly
append-icon="mdi-content-copy"
ref='login'
#click:append="copy('login')"
></v-text-field>
<v-text-field
:value="newAccount.password"
label="Password"
outlined
readonly
append-icon="mdi-content-copy"
ref='login'
#click:append="copy('login')"
></v-text-field>
</v-card>
</template>
<script>
methods: {
copy(field) {
const input = this.$refs[field].$refs.input
input.select()
document.execCommand('copy')
input.setSelectionRange(0,0)
// apply append-icon animation
}
}
</script>
There is multiple answers to this, but to answer one of them: "replacing icon" would be pretty straight forward.
You would have to change the append-icon prop do be dynamic :, then assign a variable to it like copyIcon. You will then update this variable depending on the state of the copy.
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
copyIcon: 'mdi-content-copy',
newAccount: {
login: 'GhostDestroyer69',
password: '',
},
},
methods: {
copy(field) {
const input = this.$refs[field].$refs.input
input.select()
document.execCommand('copy')
input.setSelectionRange(0, 0)
// Set icon to check
this.copyIcon = 'mdi-check'
// Reset icon to copy after 1 second
setTimeout(() => {
this.copyIcon = 'mdi-content-copy'
}, 1000)
}
}
})
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-card class="col-12 col-md-8 col-lg-6 p-6 px-16" elevation="4">
<v-text-field
:value="newAccount.login"
label="Login"
outlined
readonly
:append-icon="copyIcon"
ref='login'
#click:append="copy('login')"
></v-text-field>
</v-card>
</div>
mdi has animation helpers like
append-icon="mdi-content-copy mdi-spin"
For example.

How to add a class and then remove that same class in the vuejs?

I have the following div:
<div class="col bg-color-red-4">
<a href="#" v-on:click="showMobileMenu = !showMobileMenu">
<i class="hamburger hamburger--3dx " v-bind:class="{ 'is-active': showMobileMenu }" >
<span class="hamburger-box">
<span class="hamburger-inner"></span>
</span>
</i>
</a>
<p>3DX</p>
</div>
data(){
return {
showMobileMenu: false
}
},
That is visually like this:
basically it's a button that allows me to open the left panel:
When you click on the button you add the class 'is-active' that allows the change of form, leaving it like this:
and it effectively opens the left panel, but after turning off the left panel, that is, returning to the view that I was in, this one finds the class added.
then I need that when I click, I change the shape to an "X", when I open the left panel, but when I come back I do not have the form "X", that is, it does not contain the class 'is-active' anymore
Beforehand thank you very much.
At first read the official docs:
[https://v2.vuejs.org/v2/guide/class-and-style.html#ad][1]
At second - check Matt Oestreich's answer
At third - you can also bind classes to the variables like this:
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
/>
And in a Vue.js script:
data: {
isActive: true,
hasError: false
}
You can bind to the class attribute and supply specific classes that way..
[CodePen Mirror]
Code Snippet:
const vm = new Vue({
el: "#app",
data: {
status: false,
bars: "fa fa-bars",
times: "fa fa-times",
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.14/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/font-awesome#4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.6/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app>
<v-content>
<v-container>
<i
style="cursor:pointer;"
:class="status ? times : bars"
#click="status = !status"
></i>
<h1>Click The Icon</h1>
<h3>It is currently {{ status ? 'open' : 'closed' }}</h3>
</v-container>
</v-content>
</v-app>
</div>

vue: v-else does not completely show context

I am new to Vue. When I use v-if, v-else-if, and v-else, the first two tags work well. But for v-else, it only change the context in {{}}.
html:
<div id="app">
<div v-if="isIf === 1">
isIf is 1:{{isIf}}
</div>
<div v-else-if="2">
isIf is 2:{{isIf}}
</div>
<div v-else>
isIf is not 1 or 2:{{isIf}}
</div>
</div>
js:
<script>
var app = new Vue({
el: '#app',
data: {
isIf: 1,
isShow: false
}
});
</script>
when I change the app.isIf=3 in console, it showed isIf is 2: 3. My last try is app.isIf=2, so it showed the context with last input. Any idea?
Your v-else-if condition is wrong - instead of
<div v-else-if="2">
it should be
<div v-else-if="isIf === 2">
Except for zero, any numerical value will be considered "true" in Javascripts. So your render logic is always around "v-if" and "v-else-if", it never reaches "v-else"

VueJS Modal component inside component

I have a component like this:
<test></test>
I declare this as follows:
Vue.component('test', {
data: {
showModal: true
},
methods: {
displayComponentModalDialog: function() {
this.showModal = true;
}
},
template: `<button #click='displayComponentModalDialog'>test</button>`
});
The <test></test> component is then placed somewhere inside the <div id="#app"> wrapper.
var app = new Vue({
router,
el: '#app',
// etc.
})
Now, I want to display another component inside the test component. So in this case I want a dialog to appear after I click the button in test component. I am not able to achieve this.
What I did is adding a new component:
Vue.component('dialog', {
template: '#dialog-template'
});
And then the following code, although I do not know for sure where to put it.
<!-- template for the modal component -->
<script type="text/x-template" id="dialog-template">
<transition name="dialog">
<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">
<button class="btn btn-primary" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</script>
<!-- use the modal component, pass in the prop -->
<dialog v-if="showModal" #close="showModal = false">
<h3 slot="header">header</h3>
<p slot="body">
test
</p>
</dialog>
I tried putting this code inside the <test></test> but doesn't work. If I put it inside the template attribute in the component structure, it complains about only one root element.
So it is clear I miss some basic conception how this actually works in VueJS. Someone can help me clarify? Thanks.
As far as I can see your component indeed doesn't have a root tag. Templates have to have a root tag.
This is NOT a valid Vue template:
<div>
<h1>Stuff</h1>
</div>
<h2>Other stuff</h2>
This IS a valid Vue template:
<div>
<div>
<h1>Stuff</h1>
</div>
<h2>Other stuff</h2>
</div>
Note that in the second version we have a single root element for the template, a <div>, whereas in the first one we do not.
You have both a <script></script> and a <dialog></dialog> in your component template.
if you want to add another component in your test component . you can use slot on it.
You can refer to this documentation: https://v2.vuejs.org/v2/guide/components-slots.html
Example:
//component 1
<template>
<div id="modal">
// do something for your modal here.
<slot></slot> // reserve area for your another html or component.
</div>
</template>
// component 2
<template>
<your-modal-component>
<another-component>
</your-modal-component>
</template>

Can't get the correct value of scrollHeight for a textarea - VueJs, Vuetify

Am trying to get the value scrollHeight of a texteara filed, the problem is when i use the document object : document.querySelector("#textarea-element").scrollHeight, i have a correct value ,
but when i’ve tried to do it with refs the value is wrong and didn’t change.
I’ve made a detailed jsfiddle for these behaviors please see below:
new Vue({
el: '#app' ,
data: {
height: 'auto',
scrollHeightUsingRefsVuejs:'',
scrollHeightUsingDocumentObject: ''
},
methods:{
resizeTextarea (e) {
this.scrollHeightUsingRefsVuejs = this.$refs.messageBox.$el.scrollHeight
this.scrollHeightUsingDocumentObject = document.querySelector("#textarea-element").scrollHeight
console.log(this.scrollHeightUsingRefsVuejs, this.scrollHeightUsingDocumentObject)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link href="https://unpkg.com/vuetify#1.0.11/dist/vuetify.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vuetify#1.0.11/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-content>
<v-container>
<v-text-field
color="cyan darken"
label="Text field"
multi-line
rows="2"
placeholder="Start typing..."
ref="messageBox"
#keydown.native="resizeTextarea"
:style="{height: height}"
id="textarea-element"
></v-text-field>
<p>
Scroll Height Using Refs Vuejs : <strong>{{ scrollHeightUsingDocumentObject}}</strong>
</p>
<p>
<span style="color:red">(Wrong)</span> Scroll Height Using Refs Vuejs : <strong>{{ scrollHeightUsingRefsVuejs }}</strong>
</p>
</v-container>
</v-content>
</v-app>
</div>
(To see the value of scrollHeight type anything if the textearea filed)
The this.$refs.messageBox.$el.scrollHeight refers to parent node input-group generated by Vuetify that’s way the value seems wrong , all we need just to add a selector to tearea node like this this.$refs.messageBox.$el.querySelector('textarea').scrollHeight