Link: https://laracasts.com/series/learn-vue-2-step-by-step/
Install Vue easily by inserting the recommended CDN.
<script src="https://unpkg.com/vue@2.2.1"></script>
- Create a new Vue instance
- Bind it to an element
- Specify some data
- Bind value to form inputs using
v-model
<div id="root">
<input type="text" id="input" v-model="message">
<p>The value of input is {{ message }}</p>
</div>
new Vue({
el: '#root',
data: {
message: "Hello World"
}
})
Install the Vue Dev Tools from Chrome Web Store.
This example explains how you may loop over array objects using Vue.
Our goal is to loop over a names array in an unordered list. We start by adding the array names
to data:
.
new Vue ({
el: '#root',
data: {
names: ['Frank', 'Kay', 'Romeo', 'Caleb', 'Carlos']
}
})
In our markup, we use the the v-for
to loop over our names.
<div id="root">
<ul>
<li v-for="name in names">
{{ name }}
</li>
</ul>
</div>
or we could also use v-text
to simplify our code.
<li v-for="name in names" v-text="name">
Event Listeners can easily be added by using v-on:click
. We can fire a method addName
by including it in after the listener like this v-on:click="addName"
.
<div id="root">
<ul>
<li v-for="name in names">
{{ name }}
</li>
</ul>
<input id="input" type="text" v-model="newName">
<button v-on:click="addName">Add Name</button>
</div>
We add any custom methods in Vue by adding them to the methods
object.
Below we are accessing the value typed into the input via the v-model="newName"
and adding it to the names
array. Next we clear the content of the input by reseting newName
to an empty string.
var app = new Vue ({
el: '#root',
data: {
newName: '',
names: ['Frank', 'Kay', 'Romeo', 'Caleb', 'Carlos']
},
methods: {
addName() {
this.names.push(this.newName)
this.newName = ''
}
}
})
We will be doing a lot of event listeners so we can do the shorthand of v-on:click
like this.
<button @click="addName">Add Name</button>
You can create your own message components which will look like this in the markup.
<message title="Hello World" body="Lorem ipsum dolor sit amet"></message>
<message title="Hello Javascript" body="Why didn't anyone tell me Vue is so cool!"></message>
Behind the scenes in our JS file, we can see how to create components. Notice that we are passing in the title
and body
.
To tell Vue how to handle them we add them to our props object. We place them with {{ }}
where we want them to render. We also have a new directives named v-show
which allows to hide and show elements. We are adding the isVisable
to toggle the attribute from true
to false
once you click the button.
Vue.component('message', {
props: ['title', 'body'],
data() {
return {
isVisable: true
}
},
template: `
<article class="message" v-show="isVisable">
<div class="message-header">
{{ title }}
<button class="delete" @click="isVisable = false"></button>
</div>
<div class="message-body">
{{ body }}
</div>
</article>
`
})
new Vue({
el:'#root',
})
This lesson covers using Bulma's modal in Vue.
First we copy the html from Bulma and add it to the component we make called modal
. We have to add the is-active
class to ensure it is fired. We'll control the hiding of the modal via a custom event called close
like this:
@click="$emit('close')"
In our root Vue app we have the showModal
data object that will start off as false. This controls if the modal is visible or not.
Vue.component('modal', {
template: `
<div class="modal is-active">
<div class="modal-background"></div>
<div class="modal-content">
<div class="box">
<p>
<slot></slot>
</p>
</div>
</div>
<button class="modal-close" @click="$emit('close')"></button>
</div>
`
})
new Vue({
el:'#root',
data: {
showModal: false
}
})
In our markup we have our Vue component and see our custom event listener close
. We fire the modal using the directive @click="showModal = true"
<div id="root" class="container">
<modal v-show="showModal" @close="showModal = false">
<p>Insert me here</p>
</modal>
<button @click="showModal = true">Show Modal</button>
</div>
We make nav tabs with contenet using Bulma and Vue
<div id="root" class="container">
<tabs>
<tab name="About Us" :selected="true">
<h1>Here is some content About Us.</h1>
</tab>
<tab name="About Our Culture">
<h1>Here is some content About Our Culture.</h1>
</tab>
<tab name="About Our Vision">
<h1>Here is some content About Our Vision.</h1>
</tab>
</tabs>
</div>
Vue.component('tabs', {
template:`
<div>
<div class="tabs">
<ul>
<li v-for="tab in tabs" :class="{ 'is-active': tab.isActive }">
<a :href="tab.href" @click="selectTab(tab)"> {{ tab.name }} </a>
</li>
</ul>
</div>
<div className="tabs-details">
<slot></slot>
</div>
</div>
`,
data() {
return { tabs: [] }
},
created() {
this.tabs = this.$children;
},
methods: {
selectTab(selectedTab) {
this.tabs.forEach( tab => {
tab.isActive = (tab.name == selectedTab.name)
})
}
}
})
Vue.component('tab', {
template: `
<div v-show="isActive">
<slot></slot>
</div>
`,
props: {
name: { required: true },
selected: { default: false }
},
data() {
return {
isActive: false
}
},
computed: {
href() {
return '#' + this.name.toLowerCase().replace(/ /g, '-')
}
},
mounted() {
this.isActive = this.selected
}
})
new Vue({
el:'#root',
data: {
showModal: false
}
})
We learned how components can communicate with one another. In the is example the coupon
component triggers the h1
to show if it is triggered by the blur
event or tabbing out of the input
.
<div id="root" class="container">
<coupon @applied="onCouponApplied"></coupon>
<h1 v-if="couponApplied">You used a coupon</h1>
</div>
Vue.component('coupon', {
template: `
<input type="text" placeholder="Enter your coupon code" @blur="onCouponApplied"/>
`,
methods: {
onCouponApplied() {
this.$emit('applied')
}
}
})
new Vue({
el:'#root',
data: {
couponApplied: false
},
methods: {
onCouponApplied() {
this.couponApplied = true
}
}
})
Here we now switch to a global instance of Vue as an event dispacther. The end result is the same as Lesson 12.
window.Event = new Vue()
Vue.component('coupon', {
template: `
<input type="text" placeholder="Enter your coupon code" @blur="onCouponApplied"/>
`,
methods: {
onCouponApplied() {
Event.$emit('applied')
}
}
})
new Vue({
el:'#root',
data: {
couponApplied: false
},
created() {
Event.$on('applied', () => alert('handling it'))
}
})
Here we see the power of named slots allowing us to have several slots in a component for more customization. Also in the js component we can add default data but it will be overriden if provided in the markup.
We can use the template
element to just give us the raw data rather than using another element like div
or h1
.
<div id="root" class="container">
<modal>
<template slot="header">My Header</template>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
<template slot="footer">
<a class="button is-success">Save changes</a>
<a class="button">Cancel</a>
</template>
</modal>
</div>
Notice the <slot name="someName"></slot>
.
Vue.component('modal', {
template: `
<div class="modal is-active">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">
<slot name="header"></slot>
</p>
<button class="delete"></button>
</header>
<section class="modal-card-body">
<slot></slot>
</section>
<footer class="modal-card-foot">
<slot name="footer">
<a class="button is-success">Okay</a>
</slot>
</footer>
</div>
</div>
`
})
new Vue({
el:'#root'
})
Not every component needs to be generic and reusable. Sometimes, a single, view-specific component is exactly what the doctor ordered. In this episode, we'll review the basic concept, and then discuss when you might reach for the inline-template attribute to nest your template directly in your HTML file.
<progress-view inline-template>
<div>
<h1>Your Progress through this course is {{ completionRate }}</h1>
<p><button @click="completionRate += 10">Update Complettion Rate</button></p>
</div>
</progress-view>
Vue.component('progress-view', {
data() {
return {
completionRate: 50
}
}
})
new Vue({
el:'#root'
})
Let's begin focusing on structure, and how you'll build actual applications with Vue. That means we're ready to learn both Webpack and vue-cli.