Tạo ứng dụng effect đẹp mắt với Transitions & Animation - VueJS
Bài đăng này đã không được cập nhật trong 6 năm
Giới thiệu
Tiếp tục trong series 2018 - Cùng nhau học VueJS, hôm nay mình sẽ tạo một ứng dụng nho nhỏ với Transitions & Animation. Link github: https://github.com/vanquynguyen/vue-cli-timetable . Link demo: https://vanquynguyen.github.io/vue-cli-timetable Ứng dụng có kết hợp giữa VueCLI, event handling, Form Input Bindings và Transitions & Animation.
Nội dung
Khởi tạo VueCLI Trước khi tạo một VueCLI, đảm bảo rằng bạn đã cài npm hoặc yarn. Mình thì dùng npm =)), bạn nào cài yarn thì vào đây nhé https://yarnpkg.com/en/. Kiểm tra xem máy của bạn đã cài đặt nodejs và npm chưa
$ nodejs -v
v9.4.0
$ npm -v
5.6.0
Cài đặt vue-cli
$ npm install -g vue-cli
Sau khi cài đặt xong dùng lệnh bên dưới để tạo 1 project vue-cli
$ vue init webpack vue-cli-timetable
Trong file App.vue:
<template>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3">
<h1>Time table ({{tasks.length}})</h1>
<hr>
<br><br>
</div>
</div>
<form @submit="addTask">
<div class="form-group">
<input v-model="newTask" class="form-control" placeholder="Tôi muốn...">
</div>
</form>
<button class="btn btn-danger" @click="shuffle">Đổi chỗ</button>
<div v-for="(check, index) in checks" v-bind:key="index">
<input type="checkbox" v-model="checked" v-bind:value="check" />
{{check}}
</div>
<span>Checked: {{ checked }}</span>
<div class="row">
<div class="form-group">
<div class="searchable-container">
<transition-group name="list-complete" tag="p">
<div class="tasks col-xs-5 col-sm-5 col-md-2 col-lg-2" v-for="(task, index) in filteredTasks" v-bind:key="index">
<div class="info-block block-info clearfix">
<div class="square-box pull-left">
<span class="glyphicon glyphicon-tags glyphicon-lg"></span>
<span class="glyphicon glyphicon-trash glyphicon-lg" @click="removeTask(index)"></span>
</div>
<div data-toggle="buttons" class="btn-group bizmoduleselect">
<label class="btn btn-default" id="check" @click="checkBox(index)">
<div class="bizcontent">
<input type="checkbox" autocomplete="off">
<span class="glyphicon glyphicon-ok glyphicon-lg"></span>
<h5>{{task.body}}</h5>
</div>
</label>
</div>
</div>
<br>
</div>
</transition-group>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
tasks: [
{body:"Ăn cơm", check:"Unchecked", completed: false},
{body:"Tán gái", check:"Unchecked", completed: false},
{body:"Lướt face", check:"Unchecked", completed: false},
{body:"Học Vue", check:"Unchecked", completed: false},
{body:"Ngắm gái", check:"Unchecked", completed: false},
{body:"Nhậu", check:"Unchecked", completed: false},
{body:"Học Laravel", check:"Unchecked", completed: false},
{body:"Ngủ", check:"Unchecked", completed: false},
{body:"Play game", check:"Unchecked", completed: false},
{body:"Play girl", check:"Unchecked", completed: false},
],
checks: ['Checked', 'Unchecked'],
newTask: '',
checked: [],
}
},
computed: {
filteredTasks(){
let filterTasks = this.tasks;
$.each(this.checked, function(value, key){
filterTasks= filterTasks.filter(function(task){
return task.check == key;
})
});
return filterTasks;
}
},
methods: {
checkBox(indexTask) {
this.tasks[indexTask].check = 'Checked';
},
addTask(e){
e.preventDefault();
this.tasks.push({
body: this.newTask,
check: "Unchecked",
completed: false
});
this.newTask = '';
},
removeTask(index) {
Vue.delete(this.tasks, index);
},
shuffle() {
this.tasks = _.shuffle(this.tasks)
},
}
}
</script>
Import file App.vue và style.css vào file main.js
import Vue from 'vue'
import App from './App.vue'
import './style.css';
new Vue({
el: '#app',
render: h => h(App)
})
Đừng quên viết css cho ứng dụng, tạo file style.css
ul li {
list-style-type: none;
}
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active below version 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
.searchable-container{margin:20px 0 0 0}
.searchable-container label.btn-default.active{background-color:#007ba7;color:#FFF}
.searchable-container label.btn-default{width:90%;border:1px solid #efefef;margin:5px; box-shadow:5px 8px 8px 0 #ccc;}
.searchable-container label .bizcontent{width:100%;}
.searchable-container .btn-group{width:90%}
.searchable-container .btn span.glyphicon{
opacity: 0;
}
.searchable-container .btn.active span.glyphicon {
opacity: 1;
}
.tasks {
transition: all 1s;
display: inline-block;
margin-right: 10px;
}
.list-complete-enter, .list-complete-leave-to
/* .list-complete-leave-active below version 2.1.8 */ {
opacity: 0;
transform: translateY(30px);
}
.list-complete-leave-active {
position: absolute;
}
.row {
padding-left: 122px;
}
Cuối cùng là file index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue-cli</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
</head>
<body>
<div id="app"></div>
<script src="dist/build.js"></script>
</body>
</html>
Lời kết
:face_with_hand_over_mouth::face_with_hand_over_mouth::face_with_hand_over_mouth: Hãy theo dõi series 2018 - Cùng nhau học VueJS cùng học tập và góp ý để nâng cao kiến thức về VueJs.
All rights reserved