VueJs filters have no effect - javascript

Simple code example
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
<style>
</style>
</head>
<body>
<div id="app">
<h1>Bitcoin Price Index</h1>
<div v-for="currency in info">
{{ currency.description }}
<span v-html="currency.symbol"></span>{{ currency.rate_float || currencyToDeciaml }}
</div>
</div>
<script>
const app = new Vue({
el : '#app',
data : {
info : null,
},
filters : {
currencyToDeciaml(val) {console.log(`foo`);
return Number(val).toFixed(2);
}
},
// Dom is ready so now load the data
mounted() {
axios.get(`https://api.coindesk.com/v1/bpi/currentprice.json`)
.then(response => this.info = response.data.bpi);
},
});
</script>
</body>
</html>
I am trying to apply a simple filter currencyToDeciaml but it doesn't even get executed and foo does not display. I cannot seem to figure it out. Any help would be appreciated.

The correct syntax for filters is this:
{{ currency.rate_float | currencyToDeciaml }}
with only one pipe

Related

Using Vue components with props

I'm doing a Vue school course and I'm trying to do a little exercise with components and props. I'm trying to buid a simple button and paragraph component that takes the content of a paragraph as the prop's value:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Click-Counter</title>
</head>
<body>
<div id="app">
<h1>Vue.js Components Fundamentals</h1>
<click-counter click-title="The first counter is:"></click-counter>
<click-counter click-title="The second counter is:"></click-counter>
<click-counter click-title="The Third counter is:"></click-counter>
</div>
<script type="text/x-template" id="click-counter-template">
<div>
<p>{{ click-title }}</p>
<button v-on:click="count++"> {{ count }} </button>
</div>
</script>
<script src="https://unpkg.com/vue"></script>
<script src="app.js"></script>
</body>
</html>
app.js
Vue.component('click-counter', {
props: {
'click-title': {
type: String,
required: true
}
},
data () {
return {
count: 0
}
},
template: '#click-counter-template',
})
new Vue({
el: '#app'
})
The thing is that the content of the click-title prop is being evaluated but not rendered.
Screenshot of the Vue extension
Screenshot of the page's content
The problem was that, for Vue to understand that the prop in the app.js file and the index.html file are the same thing, you have to use camelCase in app.js (and when you define the component) and kebab-case in index.html (in the instances of the component).
In short, I changed this:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Some Head Info -->
</head>
<body>
<div id="app">
<h1>Vue.js Components Fundamentals</h1>
<!-- USE kebab-case HERE (click-title) -->
<click-counter click-title="The first counter is:"></click-counter>
<click-counter click-title="The second counter is:"></click-counter>
<click-counter click-title="The Third counter is:"></click-counter>
</div>
<script type="text/x-template" id="click-counter-template">
<div>
<!-- USE camelCase HERE (clickTitle) -->
<p>{{ clickTitle }}</p>
<button v-on:click="count++"> {{ count }} </button>
</div>
</script>
<!-- More stuff -->
</body>
</html>
app.js:
Vue.component('click-counter', {
props: {
// USE camelCase HERE (clickTitle)
'clickTitle': {
// Atributes
}
},
data () {
// Variables
},
// Template
})
// New Vue

Writing javascript code in a component using vue

I am trying to make a component using Vue for my javascript code but it does not work.
My main goal is to create a component with vue or Vue3
<head>
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
</head
<body>
<div id="app">
<myelement name="ibrahim" age="12"></myelement>
</div>
</body>
<script>
Vue.component("myelement",{
props:["name","age"], // for arguments
template:`
<h1> welcome to my vue component,<br> name :{{name }} and age : {{age}}</h1>
`// template where my code template should be
})
var vm = new Vue({ // creating an object from Vue
el:"#app" // bind my created code to the id "app"
})
</script>
This code is working, but when I put a Javascript code in instead of html code. I got an error
this code I am using for my Javascript code, but the vue is not calling my javascript code . It is just calling my html code
<head>
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
</head
<body>
<h3>this page works</h3>
<div id="app">
<myelement ></myelement >
</div>
</body>
<script>
document.write("<h1>Header from document.write()</h1>");
var temp = "<h1>Hello from vue veriable</h1>"
Vue.component("myelement ",{
template:`
<script>
alert(1);
document.write("<h1>Header from document.write()</h1>");
</script>
`// template where my code template should be
})
var vm = new Vue({ // creating an object from Vue
el:"#app" // bind my created code to the id "app"
})
</script>
what I want to do is, when I create the tag in the page then the alert(1) will show up.
In vue, you cannot use script tag in template of components and you get below error:
[Vue warn]: Error compiling template: Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed.
Instead you can put your javascript codes in created lifecycle hook. This hook is called when your component create:
<head>
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
</head>
<body>
<h3>this page works</h3>
<div id="app">
<myelement></myelement>
</div>
</body>
<script>
Vue.component("myelement", {
template: `<h2>Hello</h2>`,
});
var vm = new Vue({
el: "#app",
created() {
alert(1);
document.write("<h1>Header from document.write()</h1>");
},
});
</script>
I'm not sure but I think this code will work correctly:
<head>
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
</head>
<body>
<h3>this page works</h3>
<div id="app">
<myelement :message="variableAtParent"></myelement>
</div>
</body>
<script>
Vue.component("myelement", {
props: ['message'],
template: '<p>At child-comp, using props in the template: {{ message }}</p>',,
});
var vm = new Vue({
el: "#app",
data: {
variableAtParent: 'DATA FROM PARENT!'
}
});
</script>

VueJS Nested Builder Example

I'm new to VueJS and am trying to make a small page builder application where you can create sections and add subsections to each of those. I'm not sure how to setup the Vue data property to allow this. Any insight on how you would go about doing something like this would be appreciated. Here's my code so far:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<div id="app">
<form>
<input type="text" v-model="title"> {{title}}<br>
<button type="button" v-on:click="addSection()">Add Section</button>
</form>
<h1>Sections</h1>
<div v-for="(section, index) in sections">
<h2>{{section.title}}</h2>
<form>
<input type="text" v-model="subTitle"> {{subTitle}}<br>
<button type="button" v-on:click="addSubSection()">Add SubSection</button>
</form>
<div v-for="(subsection, index) in subsections">
<h3>{{subsection.subTitle</h3>
</div>
</div>
</div>
<script src="js/vue.min.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
title: '',
sections: []
},
methods: {
addSection: function(e) {
this.sections.push({title: this.title});
this.title = '';
},
addSubSection: function(sectionIndex) {
this.sections[sectionIndex].push({subTitle: this.subTitle});
this.subTitle = '';
}
}
});
</script>
</body>
Each of your sections is an object, not an array so this.sections[sectionIndex].push() won't work. You should probably add a sections property to each new section, eg
this.sections.push({ title: this.title, sections: [] })
and when adding a sub-section
this.sections[sectionIndex].sections.push({ subTitle: this.subTitle })
You should also have a data property for subTitle

Mustache not rendering JSON data

So, I have just started with Mustache JS. I have this simple html file
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript Mustache template</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
</head>
<body>
<script id="mp_template" type="text/template">
<p>Country: {{ name }}</p>
<p>Capital: {{ capital }}</p>
<p>Flag: <img src={{{ flag }}} ></p>
</script>
<div id="mypanel"></div>
<button id="btn">Load</button>
<script>
$(function () {
$("#btn").on('click', function () {
$.getJSON('https://restcountries.eu/rest/v2/name/aruba?fullText=true', function (data) {
var template = $("#mp_template").html();
var text = Mustache.render(template, data);
console.log(data);
$("#mypanel").html(text);
});
});
});
</script>
Its getting some data back via the .getJSON call and then trying to render that data on button click. No data is rendering. Can someone please advise what am I doing wrong ?
Please see this URL to see the structure of returned data https://restcountries.eu/rest/v2/name/aruba?fullText=true
That API returns a JSON array, not an object, that's why it isn't working.
If you only want the first item, you can do:
var template = $("#mp_template").html();
var text = Mustache.render(template, data[0]);
console.log(data);
$("#mypanel").html(text);
Or you can iterate through all the countries, by passing the array in an object property: { countries: data } and use {{#countries}} in your template
$(function () {
$("#btn").on('click', function () {
$.getJSON('https://restcountries.eu/rest/v2/name/aruba?fullText=true', function (data) {
var template = $("#mp_template").html();
var text = Mustache.render(template, { countries: data });
$("#mypanel").html(text);
});
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
</head>
<body>
<script id="mp_template" type="text/template">
{{#countries}}
<p>Country: {{ name }}</p>
<p>Capital: {{ capital }}</p>
<p>Flag: <img src={{{ flag }}} style="width: 50px"></p>
{{/countries}}
</script>
<div id="mypanel"></div>
<button id="btn">Load</button>
</body>

How do I swap content

how can I swap content of a div with Vue.js? I think I lack general lifecycle knowledge. Here is what I´ve got so far. After all I need to swap between two Vue-instances and ´d like to use only one lightbox container for them.
Here is what I´ve got so far: http://jsbin.com/qokerah/edit?html,js,output
HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.16/vue.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<script type="x-template" id="foo-template">
<div class="text">{{ fooText }}</div>
<div class="confirm" v-if="fooConfirm">confirmed</div>
</script>
<script type="x-template" id="bar-template">
<div class="heading">{{ barHeading }}</div>
<div class="info">{{ barInfo }}</div>
</script>
<div class="foo">
<div class="btn btn-primary" v-on:click="swapLightboxContent">Open foo template</div>
</div>
<div class="bar">
<div class="btn btn-primary" v-on:click="swapLightboxContent">Open bar template</div>
</div>
<div class="lightbox">
<div class="lightbox-content">Show foo- or bar-template</div>
</div>
</body>
</html>
JS
var foo = new Vue({
el: '.foo',
data: {
fooText: 'text',
fooConfirm: false
},
methods: {
swapLightboxContent: function () {
console.log('Show foo-template');
}
}
});
var bar = new Vue({
el: '.bar',
data: {
barHeading: 'text',
barInfo: 'text'
},
methods: {
swapLightboxContent: function () {
console.log('Show bar-template');
}
}
});
Ok, my main misconception where:
I Used var foo and bar as new Vue() instances without having a parent "intersection" instance
so this is now working:
http://jsbin.com/tiwoco/edit?html,js,output
Still need to figure out if accessing the currentView item through vmFoo and vmBar instances shouldn´t be done in foo and bar components :)

Categories

Resources