這篇文章對純新手友好,因此有過任何vue開發經驗的人能夠出門左轉啦!這篇文章獻給個人homie蘇蕾兒童鞋,讓她在學習vue項目的時候少走一點彎路(徑直衝向末路哈哈哈)。javascript
本文將會簡單的介紹一下vue的生態環境以及其中涉及的思想。若是剛從原始的HTML+JS+CSS中轉型,這篇文章可能會比較適合你。
我也是最近剛剛上手vue,以前有過一丟丟react開發經驗,因此對於vue的總體思路有些許的瞭解。粗鄙之見也請各位大佬多多指教。html
本文將會涉及以下內容:vue
Vue語言有很是強的靈活性,能夠直接在HTML頁面中經過引入其js文件使用,也能夠做爲一個完整的項目使用。一般狀況下,咱們會將其做爲一個完整的項目使用。這裏我使用vue-cli新建一個基於webpack的vue項目。vue-cli建立項目的教程網上不少,這裏就不詳細解釋了,能夠看到新建完成後項目目錄以下圖所示:java
在這個基礎上我會再額外的新建兩個文件夾views
,api
和store
,這篇文章暫時用不到api
和store
,以後引入vuex
以後會使用。
如今總體的項目目錄以下:node
如今着重解釋一下其中幾個目錄和文件分別用來幹啥。react
先看根目錄下的文件。jquery
package.json
用來配置node環境,它會記錄項目的相關信息以及該項目的依賴,有點像java的maven配置管理工具。通俗的來講,咱們一個項目可能會用到不少外部依賴好比jquery。因而咱們就須要一種科學有效的方式管理全部依賴及其對應的版本。而全部依賴都位於node_modules
文件夾中。後面咱們使用npm工具進行依賴管理時還會提到他。webpack
.gitignore
文件記錄了git提交時不上傳的內容,如node_modules
中的所有內容。git
index.html
文件是項目的skeleton,咱們來看一下它的內容:github
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>my website</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
這裏除了將網頁標題命名爲咱們的項目標題以外,還有一個id爲app的div。全部的頁面將以index.html做爲大框架,將元素插入到div中。後面還會繼續說起。
build
,config
文件夾涉及了各類配置文件,這裏不贅述,由於我也不是很會webpack哈哈哈。
項目的核心代碼都位於src
文件夾之下,在這個文件夾下,咱們看到一個App.vue
文件,內容以下:
<template> <div id="app"> <img src="./assets/logo.png"> <router-view/> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
它構建了一個名爲App的模塊。其實,這是整個項目的入口模塊,全部的渲染都將會通過App模塊,而後渲染至<div id="app"></div>
。所以能夠在App.vue文件中定義整個項目最通用的結構好比Header,Sidebar等等。其它狀況下也能夠不對其進行任何修改。
components
文件夾和views
文件夾都用來存儲模板,不一樣的是views文件夾中的內容對應一個完整的頁面,而components中的內容對應各個可重用的元素。好比views對應一個用戶我的信息界面,而components中可能包好這個界面中的Header,Sidebar,核心用戶信息模塊等等。
assets
中包含靜態信息如圖片等
router
目錄之下index.js對應了vue-router的配置,涉及vue-router時會繼續說起。
至此咱們基本瞭解了vue項目中各個文件夾的做用。那麼如何啓動這個項目呢?這就須要咱們的npm指令。
npm的指令不少,核心的咱們暫時只須要了解一下兩種就能夠了:npm install
: 安裝依賴,好比咱們須要安裝jquery,就可使用npm install jquery。在不指定版本號的狀況下會下載最新版本npm run dev
: 運行開發配置下的項目,咱們用這個指令在開發過程當中啓動項目並debug
該todo來自於vue官網上,須要查看源碼的能夠去官網的github上下載。
首先咱們須要使用npm install來安裝項目現有的依賴,項目現有的依賴會從package.json文件夾中查看並下載。依賴下載的過程會比較慢,可使用淘寶開發的cnpm。
咱們在使用npm run dev
查看一下運行結果:
主要的組件都位於components
之下:
分別對應着新建Todo模塊,單個Todo展現頁面和Todo列表模塊。由於這是一個單頁面app,全部沒有用到views來組裝,而是直接在App.vue中進行組裝。
<template> <div id="app"> <h1 class="ui dividing centered header">Vue.js Todo App</h1> <div class='ui three column centered grid'> <div class='column'> <todo-list v-bind:todos="todos"></todo-list> <create-todo v-on:create-todo="createTodo"></create-todo> </div> </div> </div> </template> <script> import sweetalert from 'sweetalert'; import TodoList from './components/TodoList'; import CreateTodo from './components/CreateTodo'; export default { name: 'app', components: { TodoList, CreateTodo, }, 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, }], }; }, methods: { createTodo(newTodo) { this.todos.push(newTodo); sweetalert('Success!', 'To-Do created!', 'success'); }, }, }; </script>
這裏引入了TodoList和CreateTodo模板,並在<template>中使用。同時還用props傳入了一組todo的數組模擬現有的todo內容。具體的vue語法這裏將不涉及,能夠去官網上學習,官網的教程能夠說是很是新手友好了呢。
而後咱們來看一看TodoList.vue
<template> <div> <p class="tasks">Completed Tasks: {{todos.filter(todo => {return todo.done === true}).length}}</p> <p class="tasks">Pending Tasks: {{todos.filter(todo => {return todo.done === false}).length}}</p> <todo v-on:delete-todo="deleteTodo" v-on:complete-todo="completeTodo" v-for="todo in todos" :todo.sync="todo"></todo> </div> </template> <script type = "text/javascript" > import sweetalert from 'sweetalert'; import Todo from './Todo'; export default { props: ['todos'], components: { Todo, }, methods: { deleteTodo(todo) { sweetalert({ title: 'Are you sure?', text: 'This To-Do will be permanently deleted!', type: 'warning', showCancelButton: true, confirmButtonColor: '#DD6B55', confirmButtonText: 'Yes, delete it!', closeOnConfirm: false, }, () => { const todoIndex = this.todos.indexOf(todo); this.todos.splice(todoIndex, 1); sweetalert('Deleted!', 'Your To-Do has been deleted.', 'success'); }); }, completeTodo(todo) { const todoIndex = this.todos.indexOf(todo); this.todos[todoIndex].done = true; sweetalert('Success!', 'To-Do completed!', 'success'); }, }, }; </script> <style scoped> p.tasks { text-align: center; } </style>
如今看Todo.vue文件。
<template> <div class='ui centered card'> <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> <span class='right floated trash icon' v-on:click="deleteTodo(todo)"> <i class='trash icon'></i> </span> </div> </div> <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-on:click="completeTodo(todo)" v-show="!isEditing && !todo.done"> Pending </div> </div> </template> <script type="text/javascript"> export default { props: ['todo'], data() { return { isEditing: false, }; }, methods: { completeTodo(todo) { this.$emit('complete-todo', todo); }, deleteTodo(todo) { this.$emit('delete-todo', todo); }, showForm() { this.isEditing = true; }, hideForm() { this.isEditing = false; }, }, }; </script>
它的<template>中包含了一個Todo塊的信息。以後TargetList.vue用它來展現所有的Todo。
<template> <div> <p class="tasks">Completed Tasks: {{todos.filter(todo => {return todo.done === true}).length}}</p> <p class="tasks">Pending Tasks: {{todos.filter(todo => {return todo.done === false}).length}}</p> <todo v-on:delete-todo="deleteTodo" v-on:complete-todo="completeTodo" v-for="todo in todos" :todo.sync="todo"></todo> </div> </template> <script type = "text/javascript" > import sweetalert from 'sweetalert'; import Todo from './Todo'; export default { props: ['todos'], components: { Todo, }, methods: { deleteTodo(todo) { sweetalert({ title: 'Are you sure?', text: 'This To-Do will be permanently deleted!', type: 'warning', showCancelButton: true, confirmButtonColor: '#DD6B55', confirmButtonText: 'Yes, delete it!', closeOnConfirm: false, }, () => { const todoIndex = this.todos.indexOf(todo); this.todos.splice(todoIndex, 1); sweetalert('Deleted!', 'Your To-Do has been deleted.', 'success'); }); }, completeTodo(todo) { const todoIndex = this.todos.indexOf(todo); this.todos[todoIndex].done = true; sweetalert('Success!', 'To-Do completed!', 'success'); }, }, }; </script> <style scoped> p.tasks { text-align: center; } </style>