سلام به شما عزیزان، در این آموزش قصد داریم نحوهی ساخت یک نرم افزار یا اپلیکیشن To Do List را به کمک فریم ورک بسیار قدرتمند Vue.js 2 به صورت رایگان در اختیار همراهان همیشگی روکسو قرار دهیم. این آموزش بنا به درخواست کاربران بسیار ارزشمند روکسو تهیه شده است.
با توجه به اینکه قبل از شروع هر مسیری باید پیشنیازهای آن را فرا بگیرید، لازم دانستیم تا در این فصل توضیح مختصری در ارتباط با این پیشنیازها داده و بیشتر با فریم ورک Vue.js آشنا شویم تا مخاطبان به طور کامل در جریان مباحث مربوط به این فریم ورک قرار گیرند. لازم به ذکر است این پیشنیازها در بخش های دیگر این وب سایت به صورت مفصل و با فصل بندی مشخص آموزش داده شدهاند. لذا برای دستیابی به آنها کافیست روی منوی بالای سایت ایستاده و بخش موردنظر خود را انتخاب کنید.
Vue تحت عنوان یک فریم بسیار قدرتمند و سبک شناخته شده که برای ساختن انواع اپلیکیشنهای پیچیده مورد استفاده قرار میگیرد. از طرفی این فریم به نسبت سایر فریمورکهای جاوا اسکریپت مانند انگولار بسیار ساده میباشد که با دانش مناسبی نسبت به زبانهای HTML ،CSS و JavaScript میتوان از آن بهره برد.
هدف از ارائهی این مقاله ساخت نرم افزار "To Do List" با استفاده از ابزار فریم ورک Vue js ضمن برجستهکردن نقاط قوت آن است.
خودت رو آماده کن!
برای شروع کار با فریم ورک Vue js ابتدا به یک ابزار فرمان کنترلی به نام Vue CLI نیاز داریم. CLI یک چارچوب سریع برای صفحاتی که شامل این فریم میشوند را فراهم میکند و شما در هر زمانی بدون نیاز به لود کردن یا سیو کردن خطوط برنامه، به صورت آنلاین تغییرات را مشاهده میکنید.
Vue CLI تنظیمات اولیهای را به صورت خودکار برای پیشروی سریع روی نرم افزار و کامپوننتهای Vue، اعمال میکند. همچنین این ابزار فرمان شامل آرایهای از قالبها (Templates) میباشد که باعث خودکفایی نرم افزار شما میشود. این قالبها شامل موارد زیر هستند:
Webpack: یک پکیچ با ویژگیهای کامل به همراه Vue-Loader میباشد که از Refresh کردن صفحه پس از اعمال تغییرات خودداری کرده و تغییرات ره به صورت آنلاین روی صفحهی مانیتور نمایش میدهد. همچنین از این ابزار برای تست کردن و استخراج CSS استفاده میشود.
Webpack-simple: یک پکیج ساده به همراه Vue-Loader بوده که برای پروتوتایپ سریع مورد استفاده قرار میگیرد.
Browserify: یک پکیج با ویژگیهای کامل به همراه vueify جهت جلوگیری از بارگذاری مجدد صفحه میباشد.
Browserify-simple: به عنوان یک پکیج ساده به همراه vueify جهت بهرهمندی از پروتوتایپ سریع میباشد.
simple: به عنوان یک سیستم نصبی برای اجرای Vue در یک صفحه ساده HTML مورد استفاده قرار میگیرد.
سادهترین راه برای نصب Vue CLI بهرهمندی از node میباشد. برای اینکار ابتدا node را مخصوص ویندوز یا لینوکس دانلود کرده و سپس آن را در سیستم عامل موردنظر خود نصب کنید. پس از انجام این کار به فولدر مشخصی که میتواند داخل هر مسیری تعریف شده باشد رفته و cmd یا همان خط فرمان را درون آن باز کنید. سپس دستور زیر را تایپ کرده تا Vue CLI نصب شود.
# install vue-cli $ npm install --global vue-cli
توجه داشته باشید که در این سری آموزشی تمرکز ما روی صفحات تک کامپوننتی یا به عبارتی Single File Component میباشد. همچنین در این بخشها به توضیح و نحوهی استفاده از کامپوننتهای والد و فرزند و تبادل اطلاعات بین آنها میپردازیم. به دلیل وجود قابلیت Single File Component یادگیری این فریمورک روند بسیار ملایمی دارند و اصلا شما را دچار سردرگمی نمیکند. علاوه بر این قابلیت به شما اجازه میدهد تا در هر قسمت از کد خود بتوانید کامپوننت موردنظر را استفاده کنید. این ویژگی زمانی مشهود و بارز خواهد بود که حجم پروژه شما بسیار بزرگ باشد.
مرحلهی بعدی نصب Vue روی اپلیکیشن شما با استفاده از CLI است:
ساخته پروژه با استفاده از Webpack $ vue init webpack todo-app
با اجرای دستور فوق در خط فرمان ابتدا از شما نام پروژه و سپس توضیحات مربوط به آن و در نهایت نام نویسنده پرسیده میشود. پس از پاسخگویی به این سوالات پروژهی Vue شما ساخته خواهد شد. اما هنوز Vue-router یا همان مسیرده آدرسهای Vue نصب نشده است. همچنین باید ویژگیهای Linting و Testing را روی نرمافزار خود فعال کنید. برای اینکار یک تنظیمات اولیه پیشفرض اعمال کرده تا سایر وابستگیهای موردنیاز نصب شوند. توجه داشته باشید به جای عبارت my-project باید نام فولدر خود را قرار دهید:
نصب تمام وابستگی های مربوط به پروژه با استفاده از Node $ cd my-project $ npm install
حال برای اجرای سرور node از دستور زیر استفاده میکنیم:
$ npm run dev
پس از اجرای این دستور مرورگر سریعا به مسیر http://localhost:8080 تغییر مسیر داده و صفحهی شامل پیام نصب Vue js برای شما نمایش داده میشود.
هر نرم افزاری که از فریم ورک Vue استفاده میکند به یک کامپوننت با بالاترین سطح (Top Level) جهت اجرا و طبقهبندی نرمافزار نیاز دارد. برای نرمافزار شما، یک کامپوننت اصلی به همراه کامپوننت تودرتو تحت عنوان TodoListComponent ارائه کردهایم.
حالا موقع شیرجه زدن توی دریای اپلیکیشن Vue فرا رسیده است. در ابتدا با کامپوننت سطح بالا شروع میکنیم. ابزار فرمان Vue CLI هم اکنون یک کامپوننت اصلی درون مسیر src/App.vue برای شما ایجاد کرده است. بنابراین ما سایر کامپوننتهای ضروری را ایجاد میکنیم.
ابزار فرمان Vue CLI یک کامپوننت تحت عنوان Hello در مسیر src/components/Hello.vue ایجاد کرده است. اما به هر حال ما کامپوننت خودمان را تحت عنوان TodoList.vue ایجاد میکنیم.
فایل جدید TodoList.vue را باز کرده و کدهای زیر را درون آن قرار میدهیم:
<template> <div> <ul> <li> خرید از فروشگاه اینترنتی آفر</li> <li>مطالعه مقاله های لاراول در روکسو</li> <li>دانلود آهنگ از وب سایت ادبی هنری پرسه</li> </ul> </div> </template> <style> </style> <script> export default{} </script>
همانطور که ملاحظه میکنید این کامپوننت از سه بخش کلی تشکیل شده است: قالب (Template)، کلاس و استایل. قالبها به طور عامیانه بخش HTML یک کامپوننت را تشکیل میدهند. تراکنشها، رویدادها، متدها و تبادل یا ذخیره اطلاعات موجود در قالبها با استفاده از کلاسها صورت میپذیرد و در نهایت استایلها برای بهبود ظاهر مورد استفاده قرار میگیرند.
برای استفاده از یک کامپوننت باید آن را ساخته و سپس با استفاده از دستور import عملیات فراخوانی را درون کامپوننت اصلی انجام دهیم. برای اینکار به کامپوننت اصلی App.vue در مسیر src/App.vue رفته و سپس تغییرات زیر را اعمال میکنیم:
// اضافه کردن این خط import TodoList from './components/TodoList' // حذف این خط import Hello from './components/Hello'
علاوه بر این کار باید در بخش components داخل کلاس پیشفرض کلاس کامپوننت اصلی (App.vue)، نام کامپوننتهای مورد استفاده را ذکر کنید. بنابراین داریم:
<script> import TodoList from './components/TodoList' export default { name: 'app', components: { TodoList } } </script>
توجه داشته باشید که دستور import را باید در تگ <script> قرار دهید. هم اکنون برای اضافه کردن کامپوننت TodoList باید تگ تعریف شده درون آن کامپوننت را به صورت قالب HTML به قالب کامپوننت اصلی اضافه میکنیم. توجه داشته باشید که اگر به عنوان مثال نام کامپوننت شما به صورت TodoList باشد، باید نام تگ آن را به صورت <todo-list> تعریف کنید. به عبارت خودمانی تر به ازای هر حرف بزرگ یک دش یا - اضافه میکنیم:
<template> <div> // Render the TodoList component // TodoList becomes <todo-list></todo-list> </div> </template>
حال نیاز داریم که اطلاعات و دادههایی را به نرمافزار خود اضافه کنیم. مثلا میخواهیم یک فعالیت روزانه را اضافه کنیم. در این صورت باید یک فرم درست کرده تا بتوانیم اطلاعات را درج و درون صفحه نمایش دهیم. بنابراین فرم موردنظر باید دارای بخشی برای درج عنوان فعالیت، بخشی برای توضیحات مربوط به آن فعالیت و یک گزینه برای تایید آن که آیا این فعالیت را انجام دادهاید یا خیر. بنابراین در بخش مربوط به data که در فریم ورک Vue Js محلی برای ذخیره و جابهجایی اطلاعات است خواهیم داشت:
export default { name: 'app', components: { TodoList, }, // data function avails data to the template data() { return { todos: [{ title: 'Todo A', project: 'Project A', done: false, }, { title: 'Todo B', project: 'Project B', done: true, }, { title: 'Todo C', project: 'Project C', done: false, }, { title: 'Todo D', project: 'Project D', done: false, }], }; }, };
حال باید روشی برای ارسال اطلاعات از کامپوننت اصلی به کامپوننت TodoList ارائه دهیم. برای این کار از دستور v-bind استفاده میکنیم. این دستور یک آرگومان میگیرد پس از علامت کولن (:) نوشته میشود. در این مثال آرگومان ما todos میباشد که به دستور v-bind میگوید: صفات المانهای todo را به مقادیر عبارتهای با قاعده todos وصل و ارسال کن! به عبارت سادهتر: هر آنچه به عنوان ورودی روی تگ <todo-list> قرار گرفت را به عنوان داده درنظر گرفته و ارسال کن! بنابراین در ادامه، کد مربوط به تگ <todos> را به صورت زیر ویرایش میکنیم:
<todo-list v-bind:todos="todos"></todo-list>
حال متغییر یا عبارت todosدرون کامپوننت TodoList تحت عنوان todos در دسترس خواهد بود. با اینکار اطلاعات را از کامپوننت اصلی به کامپوننت فرزند ارسال کردهایم. یعنی هر اطلاعاتی که درون کامپوننت اصلی جابهجا شود و به تگ <todos-list> ارتباط داشته باشد، به کامپوننت فرزند TodoList ارسال میشود. پس از انجام این کار نوبت به تغییر و ویرایش data یا دادهی ورودی کامپوننت فرزند میرسد. تا این اطلاعات را دریافت کرده و درون خود به صورت مجازی ذخیره کند و در صورت لزوم از آن استفاده شود. در کامپوننت TodoList برای ذخیرهسازی مجازی و استفاده از دادههای ارسالی از کامپوننت والد باید از یک ویژگی به نام props استفاده کرد. این ویژگی باعث میشود هر آنچه از کامپوننت والد ارسال شود درون متغییر یا عبارتی به نام todos ذخیره گردد. بنابراین در فایل TodoList داریم:
درون قالب کامپوننت TodoList باید یک حلقه جهت پردازش مکرر وظایف Todo قرار داده شود تا اطلاعات دریافتی شامل یک سری وظایف و فعالیتهای انجام شده و انجام نشده را نمایش دهد. برای ایجاد حلقه در Vue js از دستور v-for استفاده میشود. سینتکس یا قواعد نحوی این دستور به صورت v-for="item in items میباشد که items به عنوان آرایهای از وظایف یا دادهها و item نمایشی از هر یک از المانهای این آرایه است که میخواهیم تکرار شوند. بنابراین درون فایل TodoList.vue تغییرات زیر را لحاظ میکنیم:
<template> <div> // JavaScript expressions in Vue are enclosed in double curly brackets. <p>Completed Tasks: {{todos.filter(todo => {return todo.done === true}).length}}</p> <p>Pending Tasks: {{todos.filter(todo => {return todo.done === false}).length}}</p> <div class='ui centered card' v-for="todo in todos"> <div class='content'> <div class='header'> {{ todo.title }} </div> <div class='meta'> {{ todo.project }} </div> <div class='extra content'> <span class='right floated edit icon'> <i class='edit icon'></i> </span> </div> </div> <div class='ui bottom attached green basic button' v-show="todo.done"> Completed </div> <div class='ui bottom attached red basic button' v-show="!todo.done"> Complete </div> </div> </template> <script type = "text/javascript" > export default { props: ['todos'], }; </script>
برای دستیابی به کدهای تمیزتر و افزایش دقت میخواهیم یک کامپوننت دیگر به نام Todo در مسیر src/component ایجاد کرده و قالب todo را به آن انتقال دهیم. بنابراین فایلی با نام Todo.vue در مسیر مذکور ایجاد میکنیم و سپس کدهای زیر را درون آن قرار میدهیم:
<template> <div class='ui centered card'> <div class='content'> <div class='header'> {{ todo.title }} </div> <div class='meta'> {{ todo.project }} </div> <div class='extra content'> <span class='right floated edit icon'> <i class='edit icon'></i> </span> </div> </div> <div class='ui bottom attached green basic button' v-show="todo.done"> Completed </div> <div class='ui bottom attached red basic button' v-show="!todo.done"> Complete </div> </div> </template> <script type="text/javascript"> export default { props: ['todo'], }; </script>
در کامپوننت TodoList باید کدها را برای استفاده از کامپوننت Todo بازبینی و ویرایش کنیم. همچنین نیاز به تغییر متغییر todos برای ارسال اطلاعات به کامپوننت Todo ضروری است. ما میتوانیم برای انجام اینکار از دستور و یا صفت v-for در هر کامپوننتی استفاده کنیم. بنابراین با این کار برای هر المان آرایه موجود اطلاعاتی به کامپوننت Todo ارسال میشود. این دستور به صورت زیر میباشد:
<todo v-for="todo in todos" :key="item.id"></todo>
در نسخه 2.2.0 و به بالا، یک کلید برای استفاده از v-for به همراه کامپوننتها مورد نیاز است. یک نکتهی کلیدی این است: تا زمانیکه کامپوننتها اسکوپ یا متغییرهای محلی خودشان را نداشته باشند، این دستور به صورت خودکار اطلاعات را به کامپونننت ارسال نمیکند. برای ارسال اطلاعات از عبارت props استفاده میکنیم:
<todos v-for="(item, index) in items" v-bind:item="item" v-bind:index="index"></todo>
با ارائهی دستور فوق اطلاعات به صورت ایزوله شده با دستور v-bind به کامپوننت فرزند Todo ارسال میشوند که شامل مقدار آرایه و ایندکس آن است. حال باید قالب کامپوننت TodoList را به صورت زیر ویرایش کنیم:
<template> <div> <p>Completed Tasks: {{todos.filter(todo => {return todo.done === true}).length}}</p> <p>Pending Tasks: {{todos.filter(todo => {return todo.done === false}).length}}</p> // we are now passing the data to the todo component to render the todo list <todo v-for="todo in todos" v-bind:todo="todo"></todo> </div> </template> <script type = "text/javascript" > import Todo from './Todo'; export default { props: ['todos'], components: { Todo, }, }; </script>
حال باید یک ویژگی به کلاس کامپوننت Todo که در مسیر src/components قرار گرفته است به نام isEditing ایجاد کنیم. این ویژگی تعیین میکند که آیا یک فعالیت مشخص در حال ادیت است یا خیر. همچنین یک رویداد روی دکمهی Edit یا ویرایش در قالب اعمال میکنیم. این رویداد هنگامیکه روی دکمهی ویرایش کلیک شود نمایش داده خواهد شد. هنگامیکه ادیت صورت پذیرت ویژگی isEditing به حالت true تبدیل میشود. قبل از اینکار یک فرم به همراه شرایط مشخصی جهت نمایش فعالیت یا ویرایش آن بسته به شرایط isEditing ایجاد میکنیم. قالب ما به صورت زیر خواهد بود:
<template> <div class='ui centered card'> // Todo shown when we are not in editing mode. <div class="content" v-show="!isEditing"> <div class='header'> {{ todo.title }} </div> <div class='meta'> {{ todo.project }} </div> <div class='extra content'> <span class='right floated edit icon' v-on:click="showForm"> <i class='edit icon'></i> </span> </div> </div> // form is visible when we are in editing mode <div class="content" v-show="isEditing"> <div class='ui form'> <div class='field'> <label>Title</label> <input type='text' v-model="todo.title" > </div> <div class='field'> <label>Project</label> <input type='text' v-model="todo.project" > </div> <div class='ui two button attached buttons'> <button class='ui basic blue button' v-on:click="hideForm"> Close X </button> </div> </div> </div> <div class='ui bottom attached green basic button' v-show="!isEditing &&todo.done" disabled> Completed </div> <div class='ui bottom attached red basic button' v-show="!isEditing && !todo.done"> Pending </div> </div> </template>
علاوه بر متد showForm که برای نمایش فرم استفاده میشود، به یک متد به نام hideForm جهت بستن فرم به هنگام کلیک روی دکمهی cancel نیاز داریم. بنابراین دستورهای زیر را به ادامهی فایل Todo.vue اضافه میکنیم:
<script> export default { props: ['todo'], data() { return { isEditing: false, }; }, methods: { showForm() { this.isEditing = true; }, hideForm() { this.isEditing = false; }, }, }; </script>
حال باید یک آیکون برای حذف کردن فعالیت ها در زیر آیکون edit اضافه کنیم:
<template> <span class='right floated edit icon' v-on:click="showForm"> <i class='edit icon'></i> </span> /* add the trash icon in below the edit icon in the template */ <span class='right floated trash icon' v-on:click="deleteTodo(todo)"> <i class='trash icon'></i> </span> </template>
مرحله بعدی اضافه کردن متد حذف به هنگام کلیک روی آیکون آن میباشد. این متد یک رویداد به نام delete-todo به کامپوننت والد TodoList بیرون میریزد و دادهای را برای حذف فعالیت کنونی ارسال میکند که فعالیت کنونی را حذف میکند. ما یک رویداد و شونده (ٍEvenet Listener) برای آیکون delete اضافه میکنیم:
<span class='right floated trash icon' v-on:click="deleteTodo(todo)">
// Todo component methods: { deleteTodo(todo) { this.$emit('delete-todo', todo); }, },
حال درون کامپوننت والد TodoList باید یک کنترل رویداد را برای حذف فعالیتها ایجاد کنیم. تا رویدادی که از کامپوننت فرزند به آن ارسال میشود اجرا شده و دادهی موردنظر مجددا به کامپوننت فرزند فرستاده شود.
// TodoList component methods: { deleteTodo(todo) { const todoIndex = this.todos.indexOf(todo); this.todos.splice(todoIndex, 1); }, },
حال باید این متد مجددا به کامپوننت فرزند Todo ارسال شود:
// TodoList template <todo v-on:delete-todo="deleteTodo" v-for="todo in todos" v-bind:todo="todo"></todo>
هم اکنون با کلیک روی دکمهی icon، رویدادی به کامپوننت والد TodoList ارسال شده و پس از حذف شدن فعالیت مشخص، مجددا اطلاعات به کامپوننت فرزند فرستاده خواهد شد.
برای اضافه کردن یک فعالیت جدید، نیاز به ساخت یک کامپوننت جدید به نام CreateTodo داریم. این کامپوننت را در مسیر src/components ایجاد میکنیم. این کامپوننت یک دکمه برای بوجود آوردن یک فرم و ارسال اطلاعات و نمایش آن در اختیار ما میگذارد.
<template> <div class='ui basic content center aligned segment'> <button class='ui basic button icon' v-on:click="openForm" v-show="!isCreating"> <i class='plus icon'></i> </button> <div class='ui centered card' v-show="isCreating"> <div class='content'> <div class='ui form'> <div class='field'> <label>Title</label> <input v-model="titleText" type='text' ref='title' defaultValue=""> </div> <div class='field'> <label>Project</label> <input type='text' ref='project' defaultValue=""> </div> <div class='ui two button attached buttons'> <button class='ui basic blue button' v-on:click="sendForm()"> Create </button> <button class='ui basic red button' v-on:click="closeForm"> Cancel </button> </div> </div> </div> </div> </div> </template> <script> export default { data() { return { titleText: '', projectText: '', isCreating: false, }; }, methods: { openForm() { this.isCreating = true; }, closeForm() { this.isCreating = false; }, sendForm() { if (this.titleText.length > 0 && this.projectText.length > 0) { const title = this.titleText; const project = this.projectText; this.$emit('create-todo', { title, project, done: false, }); this.newTodoText = ''; } this.isCreating = false; }, }, }; </script>
پس از ایجاد این کامپوننت آن را به کلاس کامپوننت والد و در بخش components اضافه خواهیم کرد:
// Main Component App.vue components: { TodoList, CreateTodo, },
همچنین باید یک متد جدید به نام addTodo به کامپوننت اصلی App.vue اضافه کنید:
// App.vue methods: { addTodo(title) { this.todos.push({ title, done: false, }); }, },
در قالب کامپوننت اصلی باید تگ <create-todo> را اضافه کنیم:
<create-todo v-on:add-todo="addTodo">
در نهایت، یک متد completeTodo به کامپوننت Todo اضافه میکنیم که رویداد complete-todo را به کامپوننت والد هنگام کلیک روی دکمهی Pending، اضافه میکنیم.
// Todo component methods: { completeTodo(todo) { this.$emit('complete-todo', todo); }, }
یک کنترل رویداد به کامپوننت TodoList برای پردازش رویداد اضافه میکنیم:
methods: { completeTodo(todo) { const todoIndex = this.todos.indexOf(todo); this.todos[todoIndex].done = true; }, },
برای ارسال متد TodoList برای کامپوننت Todo داریم:
<todo v-on:delete-todo="deleteTodo" v-on:complete-todo="completeTodo" v-for="todo in todos" :todo.sync="todo"></todo>
در این مقاله یاد گرفتیم که چگونه نرم افزارهایی که با فریم ورک Vue اجرا شدهاند را با استفاده از ابزار فرمان Vue CLI راهاندازی و مقداردهی اولیه کنیم. همچنین درباره ساختار کامپوننتها، اضافه کردن داده به کامپوننتها، رویداد و شنوندهها و کنترل رویدادها اطلاعات مفیدی را کسب کردیم. نحوهی حذف کردن و اضافه کردن المانها به صفحه را آموختیم. علاوه بر این از یک سری دادههای استاتیک در کامپوننت اصلی خود استفاده کرده و در مرحلهی بعد این دادهها را از سرور بازگردانی و بروزرسانی (Update) کردیم.
امیدواریم این مقاله مورد پسند شما عزیزان قرار گرفته باشد و به اطلاعات علمی شما درباره فریمورک بسیار قدرتمند Vue.js 2 اضافه کرده باشیم.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.