set global one component vue for use anywhere - javascript

I'm working whit laravel and I have installed component vue. https://github.com/dalphyx/vue-top-progress
I will like to use this component into different pages and other components.
I don't know how to set global, for use other components or pages blade. laravel.
app.js
require('./bootstrap');
window.Vue = require('vue');
Vue.component('crud1', require('./components/crud1.vue').default);
Vue.component('crud2', require('./components/crud2.vue').default);
import { vueTopprogress } from 'vue-top-progress';
const app = new Vue({
el: '#app',
mounted(){
this.$refs.topProgress.start()
setTimeout(() => {
this.$refs.topProgress.done()
}, 2000)
},
components: {
vueTopprogress
}
});
home.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>home</title>
</head>
<body>
<div class="wrapper" id="app">
<vue-topprogress ref="topProgress"></vue-topprogress>
<crud1></crud1>
</div>
<script src="app.js"></script>
</body>
</html>
crud1.vue
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">crud 1 Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
this.$refs.topProgress.start()
setTimeout(() => {
this.$refs.topProgress.done()
}, 2000)
}
}
if I use "this.$refs.topProgress.start()" on crud1 I get this error
app.js:41686 [Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'start' of undefined"
found in
---> <crud1> at resources/js/components/crud1.vue
<Root>

Related

In Vue2.7, v-slot is not available, how to solve the problem?

When I run the following code, I get the following results (Google Chrome running screenshot).
<!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>17-Learning of Scoped Slots and Named Slots</title>
<style>
.h1Class{
color:red;
}
</style>
</head>
<body>
<div id="div_new">
<h1 class="h1Class">first set</h1>
<cpn></cpn>
<h1 class="h1Class">second set</h1>
<cpn>
<!-- first method -->
<template slot="slotName" slot-scope="planallScope">
<!-- second method after Vue2.6 -->
<!-- <template v-slot:slotName="planallScope" > -->
<h4>{{planallScope.planall[0]}}</h4>
<h4>{{planallScope.planall[1]}}</h4>
<h4>{{planallScope.planall[2]}}</h4>
</template>
</cpn>
</div>
<template id="template_div">
<div>
<slot v-bind:planall="plan" name="slotName">
<ul>
<li v-for="item in plan"> {{ item }}</li>
</ul>
</slot>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue#2.7.7/dist/vue.js"></script>
<script>
const templateDivText = {
template: '#template_div',
data() {
return {
plan: ['C#', 'Java', 'JavaScript']
}
},
}
const app_new = new Vue({
el: '#div_new',
components: {
'cpn': templateDivText,
},
})
</script>
</body>
</html>
The running result is as follows:
enter image description here
When I use v-slot, the code is as follows:
<!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>17-Learning of Scoped Slots and Named Slots</title>
<style>
.h1Class{
color:red;
}
</style>
</head>
<body>
<div id="div_new">
<h1 class="h1Class">first set</h1>
<cpn></cpn>
<h1 class="h1Class">second set</h1>
<cpn>
<!-- first method -->
<!-- <template slot="slotName" slot-scope="planallScope"> -->
<!-- second method after Vue2.6 -->
<template v-slot:slotName="planallScope" >
<h4>{{planallScope.planall[0]}}</h4>
<h4>{{planallScope.planall[1]}}</h4>
<h4>{{planallScope.planall[2]}}</h4>
</template>
</cpn>
</div>
<template id="template_div">
<div>
<slot v-bind:planall="plan" name="slotName">
<ul>
<li v-for="item in plan"> {{ item }}</li>
</ul>
</slot>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue#2.7.7/dist/vue.js"></script>
<script>
const templateDivText = {
template: '#template_div',
data() {
return {
plan: ['C#', 'Java', 'JavaScript']
}
},
}
const app_new = new Vue({
el: '#div_new',
components: {
'cpn': templateDivText,
},
})
</script>
</body>
</html>
The running result is as follows:
enter image description here
So in Vue2.7, v-slot is not available, how to solve the problem?
Your syntax is correct, except one little detail: you can't use camelCase for slot names.
To be fair, I don't precisely know why, it has to do with template compilation and with the fact the slot names get parsed as element attributes in <template v-slot:slot-name"scope">. Vue's styling guideline does strongly advise on using kebab-case for attributes, directives and the likes, when used in templates or JSX.
However, name="slotName" + <template #slot-name="scope"> doesn't seem to work for slots.
In short, name="slotName" (+ <template #slotName="scope") does not work, but name="slot-name" (+ <template #slot-name="scope") does.
See it working, in Vue 2.7.7:
const templateDivText = Vue.defineComponent({
template: '#template_div',
data() {
return {
plan: ['C#', 'Java', 'JavaScript']
}
},
})
const app_new = new Vue({
el: '#div_new',
components: {
'cpn': templateDivText,
},
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.7.7/dist/vue.min.js"></script>
<div id="div_new">
<cpn>
<template #slot-name="{planall}">
<h4>{{planall[0]}}</h4>
<h4>{{planall[1]}}</h4>
<h4>{{planall[2]}}</h4>
</template>
</cpn>
</div>
<template id="template_div">
<div>
<slot name="slot-name" :planall="plan">
<ul>
<li v-for="item in plan"> {{ item }}</li>
</ul>
</slot>
</div>
</template>
Notes:
:planAll="" is shorthand for v-bind:planAll=""
<template #slot-name=""> is shorthand for <template v-slot:slot-name="">
when you only have one slot, you can remove the slot name altogether (it defaults to name="default")

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

Uncaught SyntaxError: The requested module does not provide an export named

i've got this error in my console
Uncaught SyntaxError: The requested module './components/tileHeader/controller.js' does not provide an export named 'tileHeader'
this is my code
components/tileHeader/controller.js:
Vue.component('tileHeader',{
template: '#tileHeader',
data(){
return{
count:0
}
},
})
components/tileHeader/view.html:
<script type="text/x-template" id="tileHeader">
<div class="container">
<div class="row">
<div class="col">
<!--<div v-show="item.label != null || item.label == undefined"
class="label">{{item.label}}</div>
<img v-show="item.image != null" src="item.image"/>-->
<p>This is a Test</p>
</div>
</div>
</div>
</script>
main.js:
import Vue from './vue.js';
import { tileHeader } from './components/tileHeader/controller.js';
new Vue({
el: '#app',
components: {
'tileHeader': tileHeader
},
})
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Vue X-Templates</title>
</head>
<body>
<div id="#app"></div>
<script type="module" src="main.js"></script>
</body>
</html>
i'm working with x-templates.
this is my project structure:
structure
Could you try something like this ?
Create a single file that will contain your html / css and js.
tileHeader.vue :
<template>
<!-- Your view.html -->
</template>
<script>
export default {
name: 'tileHeader',
}
</script>
<style scoped>
</style>
Since the file has a export default, you'll be able to import it in another file
Add to main.js :
import tileHeader from "./components/tileHeader.vue";

VueJs filters have no effect

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

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