Can't create custom Vue component in JSFiddle - javascript

In my JSFiddle example, I'm trying to define a custom Vue component: https://jsfiddle.net/50wL7mdz/402951/ .
Unfortunately, nothing is rendered. Why?
The code:
HTML:
<script src="https://unpkg.com/vue"></script>
<blog-post title="hi again!"></blog-post>
JS:
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})

You forgot to create a Vue. Wrap the <blogpost> component into a div and create a Vue using that div as the template.
Like so
HTML:
<script src="https://unpkg.com/vue"></script>
<div id="app">
<blog-post title="hi again!"></blog-post>
</div>
JS
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
el: '#app'
});
Look at the documentation documentation
Here is the working fiddle

My friend I recommend you another option, that I preferred. Please use, if you want, sandbox where you can add or modify components much much easier.
Here is the sandbox link.

Related

Hiding the main div in children component Vue

Is there any way to hide the main div in a Vue app that is builded by Vue-CLI? I have tried appending display property but it didn't resolve the issue. I am trying to hide it inside the Channels component of mine. My main component looks like this :
<template>
<div id="app">
<Channels/>
</div>
</template>
<script>
import Channels from './components/Channels'
export default {
name: 'App',
components: {
Channels
}
}
</script>
You can use <template> tag.
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<template>
<p>
Am I wrapped around Div or Template?
</p>
</template>
</div>
<script>
new Vue({
el: "#app"
})
</script>
You can inspect the parent of p tag in developer tools. It is div instead of template
you mean <div id="app">?, you can delete it directly, but you should maintain that three is only one root in <template>

who is the child and which is the parent in vue.js

I'm quite new in Vue.js. I do some simple exercises about communication between Vue components. But I still have a problem who is a child and who is a parent. For example I have this code:
HTML:
<body>
<div id="root" class="component">
<coupon #applied="onCouponApplied"></coupon>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.css"
/>
<!-- <script src="app.js"></script> -->
<script src="main.js"></script>
</body>
VUE.JS:
Vue.component("coupon", {
template: `
<div>
<input palceholder="Put your name" #blur="onCouponApplied"/>
</div>
`,
data() {
return {
message: ""
};
},
methods: {
onCouponApplied() {
this.$emit("applied");
}
}
});
new Vue({
el: "#root",
methods: {
onCouponApplied() {
alert("that's work!");
}
}
});
So.. here I have component coupon and new Vue. I guess that the new Vue is a parent. But... I try to understand, how it is work. Can anyone explain to me very simply how it works? I read the vue.js documentation, but still have a problem :/
All components refer to the Vue instance you mentioned. So your coupon component is a child of your root div. The parent component is the component that embeds another component.
A "UserListView" would have a list component which embeds user components. The view is the parent of the list and the list could be the parent of the user components.
Your whole app consists of components. Every Vue app has at least one component that is the parent component (Vue instance).
Every other component that you make becomes either direct or indirect child of the Vue instance.
From official docs:
A Vue application consists of a root Vue instance created with new
Vue, optionally organized into a tree of nested, reusable components.
The root div is the parent. You are creating a new Vue instance ( new Vue({ ) and associating it with the div element tagged with an id of 'root' ( el: "#root", ). The coupon component is contained within this div element, making it a child.

Clean separation of view and code with Vue using templates

I hope this is a trivial problem for someone and I am just missing a tiny magic piece of code: I am migrating from knockout.js to vue.js and I am wondering if there is a simple way to use templates the same way in vue.js as in knockout.js. The following code snipped uses knockout.js and works as expected:
function viewmodel() {
this.person = ko.observable(new person());
}
function person() {
this.first = ko.observable('hello');
this.last = ko.observable('world');
}
ko.applyBindings(new viewmodel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/html" id="person-template">
<p data-bind="text: first"/>
<p data-bind="text: last"/>
</script>
<div>
<div data-bind="template: { name: 'person-template', data: person }"/>
</div>
However, I can't figure out how to achieve the same in vue.js. I am aware of components in vue.js and all that, but I want to keep the structure as it is and not put more view-specific code into my JavaScript files. (I am already not happy with the el: '#app', but that's my least concern at the moment) Of course this code doesn't work:
var app = new Vue({
el: '#app',
data: {
person: {
first: 'hello',
last: 'world'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<script type="text/x-template" id="person-template">
<p v-text="first"/>
<p v-text="last"/>
</script>
<div id="app">
<div><!-- how? is this even possible? --></div>
</div>
Is there a way to get this working by only changing the HTML part of code? Preferably only the <div>-Element.
So this is not quite only changing the template, but a single additional property can work here. Specify a template in the Vue.
var app = new Vue({
el: '#app',
template: "#person-template",
data: {
person: {
first: 'hello',
last: 'world'
}
}
});
I also modified your template slightly because a template for any Vue or component requires one root element. I recommend you do not use self closing tags in Vue as I've seen this cause issues. Vue requires valid HTML5 and self closing tags are not valid HTML5.
<script type="text/x-template" id="person-template">
<div>
<p v-text="person.first"></p>
<p v-text="person.last"></p>
</div>
</script>
Working example.
Additionally, a very common way of specifying templates in this fashion, without using the kind of hacky script tag is to use the HTML5 template element.
<template id="person-template">
<div>
<p v-text="person.first"></p>
<p v-text="person.last"></p>
</div>
</template>
Finally, knowing you are slightly unhappy with the el:"#app" You can leave the el property out of the Vue definition and mount the Vue on an element of your choice using the $mount method. So if you wanted to go completely hog wild on separation of concerns you could do something like this.
const renderer = Vue.compile(document.querySelector("#person-template").innerHTML)
const example = {
data: {
person: {
first: 'hello',
last: 'world'
}
}
}
const app = new Vue(Object.assign({}, example, renderer))
app.$mount("#app")
Example.
I should mention nobody really does that (compiling their templates manually, it's common to use $mount) that I'm aware of. It also depends on using the version of Vue that includes the compiler (which you might not have if you are using webpack or some other build tool for example). You could also do something like this:
const app = new Vue(Object.assign({}, example, {template: "#person-template"}))
app.$mount("#app")
which would basically allow you to specify a template, a component, and a place to mount it all separately.

Vue.js 2.0: Apply vue component rendered using v-html, compile the markup

I'm using VueJS 2.0
Is there any way to make the below render as a link?
Here is my vue component:
<template>
<div v-html="markup"></div>
</template>
<script>
new Vue({
data() {
return {
markup: '<router-link :to="{path: 'https://www.google.com'}"></router-link>',
});
},
});
</script>
In the above example, I want to dynamically export a piece of markup, it contains some dynamic contents, such as router-link like above.
But that content did not compile, and exports a <router-link> tag as a final result.
Any way to make it compile programmatically?
What I really want is to find a way to compile a piece of html manually. If v-html doesn`t work, Is there any other way?
v-html works only for pre-compiled html which is basically generated text.
If you want do dynamically change content, simply use if conditions to render your list view based on prop that will tell you the type of the list view.
I don't think it's a good idea to save the markup in your db. It's rather more convenient to save some settings in your db and based on those to render the necessary html. (the prop type in your case). Maybe if you provide a more concrete example, some suggestions will follow. As you can see, the answers were based on your router-link example which I think is not enough to answer your question
I don't think you can instantiate Vue instances via v-html directive. You must override the default to do that, which would take lots of efforts.
If you just want dynamic links, why not try this:
data: {
menu: []
}
and then :
<router-link v-for="item in menu" :to="item.src">{{item.name}}</router-link>
PS: Can you give an example that you must do such things? I am really interesting in what needs it would be.
Given that you want to render a list of links, one way to do this can be like this:
<template>
<router-link v-for="list in lists" :to="{path: list}"></router-link>
</template>
<script>
new Vue({
data() {
return {
lists: ['https://www.google.com', 'https://www.stackoverflow.com']
});
},
});
</script>
Edit:
You can use an approach like following as well using with the help of dynamic components.
Vue.use(VueRouter)
new Vue({
el: "#app",
data: {
dynamicComp: "router-link"
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.2.0/vue-router.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="app">
somethind
<component :is="dynamicComp" :to="{path: 'https://www.google.com'}"></component>
</div>

How to add v-model dynamically created html in vue.js?

I use vue.js. I want add vue model in selector, who created using jquery plugin.
My code:
<div class="app">
<div class="wysiwyg-wrap"></div>
</div>
<script>
new Vue({
el: '.app',
data: {
wysiwygText: 'text demo'
},
created: function(){
$('.wysiwyg-wrap').trumbowyg();
}
});
</script>
Jquery plugin trumbowyg create inside '.wysiwyg-wrap' many html elements. How to add in one of this elements v-model binding? I want type in my redactor and save result in 'wysiwygText' from vue model.
Thank you for any answers!
This is a great use-case for custom directives. Here is an example of a custom directive that adds jQuery functionality to Vue: https://vuejs.org/examples/select2.html
You can create a simple directive
Vue.directive('wysiwyg-wrap', function () {
$(this.el).trumbowyg();
});
Then attach it to any element
<div class="app">
<div v-wysiwyg-wrap></div>
</div>

Categories

Resources