Taller iniciació VueJS

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

Requeriments

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

NodeJS

https://nodejs.org/es/download/package-manager/

 

 

Projecte d'exemple

https://github.com/manelclos/todos_vuejs

 

Instal·lar vue-cli

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

npm install @vue/cli -g

Instal·lar la línia de comandes de Vue, globalment:

Comprovar la versió:

vue --version

Crear un projecte

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

vue create todos_vuejs

> default (babel, eslint)

cd todos_vuejs

npm run serve

Estructura

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

git checkout 1-init

TodoList template

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

<template>
  <div class="todo-list">
    <h1>{{ title }}</h1>
    <ul>
      <li
        v-for="todo in todos"
        :key="todo.description">
        <div>{{ todo.due_date }}</div>
        <div
          class="todo-description"
          >{{ todo.description }}</div>
      </li>
    </ul>
  </div>
</template>

git checkout 2-todolist

TodoList script

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

<script>
export default {
  name: 'TodoList',
  props: {
    title: String
  },
  data: function () {
    return {
      todos: [
        {
          description: 'Preparar taller VueJS',
          due_date: '2018-12-10',
        },
        {
          description: 'Enviar correu recordatori sobre portàtils, etc.',
          due_date: '2018-12-12',
        },
        {
          description: 'Taller VueJS - UdG',
          due_date: '2018-12-13',
        },
      ]
    }
  }
}
</script>

TodoList style

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
ul {
  list-style-type: none;
  padding: 0;
  width: 600px;
  margin-left: auto;
  margin-right: auto;
}
li {
  display: flex;
  padding: 5px 0;
}
.todo-description {
  margin-left: 15px;
}
</style>

Formulari per afegir

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

template:
    <form>
      Due date: <input v-model="dueDate" type="date" />
      Description: <input v-model="description" size="50" />
      <button
        @click.prevent="onAdd"
        >Afegir</button>
    </form>


script:
      dueDate: '',
      description: '',

  methods: {
    onAdd () {
      this.todos.push({
        description: this.description,
        due_date: this.dueDate
      })
    }
  }

git checkout 3-afegir

Botó per esborrar

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

template:
        <div>
          <button
            @click="onRemoveItem(todo.id)"
          >X</button>
        </div>



script:
    onRemoveItem (id) {
      this.todos = this.todos.filter(item => {
      	return item.id !== id
      })
    }

git checkout 4-esborrar

Ordenar la llista

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

template:
        v-for="todo in todosSorted"


script:
  computed: {
    todosSorted () {
      return this.todos.sort((a, b) => {
        if (a.due_date < b.due_date) {
          return -1
        }
        if (a.due_date > b.due_date) {
          return 1
        }
        return 0
      })
    }
  },

git checkout 5-ordenar

Refactor todo-item

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

<template>
  <li
    :key="todo.id">
    <div>
      <button
        @click="$emit('remove', todo.id)"
      >X</button>
    </div>
    <div>{{ todo.due_date }}</div>
    <div
      class="todo-description"
      >{{ todo.description }}</div>
  </li>
</template>

<script>
export default {
  name: 'TodoItem',
  props: ['todo']
}
</script>

<style scoped>
li {
  display: flex;
  padding: 5px 0;
}
.todo-description {
  margin-left: 15px;
}
</style>

git checkout 6-item-refactor

Refactor todo-item (II)

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

template:
    <ul>
      <todo-item
        v-for="todo in todosSorted"
        :key="todo.id"
        :todo="todo"
        @remove="onRemoveItem"
      >
      </todo-item>
    </ul>

script:
import TodoItem from './TodoItem.vue'

export default {
  name: 'TodoList',
  components: {
    TodoItem
  },

Open Source

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

apliclient.js de todos_react

https://github.com/pygrn/todos_react/blob/master/src/lib/apiclient.js

Autor: Francesc Arpí

 

Copiar a src/lib

git checkout 7-apiclient

apiclient.js

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

TodoList.vue script:
import apiclient from '../lib/apiclient.js'
...
  created () {
    this.refreshTodos()
  },
  methods: {
    onAdd () {
      apiclient.createTodo({
          description: this.description,
          dueDate: this.dueDate,
          dueTime: '00:00:00Z'
      })
        .then(response => {
          this.refreshTodos()
        })
    },
...
    refreshTodos () {
      apiclient.getTodos()
        .then(data => {
          this.todos = data
        })

Esborrar amb l'API

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

apiclient.js:
...
  deleteTodo(pk) {
    return fetch('https://server3.microdisseny.com/apps/todos/api/v1/todos/' + pk, {
      method: 'delete',
      headers: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json'
      }
    })
  }


TodoList.vue:
...
      apiclient.deleteTodo(pk)
        .then(response => {
          this.refreshTodos()
        })

git checkout 8-esborrar-api

Vue Router

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

App.vue:

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/edit">Edit</router-link>
    </div>
    <router-view/>
  </div>
</template>

vue add router

> history mode? No

git checkout 9-vue-router

Vue Router II

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

Home.vue:

<template>
  <div class="home">
    <todo-list title="Python Girona TODO list"></todo-list>
  </div>
</template>

<script>
import TodoList from '@/components/TodoList.vue'

export default {
  name: 'home',
  components: {
    TodoList
  }
}
</script>

Edit.vue:

<template>
  <div class="edit-todo">
    <h1>Edit TODO</h1>
  </div>
</template>

Edit Todo

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

TodoForm.vue:
<template>
  <div class="todo-list">
    <form>
      Due date: <input v-model="dueDate" />
      Description: <input v-model="description" size="50" />
      <button
        @click.prevent="onSave"
        >Save</button>
    </form>
  </div>
</template>

<script>
import apiclient from '../lib/apiclient.js'

export default {
  name: 'TodoForm',
  props: ['todo'],
  data: function () {
    return {
      dueDate: this.todo.due_date,
      description: this.todo.description
    }
  },
  methods: {
    onSave () {
      this.$emit('input', {
        description: this.description,
        dueDate: this.dueDate
      })
    }
  }
}
</script>

git checkout 10-edit-todo

Edit Todo II

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

TodoItem.vue:
...
    <div><router-link :to="{ name: 'edit', params: { pk: todo.pk } }">{{ todo.due_date }}</router-link></div>

router.js:
...
      path: '/edit/:pk',


apiclient.js
...
  getTodo(pk) {
    return fetch('https://server3.microdisseny.com/apps/todos/api/v1/todos/' + pk).then(response => response.json())
  }

  updateTodo(pk, formData) {
    const data = {
      description: formData.description,
      due_date: `${formData.dueDate}`
    }
    return fetch('https://server3.microdisseny.com/apps/todos/api/v1/todos/' + pk + '/', {
      method: 'put',
      headers: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    })
  }

Edit Todo III

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

Edit.vue:
<template>
  <div class="edit-todo">
    <h1>Edit TODO</h1>
    <todo-form
      v-if="todo"
      :todo="todo"
      @input='onChanged'
      ></todo-form>
  </div>
</template>

<script>
import apiclient from '../lib/apiclient.js'
import TodoForm from '@/components/TodoForm.vue'

export default {
  name: 'home',
  components: {
    TodoForm
  },
  data: function () {
    return {
      todo: null
    }
  },
  created () {
    apiclient.getTodo(this.$route.params.pk)
      .then(data => {
        this.todo = data
      })
  },
  methods: {
    onChanged (todo) {
      apiclient.updateTodo(this.todo.pk, {
        description: todo.description,
        dueDate: todo.dueDate,
      })
        .then(() => {
          this.$router.push({name: 'home'})
        })
    }
  }
}
</script>

Més

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

VueX

Vuetify

NuxtJS

Quasar Framework

...

Gràcies!

Python Girona - 13/12/2018 - Taller iniciació VueJS - Manel Clos

Taller iniciació VueJS

By Manel Clos

Taller iniciació VueJS

  • 495