Vue - Add CDN component without webpack - vue.js

I want to add this component to my Vue.js project without using webpack.
I've tried adding this to the head:
<script src="https://cdn.jsdelivr.net/npm/vuejs-auto-complete#0.9.0/dist/build.js"></script>
And this to the body:
<autocomplete :source="[{id:1,name:'abc'},{id:2,name:'def'}]"></autocomplete>
But the following error happens:
[Vue warn]: Unknown custom element: autocomplete - did you register the component correctly? For recursive components, make sure to provide the "name" option.
What should I do?
Here's the link to the component on Github.

You need to register that component first like below
components: {
Autocomplete: window["vuejs-autocomplete"]
}
Example
new Vue({
el: '#app',
components: {
Autocomplete: window["vuejs-autocomplete"]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuejs-auto-complete#0.9.0/dist/build.js"></script>
<div id="app">
<autocomplete :source="[{id:1,name:'abc'},{id:2,name:'def'}]"></autocomplete>
</div>

Have you registered it in Vue.components(); in your main.js ?

Related

VueJs: bind `v-on` on a custom component to replace an existing one

In order to ease the styling of my page, I'd like to create a bunch of mini components like, and exploit how attributes are merged in VueJs. So for example, here is a minimal js file also hosted on this JSFiddle:
Vue.component('my-button', {
template: '<button style="font-size:20pt;"><slot></slot></button>'
})
var app = new Vue({
el: "#app",
data: {
message: "world",
},
methods: {
sayHello: function () {
alert("Hello");
}
}
})
and then in my html I just want to use <my-button> instead of button:
<div id="app">
Hello {{message}} <my-button #click="sayHello" style="color:red;">Style works, but not click</my-button> <button v-on:click="sayHello" style="color:red;">Both works</button>
</div>
Unfortunately, it seems that attributes are merged, but not listeners, so it means that I can't do v-on:click on my new button... Any way to make it possible?
Thanks!
-- EDIT --
I saw the proposition of Boussadjra Brahim of using .native, and it works, but then I found this link that explains why it's not a great practice and how to use v-on="$listeners" to map all listeners to a specific sub-button. However, I tried, to just change my template with:
template: `<button style="font-size:20pt;" v-on="$listeners"><slot></slot></button>`,
but I get an error:
Vue warn: Property or method "$listeners" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option."
Here is the JSFiddle.
Your fiddle didn't work because you were using an old version of Vue, $listeners was added in Vue 2.4.0.
Here's a demo:
Vue.component('my-button', {
template: '<button style="color: red" v-on="$listeners"><slot/></button>'
})
new Vue({
el: '#app',
methods: {
sayHello() {
alert('Hello')
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<my-button #click="sayHello">Custom Button</my-button>
<button #click="sayHello">Ordinary Button</button>
</div>

VueJs component using CDN link without npm

Want to use Laravel Vue Pagination
HTML
<ul>
<li v-for="user in users.data" :key="user.id">{{ user.name }}</li>
</ul>
<pagination :data="users" #pagination-change-page="getUsers"></pagination>
Vue/Js
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/laravel-vue-pagination#2.3.1/dist/laravel-vue-pagination.umd.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
users: [],
},
mounted() {
this.getUsers();
},
methods: {
getThoughts(page = 1) {
axios.get('/api/users?page=' + page)
.then(response => {
this.users = response.data;
});
}
}
});
</script>
Problem:
Loop is working fine when using the pagination component gives me the following error.
Error
[Vue warn]: Unknown custom element: <pagination> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
Tried
Vue.component('pagination', require('laravel-vue-pagination'));
Gives me following error
Uncaught ReferenceError: require is not defined
You are loading a component using UMD modules. When loading a UMD module through script tag, the module gets added to the window object. You can access it using window['module-name']. Then you need to register the component in Vue object just like u would do it normally.
In your case you need to add:
components: {
pagination: window['laravel-vue-pagination']
},
to your Vue component so umd module laravel-vue-pagination will be registered and ready to use inside template.

vue-js / asp.net core - ERROR : did you register the component correctly?

I'm rather new to vue.js, so forgive me if it this is an uts-question :-)
The project is a asp.net core project were we integrated vue.js as a means to enrich the user-experience. In the past we used jQueru/jQueryUI. Given the ease of working we switched to vue.
I want to use this nice color picker component I downloaded from here https://www.npmjs.com/package/vue-swatches#install
I included the .js and .css file to my page and in my script I have already added successfully other components but the same method does not work for this one.
<div id="appointmentsvue" class="row">
<select v-model="selectedCareprovider" v-on:change="onSelectedCareproviderChanged" class="form-control">
<option v-for="careprovider in careproviders" v-bind:value="careprovider">
{{careprovider.FullName}}
</option>
</select>
<v-colorpicker v-model="selectedColor"></v-colorpicker>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="/lib/vue-select/vue-select.css" />
<script src="/lib/vue-select/vue-select.js"></script>
<link rel="stylesheet" href="/lib/vue-swatches/vue-swatches.min.css" />
<script src="/lib/vue-swatches/vue-swatches.min.js"></script>
<script>
let appointmentsvue = new Vue({
el: '#appointmentsvue',
components: {
'v-colorpicker': VueSwatches.VueSwatches // https://saintplay.github.io/vue-swatches/
},
data: {
selectedColor: '#AABBCC',
careproviders: [],
selectedCareprovider: {},
},
methods: {
onSelectedCareproviderChanged: function () {
},
updateCareprovider: function () {
},
}
});
</script>
I get this error after loading the page.
[Vue warn]: Unknown custom element: - did you register
the component correctly? For recursive components, make sure to
provide the "name" option.
Any suggestions ?
I did not found a true answer that allowed me just to add the javascript files to my html pages and use those components.
I found a working solution by introducing webpack, usefull resources :
webpack beginners guide
vuejs and webpack from scratch
webpack and aps.net core
On the git-pages of this component I got a solution :
https://github.com/saintplay/vue-swatches/issues/37
A solution I used for other components too.

Dynamic x-templates in Vue components

I have this component, and would like to pass a parameter/prop to the component saying which x-template to use. When I do it like this, it fails:
JS:
Vue.component('custom-table', {
props: ['template'],
template: '#' + this.template
})
new Vue({ el: '#app' })
HTML:
<custom-table template="my-template"></custom-table>
<script type="text/x-template" id="my-template">
<p>My Template</p>
</script>
Error:
vue.js:3 [Vue warn]: Cannot find element: #undefined
How can I use dynamic templates like this?
I'm not sure whether this is actually a good idea but it does come pretty close to what you've requested:
Vue.component('custom-table', {
props: ['template'],
template: `<component :is="{ template: '#' + template }" />`
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue#2.6.10/dist/vue.js"></script>
<script type="text/x-template" id="button-template">
<button>My Template</button>
</script>
<script type="text/x-template" id="em-template">
<em>My Template</em>
</script>
<div id="app">
<custom-table template="button-template"></custom-table>
<custom-table template="em-template"></custom-table>
</div>
The trick here is to use the object version of is, which allows you to pass in a component definition inline. Strictly speaking there are two components in play here, a parent and a child, and the x-template is assigned to the child. That said, the resulting DOM should be as desired as the parent doesn't add any extra elements of its own.
You can't have dynamic templates for a single component.
You could create various components, and then dynamically pick which component to render for the particular tag. For this, Vue supports dynamic component:
<component v-bind:is="currentTabComponentName"></component>
Alternatively, if you want caller to fill-in-the-blanks of your component with arbitrary HTML, then you can use slots.
Or, if it is just static HTML, then you can just pass the HTML itself as string, and render the content without escaping it:
<div v-html="task.html_content"> </div>
Maybe one of these works for you...
Other options could be to use render functions or JSX.

Trying to use ref inside a Vue single file component. Got undefined

I'm beginning with vuejs and I try to figure what could be done about reference of child component instance in root instance. I used ref attribute and it works pretty well, except if I use it in a single file component (in the template tags). In this specific case, I get 'undefined'.
So, I try to understand why, because it could be very useful for establishing dynamic references. I could probably bypass that situation easily, but I would like to understand the problem instead of run away.
So if someone have an idea ;)
I am using webpack to import my single file component in my app.js and compiled it. However the template compilation isn't done by webpack, but by the browser at runtime (maybe it's the beginning of an explanation ?).
My app is very simple, and I log my references on click on the header, so I don't think it's lifecylce callback related.
Here is my files :
app.js
import Vue from 'Vue';
import appButton from './appButton.vue';
import appSection from './appSection.vue';
var app = new Vue({
el: '#app',
components:
{
'app-button' : appButton
},
methods:
{
displayRefs: function()
{
console.log(this.$refs.ref1);
console.log(this.$refs.ref2);
console.log(this.$refs.ref3);
}
}
});
my component appButton.vue
<template>
<div ref="ref3" v-bind:id="'button-'+name" class="button">{{label}}</div>
</template>
<script>
module.exports =
{
props: ['name', 'label']
}
</script>
my index.html body
<body>
<div id="app">
<div id="background"></div>
<div id="foreground">
<img id="photo" src="./background.jpg"></img>
<header ref="ref1">
<h1 v-on:click="displayRefs">My header exemple</h1>
</header>
<nav>
<app-button ref="ref2" name="presentation" label="Qui sommes-nous ?"></app-button>
</nav>
</div>
</div>
<script src="./app.js"></script>
</body>
ref1 (header tag) and ref2 (app-button tag) are both found. But ref3 (in my single file component) is undefined. Also
Thanks for all the piece of answer you could give me, hoping it's not a silly mistake.
A ref you set is only accessible in the component itself.
If you try to console.log(this.$refs.ref3); into a method from appButton.vue, it will work. But it won't work in the parent.
If you want to access that ref from the parent, you need to use the $ref2 to access the component, and then use the $ref3. Try this:
var app = new Vue({
el: '#app',
components:
{
'app-button' : appButton
},
methods:
{
displayRefs: function()
{
console.log(this.$refs.ref1);
console.log(this.$refs.ref2);
console.log(this.$refs.ref2.$refs.ref3); // Here, ref3 will be defined.
}
}
});
Accessing some child ref from the parent is not supposed to be a good practice tho.