Vue.js

.js
- ¿Qué es Vue.js?
- Cómo crear un proyecto usando Vue CLI y Vue UI.
- Estructura de un componente y su ciclo de vida.
- Componentes padre, Hijo y base.
- Plugins, mixins, directives y filters.
- Vue Router.
- ¿Preguntas?
Introducción a Vue.js
¿Qué es Vue.js?
- Creado por Evan You
- Enfocado en UI
- Reactivo
- Basado en Componentes
- Framework Progresivo
Title Text

Cómo crear un proyecto
Instalar vue-cli
npm install -g @vue/cli
# O
yarn global add @vue/cli
Crear proyecto
vue create ibaguejs
# O
vue ui
















Estructura del proyecto

Diagrama de Componentes

Estructura de un componente
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';
export default {
name: 'home',
components: {
HelloWorld
}
};
</script>
<style>
.home img {
max-width: 200px;
}
</style>
<template>
</template>
<script>
</script>
<style lang="scss">
.home {
img {
max-width: 200px;
}
}
</style>
<template>
</template>
<script>
</script>
<style lang="scss" scoped>
.home {
img {
max-width: 200px;
}
}
</style>
<template>
</template>
<script>
</script>
<style>
.home img[data-v-fae5bece] {
max-width: 200px;
}
</style>
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js App" />
</div>
</template>
<script>
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
.home
img(alt="Vue logo", src="../assets/logo.png")
hello-world(msg="Welcome to Your Vue.js App")
</template>
<script>
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';
export default {
name: 'home',
components: {
HelloWorld
}
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';
export default {
name: 'ComponentName',
components: {
HelloWorld
}
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
h1 {{ arg }}
</template>
<script>
export default {
name: 'ComponentName',
props: ['arg'],
components: {}
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
h1 {{ arg }}
</template>
<script>
export default {
name: 'ComponentName',
props: {
arg: String
},
components: {}
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
h1 {{ arg }}
</template>
<script>
export default {
name: 'ComponentName',
props: {
arg: {
type: String,
required: true
}
},
components: {}
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
hello-world(v-bind:msg="msg")
</template>
<script>
export default {
name: 'ComponentName',
props: {},
components: {},
data() {
return {
msg: 'Welcome to Your Vue.js App'
}
},
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
.home
hello-world(:msg="msg")
ul
li(v-for="speaker in speakers")
span {{ speaker }}
</template>
<script>
export default {
name: 'ComponentName',
props: {},
components: {},
data() {
return {
msg: 'Welcome to Your Vue.js App',
speakers: ['Pablo Dorado', 'Andrés Santos']
}
},
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
ul
li(v-for="speaker in speakers" :key="speaker.id")
span {{ speaker.name }}
</template>
<script>
export default {
name: 'ComponentName',
props: {},
components: {},
data() {
return {
speakers: [
{ id: 1, name: 'Pablo Dorado' },
{ id: 2, name: 'Andrés Santos' }
]
}
},
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
.home
div
label Speakers {{ countSpeakers }}
ul
li(v-for="speaker in speakers" :key="speaker.id")
span {{ speaker.name }}
</template>
<script>
export default {
data() {
return {
speakers: []
}
},
computed: {
countSpeakers() {
return this.speakers.length;
}
}
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
select(v-model="selectedSpeaker")
option(
v-for="speaker in speakers",
:value="speaker.id"
) {{ speaker.name }}
</template>
<script>
export default {
data() {
return {
speakers: [
{ id: 1, name: 'Pablo Dorado' },
{ id: 2, name: 'Andrés Santos' }
],
selectedSpeaker: null
};
},
watch: {
selectedSpeaker(newVal, oldVal) {
// To Do
}
},
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
select(v-model="selectedSpeaker")
option(
v-for="speaker in speakers",
:value="speaker.id"
) {{ speaker.name }}
</template>
<script>
export default {
data() {
return {};
},
watch: {
selectedSpeaker(newVal, oldVal) {
this.getTalks(newVal);
}
},
methods: {
getTalks(speakerId) {
// To Do
}
}
};
</script>
<style lang="scss" scoped>
</style>
<template lang="pug">
</template>
<script>
export default {
name: 'ComponentName',
props: {},
components: {},
data: {
return {
};
},
computed: {},
watch: {},
methods: {}
};
</script>
<style lang="scss" scoped>
</style>
Ciclo de Vida


<script>
export default {
beforeCreate() {
console.log('Nothing gets called before me!');
},
created() {
this.property = 'Example property update.';
console.log(
'propertyComputed will update, as this.property is now reactive.'
);
},
beforeMount() {
console.log(`this.$el doesn't exist yet, but it will soon!`);
},
mounted() {
console.log(this.$el.textContent); // I'm text inside the component.
},
beforeUpdate() {},
updated() {},
beforeDestroy() {},
destroyed() {
console.log(this); // There's practically nothing here!
}
};
</script>


Componentes padre-hijo


<template lang="pug">
.speaker-list
speaker-form(@onSubmit="handleSubmit")
</template>
<script>
import SpeakerForm from '@/components/SpeakerForm.vue';
export default {
components: {
SpeakerForm
},
data() {
return {
speakers: []
};
},
methods: {
handleSubmit(form) {
this.speakers.push({
name: form.newSpeaker
});
}
}
};
</script>
<template lang="pug">
.speaker-form
form(@submit.prevent="onSubmit")
input(type="text", v-model="form.newSpeaker")
button(
type="submit",
class="button -fill-gradient -size-small"
) Guardar
</template>
<script>
export default {
data() {
return {
form: {
newSpeaker: ''
}
};
},
methods: {
onSubmit() {
this.$emit('onSubmit', this.form);
}
}
};
</script>
Componentes base

<template lang="pug">
input(type="checkbox", @click="toggle", :value="value")
</template>
<script>
export default {
name: 'BaseCheckbox',
props: {
value: Boolean
},
methods: {
toggle() {
this.$emit('input', !this.value);
}
}
};
</script>
// main.js
import BaseCheckbox from '@/components/BaseCheckbox.vue';
Vue.component('BaseCheckbox', BaseCheckbox);
<template lang="pug">
.speaker-form
form(@submit.prevent="onSubmit")
.field
label Name
input(type="text", v-model="form.newSpeaker")
.field
base-checkbox(
:value="form.sendEmail",
@input="(value) => form.sendEmail = value"
)
label Send email
br
button(
type="submit",
class="button -fill-gradient -size-small"
) Guardar
</template>
Plugins y mixins

// plugins/event-bus.js
const eventBus = {}
eventBus.install = function (Vue) {
Vue.prototype.$bus = new Vue()
}
export default eventBus
// main.js
import EventBus from '@/plugins/event-bus';
Vue.use(EventBus);
// mixins/speaker.js
const speakerMixin = {
props: {
speaker: {
type: Object,
required: true
}
},
methods: {
selectSpeaker(speakerId) {
this.$bus.$emit('select-speaker', speakerId);
}
}
};
export default speakerMixin;
// components/SpeakerListItem.vue
<script>
import speakerMixin from '@/mixins/speaker';
export default {
name: 'SpeakerListItem',
mixins: [speakerMixin]
};
</script>
Directivas y filtros
- v-text
- v-html
- v-show
- v-if
- v-else
- v-else-if
- v-for
- v-on = @
- v-bind = :
- v-model
// directives/blur.js
const blur = {};
function setBlur(el, binding) {
}
blur.install = function(Vue) {
Vue.directive('blur', {
bind(el, binding) {
setBlur(el, binding);
}
});
};
export default blur;
// filters/date.js
const date = {};
function format(value) {
}
date.install = function(Vue) {
Vue.filter('date', val => {
return format(val);
});
};
export default date;
// main.js
import BlurDirective from '@/directives/blur';
import DateFilter from '@/filters/date';
Vue.use(BlurDirective);
Vue.use(DateFilter);
// components/SpeakerListItem.vue
<template>
<div
class="speaker-list-item"
v-blur="speaker.blur"
@click="selectSpeaker(speaker.id)"
>
<div class="event-card -shadow">
<h4 class="title">{{ speaker.name }}</h4>
<span class="eyebrow">{{ speaker.date | date }}</span>
</div>
</div>
</template>
Vue Router
- Es modular y permite crear rutas anidadas.
- Permite crear rutas con parámetros.
- Permite aplicar transiciones a las rutas.
- Permite trabajar HTML5 History Mode
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link :to="{ name: 'about' }">About</router-link>
</div>
<router-view />
</div>
</template>
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
}
]
});
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/speaker/:id',
name: 'speaker',
props: true,
// route level code-splitting
// this generates a separate chunk (speaker.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(
/* webpackChunkName: 'speaker' */ './views/SpeakerShow.vue'
)
}
]
});
<script>
export default {
methods: {
goToProfile(speakerId) {
this.$router.push({
name: 'speaker',
params: { id: speakerId }
});
}
}
};
</script>
<template>
<div>
{{ $route.params.id }}
</div>
</template>
export default {
props: {
id: Number
}
};
¿Preguntas?
Vue
By Andrés Santos
Vue
- 163