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

  • 155