Manual Vuejs
Manual Vuejs
js
#vue.js
Tabla de contenido
Acerca de 1
Observaciones 2
Versiones 2
Examples 2
Ejemplo simple 2
Plantilla HTML 3
JavaScript 3
Capítulo 2: Accesorios 5
Observaciones 5
Examples 5
Apoyos dinámicos 10
JS 10
HTML 11
Resultado 11
ParentComponent.js 11
ChildComponent.js: 11
Introducción 13
Sintaxis 13
Observaciones 13
Examples 13
eventoBus 13
Capítulo 4: Complementos 15
Introducción 15
Sintaxis 15
Parámetros 15
Observaciones 15
Examples 15
Registrador simple 15
Capítulo 5: Componentes 17
Observaciones 17
Examples 17
HTML 17
JS 17
Registro en línea 21
Eventos 22
Observaciones 24
Examples 24
Javascript: 24
HTML: 24
Retazo: 24
Javascript: 25
HTML: 26
CSS: 26
Retazo: 26
Introducción 27
Observaciones 27
Examples 27
Sintaxis 29
Parámetros 29
Examples 29
Lo esencial 29
Examples 33
Texto 33
Atributos 33
Filtros 33
Introducción 35
Sintaxis 35
Examples 35
Enrutamiento básico 35
Examples 36
Sintaxis de eventos 36
Sintaxis 41
Parámetros 41
Examples 41
BASIC 42
Capítulo 13: Ganchos de ciclo de vida 43
Examples 43
init 43
created 43
beforeCompile 43
compiled 43
ready 43
attached 43
detached 43
beforeDestroy 43
destroyed 43
Introducción 46
Examples 46
Usando Array.prototype.splice 46
Examples 48
Mixin global 48
Lo esencial 48
Opción de fusión 49
Introducción 51
Examples 51
Modificadores de eventos 51
Modificadores clave 51
Modificadores de entrada 52
Parámetros 53
Observaciones 53
Examples 53
Observaciones 54
Examples 54
Ejemplo básico 54
Setters computados 55
Observaciones 59
Examples 59
Sintaxis 63
Observaciones 63
Examples 63
Visión general 63
v-if 63
v-else 63
v-show 63
v-if / v-else 63
v-show 65
Uso básico 66
HTML 66
Guión 66
Introducción 68
Examples 68
¡INCORRECTO! Usando una función de flecha para definir un método que se refiere a "esto" 69
Examples 71
Cómo funciona 71
Introducción 73
Examples 73
Examples 74
Inicializar: 74
Introducción 77
Examples 77
¿Qué es Vuex? 77
¿Por qué usar Vuex? 80
Creditos 86
Acerca de
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: vue-js
It is an unofficial and free Vue.js ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official Vue.js.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/es/home 1
Capítulo 1: Empezando con Vue.js
Observaciones
Vue.js es un marco de front-end en rápido crecimiento para JavaScript , inspirado en Angular.js ,
Reactive.js y Rivets.js que ofrece un diseño simplificado de interfaz de usuario, manipulación y
profunda reactividad.
Se describe como un marco modelado MVVM , Model-View View-Model , que se basa en el concepto
de datos de enlace bidireccional a componentes y vistas. Es increíblemente rápido, supera las
velocidades de otros marcos JS primer nivel y es muy fácil de usar para una fácil integración y
creación de prototipos.
Versiones
2.4.1 2017-07-13
2.3.4 2017-06-08
2.3.3 2017-05-09
2.2.6 2017-03-26
2.0.0 2016-10-02
1.0.26 2016-06-28
1.0.0 2015-10-26
0.12.0 2015-06-12
0.11.0 2014-11-06
Examples
"¡Hola Mundo!" Programa
Para comenzar a usar Vue.js , asegúrese de tener el archivo de script incluido en su HTML. Por
ejemplo, agregue lo siguiente a su HTML.
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
https://riptutorial.com/es/home 2
Ejemplo simple
Plantilla HTML
<div id="app">
{{ message }}
</div>
JavaScript
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
JSX no debe interpretarse por el navegador. Primero debe ser transpilado a Javascript estándar.
Para usar JSX necesitas instalar el plugin para babel babel-plugin-transform-vue-JSX
{
"presets": ["es2015"],
"plugins": ["transform-vue-jsx"]
}
new Vue({
el: '#app',
methods: {
handleClick () {
alert('Hello!')
https://riptutorial.com/es/home 3
}
},
render (h) {
return (
<div>
<h1 on-click={this.handleClick}>Hello from JSX</h1>
<p> Hello World </p>
</div>
)
}
})
Al utilizar JSX, puede escribir estructuras HTML / XML concisas en el mismo archivo que escribe
el código JavaScript.
VueJS también se puede usar para manejar fácilmente la entrada del usuario, y el enlace de dos
vías con v-model hace que sea muy fácil cambiar los datos fácilmente.
HTML:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
{{message}}
<input v-model="message">
</div>
JS:
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
https://riptutorial.com/es/home 4
Capítulo 2: Accesorios
Observaciones
Vue.component('child', {
props: ['myProp'],
...
});
Examples
Pasando datos de padres a hijos con accesorios
En Vue.js, cada instancia de componente tiene su propio alcance aislado , lo que significa que
si un componente principal tiene un componente secundario, el componente secundario tiene su
propio alcance aislado y el componente primario tiene su propio alcance aislado.
Para cualquier aplicación de tamaño mediano a grande, seguir las convenciones de mejores
prácticas previene muchos dolores de cabeza durante la fase de desarrollo y luego después del
mantenimiento. Una de esas cosas a seguir es que evite hacer referencia / mutar datos
primarios directamente desde el componente secundario . Entonces, ¿cómo hacemos
referencia a los datos principales desde un componente secundario?
Cualquier información de los padres que se requiera en un componente secundario se debe pasar
al niño como props de los padres.
Caso de uso : supongamos que tenemos una base de datos de usuarios con dos tablas, users y
addresses con los siguientes campos:
tabla de users
tabla de addresses
https://riptutorial.com/es/home 5
bloquear calle ciudad
y queremos tener tres componentes para mostrar la información del usuario correspondiente en
cualquier lugar de nuestra aplicación
user-component.js
export default{
template:`<div class="user-component">
<label for="name" class="form-control">Name: </label>
<input class="form-control input-sm" name="name" v-model="name">
<contact-details :phone="phone" :email="email"></contact-details>
</div>`,
data(){
return{
name:'',
phone:'',
email:''
}
},
}
contact-details.js
<h4>Address:</h4>
<address :address-type="addressType"></address>
//see camelCase vs kebab-case explanation below
</div>`,
props:['phone', 'email'],
data:(){
return:{
addressType:'Office'
}
},
components:{Address}
}
dirección.js
export default{
template:`<div class="address-component">
<h6>{{addressType}}</h6>
<label for="block" class="form-control">Block: </label>
https://riptutorial.com/es/home 6
<input class="form-control input-sm" name="block" v-model="block">
<label for="street" class="form-control">Street: </label>
<input class="form-control input-sm" name="street" v-model="street">
<label for="city" class="form-control">City: </label>
<input class="form-control input-sm" name="city" v-model="city">
</div>`,
props:{
addressType:{
required:true,
type:String,
default:'Office'
},
data(){
return{
block:'',
street:'',
city:''
}
}
}
main.js
Vue.component('user-component', require'./user-component');
Vue.component('contact-details', require'./contact-details');
new Vue({
el:'body'
});
index.html
...
<body>
<user-component></user-component>
...
</body>
Estamos mostrando los datos del phone y del email , que son propiedades del user-component de
user-component en contact-details que no tienen datos del teléfono o correo electrónico.
Dado que estamos vinculando dinámicamente las propuestas, cualquier cambio en el teléfono o
correo electrónico dentro del componente principal, es decir, <user-component> se reflejará
https://riptutorial.com/es/home 7
inmediatamente en el componente secundario, es decir, <contact-details> .
Sin embargo, si hubiéramos pasado los valores de teléfono y correo electrónico como valores
literales de cadena como phone="(44) 777 0007 0077" email="[email protected]" entonces no reflejaría
ningún cambio de datos que ocurra en el padre. componente.
Encuadernación unidireccional
En una aplicación de tamaño mediano a grande, cambiar el estado padre del estado hijo será
muy difícil de detectar y controlar, especialmente durante la depuración: tenga cuidado .
No habrá ninguna opción .sync disponible en Vue.js 2.0. El enlace bidireccional para los
accesorios está en desuso en Vue.js 2.0 .
También es posible definir un enlace explícito de una sola vez como :email.once="email , es más
o menos similar a pasar un literal, porque cualquier cambio posterior en el valor de la propiedad
principal no se propagará al elemento secundario.
ADVERTENCIA
Cuando se pasa un objeto o una matriz como prop, se pasarán SIEMPRE POR REFERENCIA ,
lo que significa que independientemente del tipo de enlace definido explícitamente
:email.sync="email" o :email="email" o :email.once="email" , Si el correo electrónico es un objeto o
una matriz en el principal, independientemente del tipo de enlace, cualquier cambio en el valor de
prop dentro del componente secundario también afectará el valor en el primario.
https://riptutorial.com/es/home 8
Apoyos como Array
En el archivo contact-details.js hemos definido props:['phone', 'email'] como una matriz, lo cual
está bien si no queremos un control detallado con props.
entonces necesitamos usar la notación de objetos para definir los accesorios, como hemos hecho
en address.js .
Si estamos creando componentes reutilizables que pueden ser utilizados por otros
desarrolladores en el equipo, entonces es una buena práctica definir objetos como objetos para
que cualquiera que use el componente tenga una idea clara de cuál debería ser el tipo de datos y
si Es obligatorio u opcional.
También se conoce como validación de accesorios . El tipo puede ser cualquiera de los
siguientes constructores nativos:
• Cuerda
• Número
• Booleano
• Formación
• Objeto
• Función
• o un constructor personalizado
Vue.component('example', {
props: {
// basic type check (`null` means accept any type)
propA: Number,
// multiple possible types (1.0.21+)
propM: [String, Number],
// a required string
propB: {
type: String,
required: true
},
// a number with default value
propC: {
type: Number,
default: 100
},
// object/array defaults should be returned from a
// factory function
https://riptutorial.com/es/home 9
propD: {
type: Object,
default: function () {
return { msg: 'hello' }
}
},
// indicate this prop expects a two-way binding. will
// raise a warning if binding type does not match.
propE: {
twoWay: true
},
// custom validator function
propF: {
validator: function (value) {
return value > 10
}
},
// coerce function (new in 1.0.12)
// cast the value before setting it on the component
propG: {
coerce: function (val) {
return val + '' // cast the value to string
}
},
propH: {
coerce: function (val) {
return JSON.parse(val) // cast the value to Object
}
}
}
});
camelCase vs kebab-case
Atributos HTML son entre mayúsculas y minúsculas, lo que significa que no puede diferenciar
entre addresstype y addressType , por lo que cuando se utiliza nombres camelCase prop como
atributos que necesitamos para utilizar su kebab de los casos equivalentes (guión) delimitado por:
Apoyos dinámicos
Al igual que puede vincular los datos de una vista al modelo, también puede vincular accesorios
utilizando la misma directiva v-bind para pasar información de los componentes principales a los
secundarios.
JS
new Vue({
el: '#example',
data: {
msg: 'hello world'
}
});
https://riptutorial.com/es/home 10
Vue.component('child', {
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>
});
HTML
<div id="example">
<input v-model="msg" />
<child v-bind:my-message="msg"></child>
<!-- Shorthand ... <child :my-message="msg"></child> -->
</div>
Resultado
hello world
ParentComponent.js
import ChildComponent from './ChildComponent';
export default {
render(h, {props}) {
const src = 'https://cdn-images-1.medium.com/max/800/1*AxRXW2j8qmGJixIYg7n6uw.jpeg';
return (
<ChildComponent src={src} />
);
}
};
Y un componente infantil, donde tenemos que pasar props. Necesitamos especificar qué
accesorios estamos pasando.
ChildComponent.js:
export default {
props: ['src'],
render(h, {props}) {
return (
<a href = {props.src} download = "myimage" >
Click this link
</a>
);
https://riptutorial.com/es/home 11
}
};
https://riptutorial.com/es/home 12
Capítulo 3: Bus de eventos
Introducción
Los buses de eventos son una forma útil de comunicación entre componentes que no están
directamente relacionados, es decir, no tienen una relación padre-hijo.
Es solo una instancia de vue vacía, que se puede usar para $emit eventos $on o escuchar $on
dichos eventos.
Sintaxis
1. exportar por defecto nuevo Vue ()
Observaciones
Use vuex si su aplicación tiene muchos componentes que requieren los datos de cada uno.
Examples
eventoBus
Vue.component('card', {
template: `<div class='card'>
Name:
<div class='margin-5'>
<input v-model='name'>
</div>
<div class='margin-5'>
<button @click='submit'>Save</button>
</div>
</div>`,
data() {
return {
name: null
}
},
methods: {
submit() {
bus.$emit('name-set', this.name)
}
}
})
https://riptutorial.com/es/home 13
// In another component that requires the emitted data.
var data = {
message: 'Hello Vue.js!'
}
https://riptutorial.com/es/home 14
Capítulo 4: Complementos
Introducción
Los complementos de Vue agregan funcionalidad global como, métodos globales, directivas,
transiciones, filtros, métodos de instancia, objetos e inyectan algunas opciones de componentes
utilizando mixins
Sintaxis
• MyPlugin.install = function (Vue, opciones) {}
Parámetros
Nombre Descripción
Observaciones
En la mayoría de los casos, deberá indicar explícitamente a Vue que use un complemento
// calls `MyPlugin.install(Vue)`
Vue.use(MyPlugin)
Pasar opciones
Examples
Registrador simple
//myLogger.js
export default {
install(Vue, options) {
function log(type, title, text) {
console.log(`[${type}] ${title} - ${text}`);
}
Vue.prototype.$log = {
https://riptutorial.com/es/home 15
error(title, text) { log('danger', title, text) },
success(title, text) { log('success', title, text) },
log
}
}
}
//main.js
import Logger from './path/to/myLogger';
Vue.use(Logger);
//myComponent.vue
export default {
data() {
return {};
},
methods: {
Save() {
this.$log.success('Transaction saved!');
}
}
}
https://riptutorial.com/es/home 16
Capítulo 5: Componentes
Observaciones
En Componente (s):
props es una matriz de literales de cadena o referencias de objetos que se utilizan para pasar
datos del componente principal. También puede estar en forma de objeto cuando se desea tener
un control más preciso, como la especificación de valores predeterminados, el tipo de datos
aceptados, si es necesario u opcional.
los datos tienen que ser una función que devuelve un objeto en lugar de un objeto plano. Esto es
así porque requerimos que cada instancia del componente tenga sus propios datos para fines de
reutilización.
eventos es un objeto que contiene escuchas para eventos a los que el componente puede
responder por cambio de comportamiento
Métodos objeto que contiene funciones que definen el comportamiento asociado con el
componente.
las propiedades computadas son como observadores u observables, cada vez que cualquier
dependencia cambia, las propiedades se recalculan automáticamente y los cambios se reflejan en
DOM al instante si DOM usa alguna propiedad computada
Examples
Componente con ámbito (no global)
Manifestación
HTML
<div id="app">
<h2>{{appName}}</h2>
<form-component title="This is a form" v-bind:name="userName"></form-component>
</div>
JS
https://riptutorial.com/es/home 17
// Describe the form component
// Note: props is an array of attribute your component can take in entry.
// Note: With props you can pass static data('title') or dynamic data('userName').
// Note: When modifying 'name' property, you won't modify the parent variable, it is only
descendent.
// Note: On a component, 'data' has to be a function that returns the data.
var formComponent = {
template: '#form-template',
props: ['title', 'name'],
data: function() {
return {
inputLabel: 'Name'
}
}
};
Los componentes en Vue son como widgets. Nos permiten escribir elementos personalizados
reutilizables con el comportamiento deseado.
No son más que objetos que pueden contener cualquiera o todas las opciones que puede
contener la raíz o cualquier instancia de Vue, incluida una plantilla HTML para representar.
Estos pueden escribirse en un archivo separado o como un solo archivo con la extensión .vue . A
continuación hay ejemplos que muestran ambas formas:
<style>
.hello-world-compoment{
color:#eeeeee;
background-color:#555555;
}
</style>
https://riptutorial.com/es/home 18
<template>
<div class="hello-world-component">
<p>{{message}}</p>
<input @keyup.enter="changeName($event)"/>
</div>
</template>
<script>
export default{
props:[ /* to pass any data from the parent here... */ ],
events:{ /* event listeners go here */},
ready(){
this.name= "John";
},
data(){
return{
name:''
}
},
computed:{
message(){
return "Hello from " + this.name;
}
},
methods:{
// this could be easily achieved by using v-model on the <input> field, but just
to show a method doing it this way.
changeName(e){
this.name = e.target.value;
}
}
}
</script>
Archivos separados
export default{
template:require('./hello-world.template.html'),
props:[ /* to pass any data from the parent here... */ ],
events:{ /* event listeners go here */ },
ready(){
this.name="John";
},
data(){
return{
name:''
}
},
computed:{
message(){
return "Hello World! from " + this.name;
}
},
methods:{
changeName(e){
let name = e.target.value;
this.name = name;
https://riptutorial.com/es/home 19
}
}
}
hello-world.template.html
<div class="hello-world-component">
<p>{{message}}</p>
<input class="form-control input-sm" @keyup.enter="changeName($event)">
</div>
hola-mundo.css
.hello-world-compoment{
color:#eeeeee;
background-color:#555555;
}
Estos ejemplos utilizan la sintaxis de es2015, por lo que se necesitará a Babel para compilarlos
en es5 para navegadores más antiguos.
Babel junto con Browserify + vueify o Webpack + vue-loader deberán compilar hello-world.vue
.
Ahora que tenemos el componente hello-world definido, debemos registrarlo con Vue.
import Vue from 'vue'; // Note that 'vue' in this case is a Node module installed with 'npm
install Vue'
Vue.component('hello-world', require('./hello-world'); // global registeration
new Vue({
el:'body',
import Vue from 'vue'; // Note that 'vue' in this case is a Node module installed with 'npm
install Vue'
import HelloWorld from './hello-world.js';
new Vue({
el:'body',
template:'<div class="app-container"><hello-world></hello-world></div>",
https://riptutorial.com/es/home 20
});
Los componentes globales se pueden utilizar en cualquier lugar dentro de la aplicación Vue.
Los componentes locales solo están disponibles para su uso en el componente principal con el
que están registrados.
El nuevo componente () solo estará disponible dentro del alcance (plantilla) del componente
principal.
Registro en línea
Vue.component('custom-component', {
template: '<div>A custom component!</div>'
})
Pasar un objeto a la propiedad de data al registrar un componente causaría que todas las
https://riptutorial.com/es/home 21
instancias del componente apunten a los mismos datos. Para resolver esto, necesitamos devolver
data de una función.
Eventos
Una de las formas en que los componentes pueden comunicarse con sus ancestros /
descendientes es a través de eventos de comunicación personalizados. Todas las instancias de
Vue también son emisores e implementan una interfaz de eventos personalizada que facilita la
comunicación dentro de un árbol de componentes. Podemos utilizar lo siguiente:
En el elemento hijo:
• Cada vez que un evento encuentra un componente que lo escucha y se activa, se detendrá
la propagación a menos que la función de devolución de llamada en este componente
https://riptutorial.com/es/home 22
devuelva true .
• $dispatch() siempre activa primero el componente que lo ha emitido.
• Podemos pasar cualquier número de argumentos al controlador de eventos. Haciendo
this.$broadcast('submit-form', this.formData, this.formStatus) nos permite acceder a estos
argumentos como 'submit-form': function (formData, formStatus) {}
https://riptutorial.com/es/home 23
Capítulo 6: Componentes dinámicos
Observaciones
es un elemento de componente reservado, no se confunda con la instancia de
<component>
componentes.
v-bindes una directiva. Las directivas tienen el prefijo v- para indicar que son atributos especiales
proporcionados por Vue.
Examples
Ejemplo de componentes dinámicos simples
Cambie dinámicamente entre varios componentes utilizando el elemento <component> y pase los
datos a v-bind: es atributo:
Javascript:
new Vue({
el: '#app',
data: {
currentPage: 'home'
},
components: {
home: {
template: "<p>Home</p>"
},
about: {
template: "<p>About</p>"
},
contact: {
template: "<p>Contact</p>"
}
}
})
HTML:
<div id="app">
<component v-bind:is="currentPage">
<!-- component changes when currentPage changes! -->
<!-- output: Home -->
</component>
</div>
Retazo:
https://riptutorial.com/es/home 24
Demo en vivo
A veces desea mantener los componentes apagados en la memoria, para que esto ocurra, debe
usar el elemento <keep-alive> :
Javascript:
new Vue({
el: '#app',
data: {
currentPage: 'home',
},
methods: {
switchTo: function(page) {
this.currentPage = page;
}
},
components: {
home: {
template: `<div>
<h2>Home</h2>
<p>{{ homeData }}</p>
</div>`,
data: function() {
return {
homeData: 'My about data'
}
}
},
about: {
template: `<div>
<h2>About</h2>
<p>{{ aboutData }}</p>
</div>`,
data: function() {
return {
aboutData: 'My about data'
}
}
},
contact: {
template: `<div>
<h2>Contact</h2>
<form method="POST" @submit.prevent>
<label>Your Name:</label>
<input type="text" v-model="contactData.name" >
<label>You message: </label>
<textarea v-model="contactData.message"></textarea>
<button type="submit">Send</button>
</form>
</div>`,
data: function() {
return {
contactData: { name:'', message:'' }
}
}
https://riptutorial.com/es/home 25
}
}
})
HTML:
<div id="app">
<div class="navigation">
<ul>
<li><a href="#home" @click="switchTo('home')">Home</a></li>
<li><a href="#about" @click="switchTo('about')">About</a></li>
<li><a href="#contact" @click="switchTo('contact')">Contact</a></li>
</ul>
</div>
<div class="pages">
<keep-alive>
<component :is="currentPage"></component>
</keep-alive>
</div>
</div>
CSS:
.navigation {
margin: 10px 0;
}
.navigation ul {
margin: 0;
padding: 0;
}
.navigation ul li {
display: inline-block;
margin-right: 20px;
}
input, textarea {
margin-bottom: 10px;
}
Retazo:
Demo en vivo
https://riptutorial.com/es/home 26
Capítulo 7: Componentes personalizados con
v-modelo
Introducción
Muchas veces tenemos que crear algunos componentes que realizan algunas acciones /
operaciones en los datos y requerimos eso en el componente principal. La mayoría de las veces,
vuex sería una mejor solución, pero en los casos en que el comportamiento del componente
secundario no tiene nada que ver con el estado de la aplicación, por ejemplo: un control
deslizante de rango, selector de fecha / hora, lector de archivos
Tener tiendas individuales para cada componente cada vez que se usan se complica.
Observaciones
Para tener v-model en un componente, debe cumplir dos condiciones.
<component v-model='something'></component>
<component
:value="something"
@input="something = $event.target.value"
>
</component>
Examples
v-modelo en un componente contador
Aquí el counter es un componente secundario al que se accede mediante una demo que es un
componente principal que usa v-model .
// child component
Vue.component('counter', {
template: `<div><button @click='add'>+1</button>
<button @click='sub'>-1</button>
<div>this is inside the child component: {{ result }}</div></div>`,
data () {
return {
result: 0
https://riptutorial.com/es/home 27
}
},
props: ['value'],
methods: {
emitResult () {
this.$emit('input', this.result)
},
add () {
this.result += 1
this.emitResult()
},
sub () {
this.result -= 1
this.emitResult()
}
}
})
Este componente hijo emitirá result cada vez que se llamen los métodos sub() o add() .
// parent component
new Vue({
el: '#demo',
data () {
return {
resultFromChild: null
}
}
})
// parent template
<div id='demo'>
<counter v-model='resultFromChild'></counter>
This is in parent component {{ resultFromChild }}
</div>
Dado que v-model está presente en el componente secundario, al mismo tiempo se envió un prop
con value nombre, hay un evento de entrada en el counter que, a su vez, proporcionará el valor
del componente secundario.
https://riptutorial.com/es/home 28
Capítulo 8: Directivas personalizadas
Sintaxis
• Vue.directive(id, definition);
• Vue.directive(id, update); //when you need only the update function.
Parámetros
Parámetro Detalles
Examples
Lo esencial
Puede registrar una directiva personalizada global con el Vue.directive(id, definition) , pasando
una id de directiva seguida de un objeto de definición. También puede registrar una directiva
personalizada local incluyéndola en la opción de directives un componente.
Funciones de gancho
• bind : se llama solo una vez, cuando la directiva se enlaza por primera vez al elemento.
• actualización : se llama por primera vez inmediatamente después del bind con el valor
inicial, y luego nuevamente cuando el valor del enlace cambia. El nuevo valor y el valor
anterior se proporcionan como el argumento.
• desvincular : se llama solo una vez, cuando la directiva no está vinculada al elemento.
Vue.directive('my-directive', {
bind: function () {
// do preparation work
// e.g. add event listeners or expensive stuff
// that needs to be run only once
},
update: function (newValue, oldValue) {
// do something based on the updated value
// this will also be called for the initial value
},
https://riptutorial.com/es/home 29
unbind: function () {
// do clean up work
// e.g. remove event listeners added in bind()
}
})
Una vez registrado, puede usarlo en plantillas Vue.js como esta (recuerde agregar el prefijo v- ):
<div v-my-directive="someValue"></div>
Cuando solo necesita la función de update , puede pasar una sola función en lugar del objeto de
definición:
Todas las funciones de enganche se copiarán en el objeto real de la Directiva, que se puede
acceder dentro de estas funciones como su this contexto. El objeto directivo expone algunas
propiedades útiles:
Debe tratar todas estas propiedades como de solo lectura y nunca modificarlas.
También puede adjuntar propiedades personalizadas al objeto directivo, pero tenga
cuidado de no sobrescribir accidentalmente las existentes internas.
HTML
JavaScript
Vue.directive('demo', {
bind: function () {
console.log('demo bound!')
},
update: function (value) {
this.el.innerHTML =
https://riptutorial.com/es/home 30
'name - ' + this.name + '<br>' +
'expression - ' + this.expression + '<br>' +
'argument - ' + this.arg + '<br>' +
'modifiers - ' + JSON.stringify(this.modifiers) + '<br>' +
'value - ' + value
}
})
var demo = new Vue({
el: '#demo',
data: {
msg: 'hello!'
}
})
Resultado
name - demo
expression - msg
argument - hello
modifiers - {"b":true,"a":true}
value - hello!
Objeto Literal
Si su directiva necesita varios valores, también puede pasar un objeto literal de JavaScript.
Recuerda, las directivas pueden tomar cualquier expresión válida de JavaScript:
HTML
JavaScript
Modificador literal
Cuando se usa una directiva con el modificador literal, su valor de atributo se interpretará como
una cadena simple y se pasará directamente al método de update . El método de update también
se llamará una sola vez, porque una cadena simple no puede ser reactiva.
HTML
JavaScript
https://riptutorial.com/es/home 31
})
https://riptutorial.com/es/home 32
Capítulo 9: El enlace de datos
Examples
Texto
La etiqueta del bigote se reemplazará con el valor de la propiedad msg en el objeto de datos
correspondiente. También se actualizará cada vez que cambie la propiedad msg del objeto de
datos.
También puede realizar interpolaciones de una sola vez que no se actualizan en el cambio de
datos:
Los bigotes dobles interpretan los datos como texto plano, no HTML. Para generar HTML real,
deberá usar los bigotes triples:
Los contenidos se insertan como HTML simple: se ignoran los enlaces de datos. Si necesita
reutilizar piezas de plantilla, debe usar parciales.
Atributos
Tenga en cuenta que las interpolaciones de atributos no están permitidas en las directivas Vue.js
y los atributos especiales. No te preocupes, Vue.js generará advertencias cuando los bigotes se
usen en lugares equivocados.
Filtros
Vue.js le permite agregar "filtros" opcionales al final de una expresión, denotados por el símbolo
"pipe":
https://riptutorial.com/es/home 33
{{ message | capitalize }}
Aquí estamos "canalizando" el valor de la expresión del message través del filtro de capitalize
incorporado, que de hecho es solo una función de JavaScript que devuelve el valor capitalizado.
Vue.js proporciona una serie de filtros integrados, y hablaremos sobre cómo escribir sus propios
filtros más adelante.
Tenga en cuenta que la sintaxis de canalización no forma parte de la sintaxis de JavaScript, por lo
tanto, no puede mezclar filtros dentro de las expresiones; solo puedes añadirlos al final de una
expresión.
La función de filtro siempre recibe el valor de la expresión como primer argumento. Los
argumentos entre comillas se interpretan como una cadena simple, mientras que los que no están
entre comillas se evaluarán como expresiones. Aquí, la cadena simple 'arg1' pasará al filtro como
segundo argumento, y el valor de la expresión arg2 se evaluará y pasará como el tercer
argumento.
https://riptutorial.com/es/home 34
Capítulo 10: enrutador vue
Introducción
vue-router es la biblioteca de enrutamiento soportada oficialmente para vue.js.
Sintaxis
• <router-link to="/path">Link Text</router-link> <!-- Creates a link to the route that
matches the path -->
• <router-view></router-view> <!-- Outlet for the currently matched route. It's component
will be rendered here. -->
Examples
Enrutamiento básico
La forma más fácil de comenzar a utilizar vue-router es usar la versión provista a través de CDN.
HTML:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="router-example">
<router-link to="/foo">Link to Foo route</router-link>
<router-view></router-view>
</div>
JavaScript (ES2015):
const Foo = { template: <div>This is the component for the Foo route</div> }
https://riptutorial.com/es/home 35
Capítulo 11: Eventos
Examples
Sintaxis de eventos
https://riptutorial.com/es/home 36
Aquí hay un ejemplo de cómo funciona:
MANIFESTACIÓN
HTML
JS
var messageBox = {
template: '#message-box',
props: ['msg']
};
new Vue({
el: 'body',
https://riptutorial.com/es/home 37
data: {
message: ''
},
methods: {
updateMessage: function(msg) {
this.message = msg;
}
},
components: {
'message-box': messageBox
}
});
DEMO vue1
DEMO vue2
En Vue1, debe usar .sync en la propiedad enviada al componente <message-box> . Esto le indica a
VueJS que sincronice el valor en el componente secundario con el principal.
HTML Vue1
<div id="app">
<message-box :value.sync="message"></message-box>
<div>You typed: {{message}}</div>
</div>
En Vue2, hay un evento especial de 'input' que puede $emit . El uso de este evento le permite
poner un v-model directamente en el componente <message-box> . El ejemplo se verá como sigue:
HTML Vue2
<div id="app">
<message-box v-model="message"></message-box>
<div>You typed: {{message}}</div>
</div>
https://riptutorial.com/es/home 38
JS Vue 1 y 2
var messageBox = {
template: '#message-box',
props: ['value']
};
new Vue({
el: '#app',
data: {
message: ''
},
components: {
'message-box': messageBox
}
});
Es posible que se haya dado cuenta de que $emit está dentro del alcance del componente que
emite el evento. Eso es un problema cuando se quiere comunicar entre componentes alejados
entre sí en el árbol de componentes.
Nota: En Vue1 puede usar $dispatch o $broadcast , pero no en Vue2. La razón es que no se
escala bien. Hay un patrón de bus popular para gestionar esto:
MANIFESTACIÓN
HTML
<sender></sender>
<receiver></receiver>
JS
var senderComponent = {
template: '#sender',
data() {
return {
bus: bus
}
https://riptutorial.com/es/home 39
}
};
var receiverComponent = {
template: '#receiver',
data() {
return {
numberOfEvents: 0
}
},
ready() {
var self = this;
bus.$on('new-event', function() {
++self.numberOfEvents;
});
}
};
new Vue({
el: 'body',
components: {
'sender': senderComponent,
'receiver': receiverComponent
}
});
Solo debe comprender que cualquier instancia de Vue() puede $emit y capturar ( $on ) un evento.
Simplemente declaramos un bus llamadas de instancia de Vue global y luego cualquier
componente con esta variable puede emitir y capturar eventos desde él. Solo asegúrese de que el
componente tenga acceso a la variable de bus .
https://riptutorial.com/es/home 40
Capítulo 12: Filtros personalizados
Sintaxis
• Vue.filter(name, function(value){}); //BASIC
• Vue.filter(name, function(value, begin, end){}); // Basic con valores de envoltura
• Vue.filter(name, function(value, input){}); //Dinámica
• Vue.filter(name, { read: function(value){}, write: function(value){} }); //De doble sentido
Parámetros
Parámetro Detalles
valor [Devolución de llamada] Cualquiera - valor de los datos que pasan al filtro
empezar [Devolución de llamada] Cualquier valor por venir antes de los datos pasados
Examples
Filtros de dos vías
Con un two-way filter , podemos asignar una operación de read y write para un solo filter que
cambia el valor de los mismos datos entre la view y el model .
//JS
Vue.filter('uppercase', {
//read : model -> view
read: function(value) {
return value.toUpperCase();
},
/*
* Base value of data: 'example string'
*
* In the view : 'EXAMPLE STRING'
https://riptutorial.com/es/home 41
* In the model : 'example string'
*/
BASIC
Los filtros personalizados en Vue.js se pueden crear fácilmente en una sola función de llamada a
Vue.filter .
//JS
Vue.filter('reverse', function(value) {
return value.split('').reverse().join('');
});
//HTML
<span>{{ msg | reverse }}</span> //'This is fun!' => '!nuf si sihT'
Es una buena práctica almacenar todos los filtros personalizados en archivos separados, por
ejemplo, en ./filters ya que es fácil reutilizar su código en su próxima aplicación. Si vas de esta
manera tienes que reemplazar la parte JS :
//JS
Vue.filter('reverse', require('./filters/reverse'));
//JS
Vue.filter('wrap', function(value, begin, end) {
return begin + value + end;
});
//HTML
<span>{{ msg | wrap 'The' 'fox' }}</span> //'quick brown' => 'The quick brown fox'
https://riptutorial.com/es/home 42
Capítulo 13: Ganchos de ciclo de vida
Examples
Ganchos para vue 1.x
• init
• created
• beforeCompile
• compiled
• ready
• attached
Ocurre cuando $el se adjunta al DOM por una directive o instancia llama a $appendTo() .
• detached
• beforeDestroy
• destroyed
Llamado después de que se destruye una instancia. Todas las bindings y directives ya se
https://riptutorial.com/es/home 43
han liberado y las instancias secundarias también se han destruido.
Dado que todos los ganchos de ciclo de vida en Vue.js son solo functions , puede colocar
cualquiera de ellos directamente en la instancia declaraction.
//JS
new Vue({
el: '#example',
data: {
...
},
methods: {
...
},
ready: function() {
...
}
});
Un caso de uso común para el enlace ready() es acceder al DOM, por ejemplo, para iniciar un
complemento de Javascript, obtener las dimensiones de un elemento, etc.
El problema
La solución
Para esta situación, el método de instancia $nextTick() puede ayudar. Este método difiere la
ejecución de la función de devolución de llamada proporcionada hasta después del siguiente tick,
lo que significa que se activa cuando se garantiza que todas las actualizaciones de DOM
finalizarán.
Ejemplo:
module.exports {
ready: function () {
https://riptutorial.com/es/home 44
$('.cool-input').initiateCoolPlugin() //fails, because element is not in DOM yet.
this.$nextTick(function() {
$('.cool-input').initiateCoolPlugin() // this will work because it will be executed
after the DOM update.
})
}
}
https://riptutorial.com/es/home 45
Capítulo 14: Las advertencias de detección
de cambio de matriz
Introducción
Cuando intenta establecer un valor de un elemento en un índice particular de una matriz
inicializada en la opción de datos, vue no puede detectar el cambio y no desencadena una
actualización al estado. Para superar esta advertencia, debe usar Vue. $ Set o usar el método
Array.prototype.splice.
Examples
Usando Vue. $ Set
new Vue({
el: '#app',
data:{
myArr : ['apple', 'orange', 'banana', 'grapes']
},
methods:{
changeArrayItem: function(){
//this will not work
//myArr[2] = 'strawberry';
Usando Array.prototype.splice
Puede realizar el mismo cambio en lugar de usar Vue.$set utilizando el splice() del prototipo Array
splice()
new Vue({
el: '#app',
data:{
myArr : ['apple', 'orange', 'banana', 'grapes']
},
methods:{
changeArrayItem: function(){
//this will not work
//myArr[2] = 'strawberry';
https://riptutorial.com/es/home 46
//Array.splice(index, 1, newValue)
this.myArr.splice(2, 1, 'strawberry');
}
}
})
new Vue({
el: '#app',
data:{
myArr : [
['apple', 'banana'],
['grapes', 'orange']
]
},
methods:{
changeArrayItem: function(){
this.$set(this.myArr[1], 1, 'strawberry');
}
}
})
new Vue({
el: '#app',
data:{
myArr : [
{
name: 'object-1',
nestedArr: ['apple', 'banana']
},
{
name: 'object-2',
nestedArr: ['grapes', 'orange']
}
]
},
methods:{
changeArrayItem: function(){
this.$set(this.myArr[1].nestedArr, 1, 'strawberry');
}
}
})
https://riptutorial.com/es/home 47
Capítulo 15: Mixins
Examples
Mixin global
También puedes aplicar una mezcla globalmente. ¡Con precaución! Una vez que aplique una
mezcla globalmente, afectará a cada instancia de Vue creada posteriormente. Cuando se usa
correctamente, se puede usar para inyectar lógica de procesamiento para opciones
personalizadas:
new Vue({
myOption: 'hello!'
})
// -> "hello!"
Utilice los mixins globales de forma dispersa y cuidadosa, ya que afecta a cada
instancia de Vue creada, incluidos los componentes de terceros. En la mayoría de los
casos, solo debe usarlo para el manejo de opciones personalizadas como se muestra
en el ejemplo anterior.
Para la mayoría de las opciones basadas en objetos, simplemente puede usar la misma
estrategia utilizada por los methods :
Lo esencial
https://riptutorial.com/es/home 48
Los mixins son una forma flexible de distribuir funcionalidades reutilizables para componentes de
Vue. Un objeto mixin puede contener cualquier opción de componente. Cuando un componente
usa una mezcla, todas las opciones en la mezcla se "mezclan" en las propias opciones del
componente.
Opción de fusión
var mixin = {
created: function () {
console.log('mixin hook called')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('component hook called')
}
})
Las opciones que esperan valores de objetos, por ejemplo, methods , components y directives , se
fusionarán en el mismo objeto. Las opciones del componente tendrán prioridad cuando haya
claves en conflicto en estos objetos:
var mixin = {
methods: {
foo: function () {
https://riptutorial.com/es/home 49
console.log('foo')
},
conflicting: function () {
console.log('from mixin')
}
}
}
https://riptutorial.com/es/home 50
Capítulo 16: Modificadores
Introducción
Hay algunas operaciones de uso frecuente como event.preventDefault() o event.stopPropagation()
dentro de los controladores de eventos. Aunque podemos hacer esto fácilmente dentro de los
métodos, sería mejor si los métodos fueran puramente lógicos de datos en lugar de tener que
lidiar con los detalles del evento DOM.
Examples
Modificadores de eventos
Vue proporciona modificadores de eventos para v-on llamando a las directivas postfixes
denotadas por un punto.
• .stop
• .prevent
• .capture
• .self
• .once
Por ejemplo:
<!-- the submit event will no longer reload the page -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- use capture mode when adding the event listener -->
<div v-on:click.capture="doThis">...</div>
Modificadores clave
• .enter
• .tab
• .delete (captura las teclas "Eliminar" y "Retroceso")
• .esc
• .space
• .up
https://riptutorial.com/es/home 51
• .down
• .left
• .right
Por ejemplo:
<input v-on:keyup.enter="submit">
Modificadores de entrada
• .trim
Si desea que las entradas del usuario se recorten automáticamente, puede agregar el modificador
de trim a las entradas administradas de su v-model :
<input v-model.trim="msg">
• .number
Si desea que la entrada del usuario se escriba automáticamente como un número, puede hacer lo
siguiente:
• .lazy
En general, v-model sincroniza la entrada con los datos después de cada evento de entrada, pero
puede agregar el modificador lazy para sincronizar en su lugar después de los eventos de
cambio:
https://riptutorial.com/es/home 52
Capítulo 17: Plantilla "webpack" de polyfill
Parámetros
Archivos o
Comando o configuración a modificar.
paquetes
files: ['../../node_modules/babel-
karma.conf.js polyfill/dist/polyfill.js','./index.js'],
Observaciones
Las configuraciones descritas anteriormente, el ejemplo que usa una función no estandarizada
funcionará en "internet explorer" y la npm test pasará.
Examples
Uso de funciones para polyfill (ex: find)
<template>
<div class="hello">
<p>{{ filtered() }}</p>
</div>
</template>
<script>
export default {
name: 'hello',
data () {
return {
list: ['toto', 'titi', 'tata', 'tete']
}
},
methods: {
filtered () {
return this.list.find((el) => el === 'tata')
}
}
}
</script>
https://riptutorial.com/es/home 53
Capítulo 18: Propiedades calculadas
Observaciones
Examples
Ejemplo básico
Modelo
<div id="example">
a={{ a }}, b={{ b }}
</div>
JavaScript
Resultado
a=1, b=2
Aquí hemos declarado una propiedad computada b . La función que proporcionamos se utilizará
https://riptutorial.com/es/home 54
como la función getter para la propiedad vm.b :
console.log(vm.b) // -> 2
vm.a = 2
console.log(vm.b) // -> 3
Puede enlazar datos a propiedades computadas en plantillas como una propiedad normal. Vue es
consciente de que vm.b depende de vm.a , por lo que actualizará todos los enlaces que dependan
de vm.b cuando vm.a cambie.
modelo
<div id="demo">{{fullName}}</div>
ver ejemplo
Ejemplo calculado
Setters computados
https://riptutorial.com/es/home 55
Las propiedades calculadas se volverán a calcular automáticamente cada vez que se modifique
cualquier dato del que dependan los cálculos. Sin embargo, si necesita cambiar manualmente
una propiedad computada, Vue le permite crear un método de establecimiento para hacer esto:
<div id="example">
a={{ a }}, b={{ b }}
</div>
Javascript:
console.log(vm.b) // -> 2
vm.b = 4 // (setter)
console.log(vm.b) // -> 4
console.log(vm.a) // -> 3
La plantilla:
<div id="demo">
<div class='inline-block card'>
<div :class='{onlineMarker: true, online: status, offline: !status}'></div>
<p class='user-state'>User is {{ (status) ? 'online' : 'offline' }}</p>
</div>
<div class='margin-5'>
https://riptutorial.com/es/home 56
<input type='checkbox' v-model='status'>Toggle status (This will show you as offline to
others)
</div>
</div>
Estilo:
#demo {
font-family: Helvetica;
font-size: 12px;
}
.inline-block > * {
display: inline-block;
}
.card {
background: #ddd;
padding:2px 10px;
border-radius: 3px;
}
.onlineMarker {
width: 10px;
height: 10px;
border-radius: 50%;
transition: all 0.5s ease-out;
}
.online {
background-color: #3C3;
}
.offline {
background-color: #aaa;
}
.user-state {
text-transform: uppercase;
letter-spacing: 1px;
}
.margin-5 {
margin: 5px;
}
El componente:
https://riptutorial.com/es/home 57
Fiddle Aquí verás, al hacer clic en el botón de radio no tiene ningún uso, tu estado aún está en
línea.
violín Y ahora puede ver el cambio cuando la casilla de verificación está activada / desactivada.
https://riptutorial.com/es/home 58
Capítulo 19: Ranuras
Observaciones
¡Importante! Las ranuras después del render no garantizan el orden para las posiciones de las
ranuras. La ranura, que fue la primera, puede tener una posición diferente después del render.
Examples
Uso de ranuras individuales
Las ranuras únicas se utilizan cuando un componente secundario solo define una slot dentro de
su plantilla. El componente de la page anterior utiliza una única ranura para distribuir contenido.
A continuación se muestra un ejemplo de la plantilla del componente de la page que utiliza una
única ranura:
<html>
<head>
<title>Page Title</title>
</head>
<body>
<slot>
This will only be displayed if there is no content
to be distributed.
</slot>
</body>
</html>
Para ilustrar cómo funciona la ranura, podemos configurar una página de la siguiente manera.
<page>
<p>This content will be displayed within the page component</p>
</page>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<p>This content will be displayed within the page component</p>
</body>
</html>
https://riptutorial.com/es/home 59
<html>
<head>
<title>Page Title</title>
</head>
<body>
This will only be displayed if there is no content
to be distributed.
</body>
</html>
Las ranuras ofrecen una forma conveniente de distribuir contenido de un componente principal a
un componente secundario. Este contenido puede ser cualquier cosa, desde texto, HTML o
incluso otros componentes.
A veces puede ser útil pensar en las ranuras como un medio para inyectar contenido
directamente en la plantilla de un componente secundario.
Las ranuras son especialmente útiles cuando la composición del componente debajo del
componente principal no es siempre la misma.
Artículo
<page>
<article></article>
<comments></comments>
</page>
Entrada en el blog
<page>
<blog-post></blog-post>
<comments></comments>
</page>
Formar
<page>
<form></form>
</page>
Observe cómo el contenido del componente de la page puede cambiar. Si no usáramos las
ranuras, esto sería más difícil ya que la parte interna de la plantilla se arreglaría.
https://riptutorial.com/es/home 60
Usando ranuras nombradas
Las ranuras con nombre funcionan de manera similar a las ranuras individuales, pero en su lugar
le permiten distribuir contenido a diferentes regiones dentro de su plantilla de componente
secundaria.
Tome el componente de la page del ejemplo anterior, pero modifique su plantilla para que sea
como sigue:
<html>
<head>
<title>Page Title</title>
</head>
<body>
<aside>
<slot name="sidebar"></slot>
</aside>
<main>
<slot name="content"></slot>
</main>
</body>
</html>
<page>
<p slot="sidebar">This is sidebar content.</p>
<article slot="content"></article>
</page>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<aside>
<p>This is sidebar content.</p>
</aside>
<main>
<article></article>
</main>
</body>
</html>
Si se define una slot sin un atributo de name , cualquier contenido que se coloque dentro de
etiquetas de componentes que no especifiquen un atributo de slot se colocará en esa ranura.
https://riptutorial.com/es/home 61
Si estás usando VueJS2 y te gusta usar JSX junto con él. En este caso, para usar la ranura, a
continuación se muestra la solución con el ejemplo. Tenemos que usar this.$slots.default Es
casi como this.props.children en React JS.
Componente.js:
export default {
render(h) { //eslint-disable-line
return (
<li>
{ this.$slots.default }
</li>
);
}
};
ParentComponent.js
export default {
render(h) { //eslint-disable-line
return (
<ul>
<Component>
Hello World
</Component>
</ul>
);
}
};
https://riptutorial.com/es/home 62
Capítulo 20: Representación condicional
Sintaxis
• <element v-if="condition"></element> // v-if
• <element v-if="condition"></element><element v-else="condition"></element> // v-if | v-else
• <template v-if="condition">...</template> // v-if con plantilla
• <element v-show="condition"></element> // v-show
Observaciones
Es muy importante recordar la diferencia entre v-if y v-show . Si bien sus usos son casi idénticos,
un elemento vinculado a v-if solo se procesará en el DOM cuando su condición sea true por
primera vez . Cuando se usa la directiva v-show , todos los elementos se representan en el DOM
pero se ocultan usando el estilo de display si la condición es false .
Examples
Visión general
v-if
v-else
No acepta una condición, sino que procesa el elemento si la condición v-if del elemento anterior
es false . Solo se puede utilizar después de un elemento con la directiva v-if .
v-show
Sin embargo, se comporta de manera similar a v-if , sin embargo, el elemento siempre se
representará en el DOM, incluso cuando la condición sea false . Si la condición es false , esta
directiva simplemente establecerá el estilo de display del elemento en none .
v-if / v-else
https://riptutorial.com/es/home 63
el: '#example',
data: {
a: true,
b: false
}
});
<!-- will render 'The condition is true' into the DOM -->
<div id="example">
<h1 v-if="a">The condition is true</h1>
</div>
El elemento <h1> se representará en este caso, porque la variable 'a' es verdadera. v-if puede
usarse con cualquier expresión, propiedad computada o función que se evalúe como un valor
booleano:
Puede usar un elemento de template para agrupar varios elementos para una sola condición:
<!-- in this case, nothing will be rendered except for the containing 'div' -->
<div id="example">
<template v-if="b">
<h1>Heading</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
</div>
Al usar v-if , también tiene la opción de integrar una condición de contador con la directiva v-else
. El contenido contenido dentro del elemento solo se mostrará si la condición del v-if anterior era
falsa. Tenga en cuenta que esto significa que un elemento con v-else debe aparecer
inmediatamente después de un elemento con v-if.
Al igual que con v-if, con v-else puede agrupar varios elementos html en un <template> :
https://riptutorial.com/es/home 64
</template>
v-show
El uso de la directiva v-show es casi idéntico al de v-if . Las únicas diferencias son que v-show no
admite la sintaxis <template> y no existe una condición "alternativa".
Si bien v-show no admite la directiva v-else para definir condiciones "alternativas", esto se puede
lograr al anular la anterior ...
https://riptutorial.com/es/home 65
Capítulo 21: Representación de lista
Examples
Uso básico
Se puede representar una lista usando la directiva v-for . La sintaxis requiere que especifique la
matriz de origen para iterar, y un alias que se usará para hacer referencia a cada elemento en la
iteración. En el siguiente ejemplo, usamos items como la matriz de origen, y item como el alias
para cada elemento.
HTML
<div id="app">
<h1>My List</h1>
<table>
<tr v-for="item in items">
<td>{{item}}</td>
</tr>
</table>
</div>
Guión
new Vue({
el: '#app',
data: {
items: ['item 1', 'item 2', 'item 3']
}
})
<ul id="render-sample">
<li v-for="n in 5">
Hello Loop
</li>
</ul>
<ul>
<li v-for="n in 10">{{11 - n}} pigs are tanning at the beach. One got fried, and
https://riptutorial.com/es/home 66
</ul>
https://jsfiddle.net/gurghet/3jeyka22/
HTML:
Guión:
new Vue({
el: '#repeat-object',
data: {
object: {
FirstName: 'John',
LastName: 'Doe',
Age: 30
}
}
})
https://riptutorial.com/es/home 67
Capítulo 22: Usando "esto" en Vue
Introducción
Uno de los errores más comunes que encontramos en el código Vue en StackOverflow es el mal
uso de this . Los errores más comunes generalmente se dividen en dos áreas, utilizando this en
devoluciones de llamadas para promesas u otras funciones asíncronas y utilizando funciones de
flecha para definir métodos, propiedades computadas, etc.
Examples
¡INCORRECTO! Usando "esto" en una devolución de llamada dentro de un
método Vue.
new Vue({
el:"#app",
data:{
foo: "bar"
},
methods:{
doSomethingAsynchronous(){
setTimeout(function(){
// This is wrong! Inside this function,
// "this" refers to the window object.
this.foo = "baz";
}, 1000);
}
}
})
new Vue({
el:"#star-wars-people",
data:{
people: null
},
mounted: function(){
$.getJSON("http://swapi.co/api/people/", function(data){
// Again, this is wrong! "this", here, refers to the window.
this.people = data.results;
})
}
})
https://riptutorial.com/es/home 68
new Vue({
el:"#star-wars-people",
data:{
people: null
},
mounted: function(){
// Before executing the web service call, save this to a local variable
var self = this;
$.getJSON("http://swapi.co/api/people/", function(data){
// Inside this call back, because of the closure, self will
// be accessible and refers to the Vue object.
self.people = data.results;
})
}
})
new Vue({
el:"#star-wars-people",
data:{
people: null
},
mounted:function(){
$.getJSON("http://swapi.co/api/people/", function(data){
this.people = data.results;
}.bind(this));
}
})
new Vue({
el:"#star-wars-people",
data:{
people: null
},
mounted: function(){
$.getJSON("http://swapi.co/api/people/", data => this.people = data.results);
}
})
¡Precaución! Las funciones de flecha son una sintaxis introducida en Ecmascript 2015. Todavía
no es compatible con todos los navegadores modernos, así que solo úselo si está apuntando a un
navegador que sabe que lo soporta, o si está compilando su javascript hasta la sintaxis de ES5
usando algo como babel .
new Vue({
https://riptutorial.com/es/home 69
el:"#app",
data:{
foo: "bar"
},
methods:{
// This is wrong! Arrow functions capture "this" lexically
// and "this" will refer to the window.
doSomething: () => this.foo = "baz"
}
})
new Vue({
el:"#app",
data:{
foo: "bar"
},
methods:{
doSomething: function(){
this.foo = "baz"
}
}
})
new Vue({
el:"#app",
data:{
foo: "bar"
},
methods:{
doSomething(){
this.foo = "baz"
}
}
})
https://riptutorial.com/es/home 70
Capítulo 23: Vigilantes
Examples
Cómo funciona
Puedes ver la propiedad de datos de cualquier instancia de Vue. Al ver una propiedad, activa un
método al cambiar:
export default {
data () {
return {
watched: 'Hello World'
}
},
watch: {
'watched' () {
console.log('The watched property has changed')
}
}
}
export default {
data () {
return {
watched: 'Hello World'
}
},
watch: {
'watched' (value, oldValue) {
console.log(oldValue) // Hello World
console.log(value) // ByeBye World
}
},
mounted () {
this.watched = 'ByeBye World'
}
}
export default {
data () {
return {
someObject: {
message: 'Hello World'
}
}
},
watch: {
'someObject': {
https://riptutorial.com/es/home 71
deep: true,
handler (value, oldValue) {
console.log('Something changed in someObject')
}
}
}
}
Si necesita activar el observador antes de realizar algunos cambios nuevos en un objeto, debe
usar el método nextTick() :
export default {
data() {
return {
foo: 'bar',
message: 'from data'
}
},
methods: {
action () {
this.foo = 'changed'
// If you juste this.message = 'from method' here, the watcher is executed after.
this.$nextTick(() => {
this.message = 'from method'
})
}
},
watch: {
foo () {
this.message = 'from watcher'
}
}
}
https://riptutorial.com/es/home 72
Capítulo 24: Vue componentes de un solo
archivo
Introducción
Describe cómo crear componentes de un solo archivo en un archivo .vue.
Examples
Ejemplo de archivo componente .vue
<template>
<div class="nice">Component {{title}}</div>
</template>
<script>
export default {
data() {
return {
title: "awesome!"
};
}
}
</script>
<style>
.nice {
background-color: red;
font-size: 48px;
}
</style>
https://riptutorial.com/es/home 73
Capítulo 25: VueJS + Redux con Vua-Redux
(la mejor solución)
Examples
Cómo utilizar Vua-Redux
Inicializar:
===============
// main.js
// install vua-redux
Vue.use(reduxStorePlugin);
new Vue({
store: AppStore,
render(h) {
return <App />
}
});
// AppStore.js
const initialState = {
todos: []
};
https://riptutorial.com/es/home 74
default:
return state;
}
}
Use en su componente:
// componentes / App.js
const App = {
props: ['some-prop', 'another-prop'],
/**
* everything you do with vue component props
* you can do inside collect key
*/
collect: {
todos: {
type: Array,
},
addTodo: {
type: Function,
},
},
methods: {
handleAddTodo() {
const todo = this.$refs.input.value;
this.addTodo(todo);
}
},
render(h) {
return <div>
<ul>
{this.todos.map(todo => <li>{todo}</li>)}
</ul>
<div>
<input type="text" ref="input" />
<button on-click={this.handleAddTodo}>add todo</button>
</div>
</div>
}
};
function mapStateAsProps(state) {
return {
todos: state.todos
};
}
function mapActionsAsProps(dispatch) {
return {
https://riptutorial.com/es/home 75
addTodo(todo) {
dispatch({
type: 'ADD_TODO',
data: { todo }
})
}
}
}
Lea VueJS + Redux con Vua-Redux (la mejor solución) en línea: https://riptutorial.com/es/vue-
js/topic/7396/vuejs-plus-redux-con-vua-redux--la-mejor-solucion-
https://riptutorial.com/es/home 76
Capítulo 26: Vuex
Introducción
Vuex es una biblioteca de patrones de administración de estado para aplicaciones Vue.js. Sirve
como un almacén centralizado para todos los componentes de una aplicación, con reglas que
garantizan que el estado solo se puede mutar de manera predecible. También se integra con la
extensión de herramientas de desarrollo oficial de Vue para proporcionar funciones avanzadas
como la depuración de viajes en tiempo de configuración cero y la exportación / importación de
instantáneas de estado.
Examples
¿Qué es Vuex?
Vuex es un complemento oficial para Vue.js que ofrece un almacén de datos centralizado para
usar dentro de su aplicación. Está muy influido por la arquitectura de la aplicación Flux, que
presenta un flujo de datos unidireccional que conduce a un diseño y un razonamiento más
simples.
Dentro de una aplicación Vuex, el almacén de datos contiene todo el estado de la aplicación
compartida . Este estado se altera por las mutaciones que se realizan en respuesta a una
acción que invoca un evento de mutación a través del despachador .
Un ejemplo del flujo de datos en una aplicación Vuex se describe en el diagrama a continuación.
https://riptutorial.com/es/home 77
https://riptutorial.com/es/home 78
Diagrama utilizado bajo la licencia MIT , originalmente del repositorio oficial de Vuex GitHub .
Los componentes individuales de la aplicación Vue.js pueden acceder al objeto de la tienda para
recuperar datos a través de captadores , que son funciones puras que devuelven una copia de
solo lectura de los datos deseados.
Los componentes pueden tener acciones que son funciones que realizan cambios en la propia
copia de los datos del componente, luego usan el despachador para enviar un evento de
mutación. Este evento es manejado por el almacén de datos que actualiza el estado según sea
necesario.
Los cambios se reflejan automáticamente en toda la aplicación, ya que todos los componentes
están vinculados de forma reactiva a la tienda a través de sus captadores.
const state = {
lastClickTime: null
}
const mutations = {
updateLastClickTime: (state, payload) => {
state.lastClickTime = payload
}
}
const getters = {
getLastClickTime: state => {
return new Date(state.lastClickTime)
}
}
const actions = {
syncUpdateTime: ({ commit }, payload) => {
commit("updateLastClickTime", payload)
},
asyncUpdateTime: ({ commit }, payload) => {
setTimeout(() => {
commit("updateLastClickTime", payload)
}, Math.random() * 5000)
}
}
// Vue
const vm = new Vue({
el: '#container',
store,
https://riptutorial.com/es/home 79
computed: {
...mapGetters([
'getLastClickTime'
])
},
methods: {
...mapActions([
'syncUpdateTime',
'asyncUpdateTime'
]),
updateTimeSyncTest () {
this.syncUpdateTime(Date.now())
},
updateTimeAsyncTest () {
this.asyncUpdateTime(Date.now())
}
}
})
<div id="container">
<p>{{ getLastClickTime || "No time selected yet" }}</p>
<button @click="updateTimeSyncTest">Sync Action test</button>
<button @click="updateTimeAsyncTest">Async Action test</button>
</div>
2. El captador utilizado proporciona una propiedad calculada que se actualizará cada vez que
una mutación actualice el valor de la propiedad estatal.
3. Solo se permite que las mutaciones cambien el estado y sus propiedades, dicho esto, solo
lo hace de forma síncrona .
Al crear aplicaciones de gran tamaño, como las aplicaciones de una sola página (SPA), que
suelen constar de muchos componentes reutilizables, se pueden volver difíciles de construir y
mantener rápidamente. El intercambio de datos y el estado entre estos componentes también
puede descomponerse rápidamente y ser difícil de depurar y mantener.
https://riptutorial.com/es/home 80
se puede representar en un solo lugar, lo que hace que la aplicación esté más organizada.
Mediante el uso de un flujo de datos unidireccional, las mutaciones y el acceso a los datos del
componente de alcance solo a los datos requeridos, se vuelve mucho más sencillo razonar sobre
el rol del componente y cómo debe afectar el estado de la aplicación.
Los componentes de VueJS son entidades separadas y no pueden compartir datos entre sí
fácilmente. Para compartir datos sin vuex necesitamos emit evento con datos y luego escuchar y
capturar ese evento con on .
componente 1
this.$emit('eventWithDataObject', dataObject)
componente 2
Con vuex instalado, simplemente podemos acceder a sus datos desde cualquier componente sin
necesidad de escuchar los eventos.
this.$store.state.myData
También podemos cambiar los datos de forma sincronizada con mutadores, utilizar las acciones
asíncronos y obtener datos con funciones getter.
Las funciones de Getter podrían funcionar como funciones globales computadas. Podemos
acceder a ellos desde componentes:
this.$store.getters.myGetter
this.$store.dispatch('myAction', myDataObject)
Y las mutaciones son la única forma de cambiar los datos en vuex. Podemos confirmar los
cambios:
this.$store.commit('myMutation', myDataObject)
state: {
myData: {
key: 'val'
}
},
getters: {
https://riptutorial.com/es/home 81
myGetter: state => {
return state.myData.key.length
}
},
actions: {
myAction ({ commit }, myDataObject) {
setTimeout(() => {
commit('myMutation', myDataObject)
}, 2000)
}
},
mutations: {
myMutation (state, myDataObject) {
state.myData = myDataObject
}
}
La mayor parte del tiempo que utilizará Vuex estará en aplicaciones basadas en componentes
más grandes donde probablemente esté utilizando un paquete de paquetes como Webpack o
Browserify junto con Vueify si está usando archivos individuales.
En este caso, la forma más fácil de obtener Vuex es desde NPM. Ejecute el siguiente comando
para instalar Vuex y guárdelo en las dependencias de su aplicación.
Asegúrese de cargar el enlace de Vuex con su configuración de Vue colocando la siguiente línea
después de su declaración de require('vue') .
Vue.use(require('vuex'))
Vuex también está disponible en CDN; Puede obtener la última versión de cdnjs aquí .
notificaciones.js
https://riptutorial.com/es/home 82
establecer el estado inicial de nuestro módulo
const state = {
Notifications: []
}
const getters = {
//All notifications, we are returning only the raw notification objects
Notifications: state => state.Notifications.map(n => n.Raw)
}
const actions = {
//On actions we receive a context object which exposes the
//same set of methods/properties on the store instance
//{commit} is a shorthand for context.commit, this is an
//ES2015 feature called argument destructuring
Add({ commit }, notification) {
//Get notification duration or use default duration
let duration = notification.duration || defaultDuration
const mutations = {
//On mutations we receive current state and a payload
[NOTIFICATION_ADDED](state, notification) {
state.Notifications.push(notification);
},
//remember, current state and payload
[NOTIFICATION_DISMISSED](state, rawNotification) {
var i = state.Notifications.map(n => n.Raw).indexOf(rawNotification);
if (i == -1) {
return;
}
https://riptutorial.com/es/home 83
clearTimeout(state.Notifications[i].TimeOut);
state.Notifications.splice(i, 1);
}
}
_store.registerModule('notifications', {
state,
getters,
actions,
mutations
});
Uso
componenteA.vue
Este componente muestra todas las notificaciones como alertas de bootstrap en la esquina
superior derecha de la pantalla, también permite descartar manualmente cada notificación.
<template>
<transition-group name="notification-list" tag="div" class="top-right">
<div v-for="alert in alerts" v-bind:key="alert" class="notification alert alert-dismissible"
v-bind:class="'alert-'+alert.type">
<button v-on:click="dismiss(alert)" type="button" class="close" aria-label="Close"><span
aria-hidden="true">×</span></button>
<div>
<div>
<strong>{{alert.title}}</strong>
</div>
<div>
{{alert.text}}
</div>
</div>
</div>
</transition-group>
</template>
<script>
export default {
name: 'arc-notifications',
computed: {
alerts() {
//Get all notifications from store
return this.$store.getters.Notifications;
}
},
methods: {
//Manually dismiss a notification
dismiss(alert) {
this.$store.dispatch('Dismiss', alert);
}
}
}
</script>
<style lang="scss" scoped>
https://riptutorial.com/es/home 84
$margin: 15px;
.top-right {
top: $margin;
right: $margin;
left: auto;
width: 300px;
//height: 600px;
position: absolute;
opacity: 0.95;
z-index: 100;
display: flex;
flex-wrap: wrap;
//background-color: red;
}
.notification {
transition: all 0.8s;
display: flex;
width: 100%;
position: relative;
margin-bottom: 10px;
.close {
position: absolute;
right: 10px;
top: 5px;
}
> div {
position: relative;
display: inline;
}
}
.notification:last-child {
margin-bottom: 0;
}
.notification-list-enter,
.notification-list-leave-active {
opacity: 0;
transform: translateX(-90px);
}
.notification-list-leave-active {
position: absolute;
}
</style>
https://riptutorial.com/es/home 85
Creditos
S.
Capítulos Contributors
No
4 Complementos AldoRomo88
Componentes
6 Med, Ru Chern Chong
dinámicos
Componentes
7 personalizados con Amresh Venugopal
v-modelo
Directivas
8 Mat J, Ogie Sado
personalizadas
11 Eventos Elfayer
Filtros
12 Finrod, M U, m_callens
personalizados
Ganchos de ciclo de
13 Linus Borg, m_callens, PatrickSteele, xtreak
vida
Las advertencias de
14 detección de cambio Vamsi Krishna
de matriz
https://riptutorial.com/es/home 86
16 Modificadores sept08
Plantilla "webpack"
17 Stefano Nepa
de polyfill
Representación
20 jaredsk, m_callens, Nirazul, user6939352
condicional
Representación de
21 chuanxd, gurghet, Mahmoud, Theo
lista
Usando "esto" en
22 Bert
Vue
23 Vigilantes El_Matella
Vue componentes de
24 jordiburgos, Ru Chern Chong
un solo archivo
https://riptutorial.com/es/home 87