vue01 : vue基本語法javascript
vue02 : 博彩項目採用vue方式實現css
vue03 : 博彩項目採用vue方式實現html
傳統的Web項目 : 後臺邏輯,html數據的渲染thymeleaf,jsp前端
web項目: 後臺程序只負責提供數據, 前端負責去展示html數據vue
簡單來講,Vue是一套渲染UI的強大前端框架。java
官網地址:https://cn.vuejs.org/webpack
主要特性:git
其中,最重要最核心的特性就是:響應式和組件化。github
官方文檔:https://cn.vuejs.org/web
經過<script></script>
引用
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
經過vue-cli安裝全套開發環境,項目開發推薦
經過一個簡單的例子,來快速感覺一下Vue的特性。
例子中使用:值填充以及響應式的UI刷新,
v-model實現輸入項雙向綁定特性
v-on:click單擊事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> </head> <body> <div id="app"> {{msg}} <input type="text" v-model="username"><span>{{username}}</span> <ul> <li v-for="item in list">{{item}}</li> </ul> <h3 v-if="isShow">我在某些條件下才顯示</h3> <button @click="isShow=!isShow">點我隱藏上面的文字</button> </div> <script> let vm = new Vue({ el: '#app', data:{ msg: "我是Vue", list:[ 'a', 'b', 'c' ], isShow: true, username: "aaaa" } }); setTimeout(()=>{ vm.msg = "個人值被改變了,會響應式的刷新到UI上"; vm.list.push("dd"); }, 2000) </script> </body> </html>
每個Vue實例,均可以有本身的數據和自定義方法。自定義方法通常用來獲取數據或者對數據進行處理。
let vue = new Vue({ el: "#app", data: { content: "aaa" }, template: "<div><button v-on:click=\"handleClick\">點我讓content變化</button> : {{content}}</div>", methods: { handleClick(){ this.content = "bbb" } } });
所謂的生命週期其實就像咱們人,從出生到成長到死亡的過程同樣.在Vue中生命週期指的是Vue實例從初始化,建立,顯示,更新以及銷燬的整個過程,而生命週期鉤子指的是每一個過程都有一個回調函數,Vue中把回調函數稱爲鉤子。
再次回顧一下什麼是Vue生命週期鉤子? 生命週期鉤子就是Vue實例在某個時間點自動執行的回調函數.咱們經常使用的生命週期鉤子有: created,mounted
<script> let vm = new Vue({ el:'#app', template:'<span>{{msg}}</span>', data:{ msg:'hahaha' }, beforeCreate(){ console.log("beforeCreate...") }, created(){ console.log("created...") }, beforeMount(){ console.log("beforeMount..."+this.$el.innerHTML) }, mounted(){ console.log("mounted..."+this.$el.innerHTML) }, beforeDestroy(){ console.log("beforeDestory...") }, destroyed(){ console.log("destoryed...") }, beforeUpdate(){ console.log("beforeUpdate...") }, updated(){ console.log("updated") } }) </script>
計算屬性和方法均可以對數據進行處理。可是計算屬性有基於依賴數據的智能緩存,當計算屬性所依賴的值發生改變,計算屬性纔會從新計算, 因此性能更高,咱們應該優先考慮使用。
若是是普通的方法實現相同的功能,每當頁面數據任何數據發生改變的時候,方法都會被執行一次
let vue = new Vue({ el: "#app", data: { firstName: "Xiao", lastName: "Kaikai", age:30 }, computed: { // 計算屬性有基於依賴數據的緩存 fullName(){ console.log("計算屬性執行了一次"); return this.firstName + this.lastName; } } , methods: { getFullName(){ console.log("自定義方法執行了"); return this.firstName + this.lastName; } } });
偵聽器能夠用來偵聽數據的改變. 若是一個功能,方法能實現,計算屬性能實現,偵聽器也能實現,咱們應該優先選擇計算屬性
let vm = new Vue({ el:'#app', data:{ firstName:'Kaikai', lastName:'Xiao', age:30, fullName:"Kaikai Xiao" }, methods:{ getFullName(){ console.log("getFullName執行了一次運算") return this.firstName + ' ' + this.lastName; } }, watch:{ firstName(newVal,oldVal){ this.fullName = this.firstName + this.lastName; console.log('newVal:'+newVal+" oldVal:"+oldVal); }, lastName(){ this.fullName = this.firstName + this.lastName; } } }
Vue容許咱們給DOM元素動態綁定一些class。
<body> <div id="app"> <div class="c1" :class="{c2:isShow,c3:isShow}" @click="isShow=!isShow" >{{name}}</div> class動態綁定數組的語法 <div class="c1" :class="classes" @click="isShow=!isShow" >{{name}}</div> </div> </body> <script> let vm = new Vue({ el:'#app', data:{ name:'zhangsan', isShow:true, classes:['c1','c2','c3'] } }); </script> <style> .c1{ font-size: 10px; color: green; background-color: yellow; } .c2{ font-size: 30px; } .c3{ background-color: red; } </style>
v-show
<div v-show="isShow">頁面內容v-show</div>
v-if
v-else-if
v-else
<div id="app" > <div v-if="isLogin">您好,劉德華</div> <div v-else><button @click="isLogin=true">登陸</button></div> <!--對於須要頻繁切換顯示隱藏的場景,用v-show,由於性能更高--> <!--<div v-show="isLogin">您好,劉德華2</div>--> </div> <script> let vue = new Vue({ el: "#app", data: { isLogin: false } }); </script>
當咱們去使用v-for的時候,最好去給它指定一個惟一的key值,這樣的會方便vue複用dom節點,從而提升性能
使用的語法: v-for="(item,index) in 數組" 若寫了:key,那麼它的值須要是惟一的值
<div id="app" > <div>最好吃的水果:</div> <div v-for="item in list">{{item}}</div> <input type="text" v-model="fruit"><button @click="handleClick">添加</button> <div> <button @click="handleDelete">刪除第</button><input type="text" v-model="index">個 </div> </div> <script> let vm = new Vue({ el: "#app", data: { list:[ "蘋果","西瓜","哈蜜瓜" ], fruit: "", index: 0 }, methods:{ handleClick(){ this.list.push(this.fruit); this.fruit = ""; }, handleDelete(){ this.list.splice(this.index, 1); } } }); </script>
注意:當咱們去修改數組的時候,不能使用下標的方式,不然數據添加進去了,頁面不會刷新,咱們須要藉助數組提供的一些方法來修改,咱們經常使用的數組方法有:
v-for="(item,key,index) in 對象"
<div v-for="item,key,index in user">{{item}}--{{key}}--{{index}}</div> let vm = new Vue({ el:'#app', data:{ user:{ username:"haha", password:123, age:100 } } });
注意: 咱們若是直接添加一個屬性,頁面上並不會跟着刷新
當咱們去修改某一個對象的內容的時候,因爲vue中並不知道對象內容發生了改變,因此也就不會從新渲染了,若想當對象內容發生改變頁面從新渲染,咱們須要藉助Vue給咱們提供的一下方法
使用全局的方法: Vue.set(對象,改變的key,改變的值)
使用實例的方法: vm.$set(對象,改變的key,改變的值)
數組中使用set方法: vm.$set(對象,要改變的下標,改變的值)
用上面學的語法,實現一個ToDoList。
<body> <div id="app"> <h3>添加今日要完成任務</h3> <input type="text" v-model="currentInput" /><button @click="handleAdd">添加</button> <ul> <li v-for="item in todos" :class="{done:item.isDone}" > {{item.text}} <button @click="handleComplete(item)" >標記完成</button> <button @click="handleDelete(item)">刪除</button> </li> </ul> </div> </body> <style> .done{ background-color: red; } </style> <script> let vm = new Vue({ el:'#app', data:{ todos:[], currentInput:"" }, methods:{ handleAdd(){ //判斷是否爲空 if(this.currentInput === ""){ return ; } //檢查是否有重複的內容 for(let i=0;i<this.todos.length;i++){ //數組中的每一項 let item = this.todos[i]; //判斷是否有重複 if(item.text === this.currentInput){ return; } } //獲取輸入項的內容,將輸入項的內容存到todos this.todos.push({text:this.currentInput,isDone:false}); //清空輸入項的內容 this.currentInput = "" }, handleComplete(item){ item.isDone = true; }, handleDelete(item){ //從todos中刪除這個item let index = this.todos.indexOf(item); //調用數組中刪除的方法 this.todos.splice(index,1); } } }); </script> </html>
組件是Vue的核心之一,任何一個大的系統均可以由多個小的組件共同構成。組件的複用性,也大大提升了前端開發的效率。
組件的註冊有全局註冊和局部註冊兩種方式。
全局註冊: 註冊以後能夠用在任何新建立的 Vue 根實例 (new Vue
) 的模板中
<script> /*定義一個全局組件*/ Vue.component('title-bar',{ template:`<div><h1>首頁標題欄</h1></div>` }); /*定義一個全局組件*/ Vue.component('MenuBar',{ template:`<div><h1>底部菜單欄</h1></div>` }); let vm = new Vue({ el:'#app' }); </script>
局部註冊: 全局註冊每每是不夠理想的。好比,若是你使用一個像 webpack 這樣的構建系統,全局註冊全部的組件意味着即使你已經再也不使用一個組件了,它仍然會被包含在你最終的構建結果中。這形成了用戶下載的 JavaScript 的無謂的增長。
<script> <!--定義局部組件--> let TitleBar = { name:'title-bar', template:`<div><h1>{{title}}標題部分</h1></div>`, data(){ return { title:'首頁' } } } /*定義一個局部組件*/ let MenuBar = { name:'menu-bar', template:`<div><h1>底部菜單部分</h1></div>` } //根實例 let vm = new Vue({ el:'#app', components:{ TitleBar, MenuBar } }); </script>
父子組件之間每每不是獨立的,須要進行數據的通訊。從父到子,用props;從子到父,用$emit。
<div id="app"> <ul> <li v-for="item,index in list"><todo-item :content="item" :index='index' @delete-item="handleDeleteItem"></todo-item></li> </ul> <child :text="text"></child> </div> <script> // 全局註冊 Vue.component("todo-item", { props:['content','index'], data() { return { } }, template: "<div @click='handlerClick'>{{content}}</div>", methods: { handlerClick(){ this.$emit("delete-item", this.index); } } }); // 子組件不要去直接修改父組件的數據 Vue.component("child", { props:['text'], data() { return { myText: this.text } }, template: "<div @click='changeText'>{{myText}}</div>", methods: { changeText(){ this.myText = "修改了的文字"; } } }); let vue = new Vue({ el: "#app", data: { list: [ "吃飯", "睡覺", "打豆豆" ], text: "文字" }, methods:{ handleDeleteItem(index){ this.list.splice(index, 1); } } }); </script>
若是咱們在自定義組件上綁定事件是沒有效果的,由於組件上定義的事件都是自定義的,想要觸發須要咱們在子組件內部調用$emit派發.可是這樣作又很麻煩,因此當咱們想使用點擊事件,咱們可使用Vue提供的綁定原生事件方式,咱們只須要使用@click.native
<div id="app"> <child :text="text" @click.native="handleChildClick"></child> </div> <script> //全局組件 Vue.component('child',{ template:`<div>子組件的內容展現</div>` /*template:`<div @click="handleChildClick">子組件的內容展現</div>`, methods:{ handleChildClick(){ console.log("child click"); this.$emit('click'); } }*/ }); //根實例 ,父組件 let vm = new Vue({ el:'#app', methods:{ handleFatherClick(){ console.log("father click") } } }); </script>
有時候咱們組件的內容是不肯定的,咱們定義組件的時候使用slot留出空白,外界使用的時候動態插入,這就是插槽。
<body> <div id="app"> <child > <div slot="header">header</div> <!--<div slot="footer">footer</div>--> </child> </div> </body> <script> //定義子組件 Vue.component('child',{ template:`<div> <slot name="header"></slot> <div>內容不變</div> <slot name="footer">默認頁腳</slot> </div> ` }); //根實例 ,父組件 let vm = new Vue({ el:'#app', }); </script>
動態組件能夠很是方便的切換幾個不一樣的組件,並且支持緩存。
<body> <div id="app"> <component :is="currentName"></component> <button @click="handleClick('home')">首頁</button> <button @click="handleClick('my')">個人</button> </div> </body> <script> Vue.component('home',{ template:`<div>這是網站首頁的內容</div>` }); Vue.component('my',{ template:`<div>這是個人我的頁面</div>` }) //根實例 ,父組件 let vm = new Vue({ el:'#app', data:{ currentName:'home' }, methods:{ handleClick(name){ this.currentName = name; } } }); </script>
以上內容是項目開發中經常使用的基礎知識點。可是作項目開發,咱們須要考慮一下幾點:
而Vue-cli就爲了解決上面的問題而生的,它給咱們打包好了全部能用到的好工具,提供一個開箱即用的項目開發環境。因此,咱們須要用它來建立項目。
vue-cli官網:https://cli.vuejs.org/,官網寫的是3.0版本的使用,2.xx纔是穩定版。
vue-cli github主頁:https://github.com/vuejs/vue-cli
vue-cli的github網站默認是3.0的測試版本分支,須要切換爲主分支。
npm install -g vue-cli vue init webpack xxx ?Project name lottery ?Project description this is a niubility project ?Author xiaokaikai ?Vue build (選擇一種構建的形式) > Runtime + Compiler: recommended for most users ?Install vue-router?(Y/n) Y --這裏說是否安裝路由插件 ?Use ESLint to lint your code? N-- 是否檢查代碼格式 ?Pick an ESLint preset Standard -- 選擇一種代碼檢查的規範 ?Set up unit tests N 是否進行單元測試 ?Setup e2e tests with Nightwatch N 是否使用e2e工具進行構建 ?Should we run 'npm install' for you after the project has been created? npm --選擇npm方式安裝 輸入完成以後,工具就開始構建咱們的工程啦!
傳統的路由是後端來作,簡單說就是請求一個url,後端根據請求的參數內容渲染出相應的html返回。因爲JS能夠感知到瀏覽器URL的變化,所以能夠作到在url變化的時候去加載不一樣的DOM內容,這就是前端路由,和後端沒有任何關係了。
單頁應用(SPA)的用戶體驗比傳統的多頁應用要好不少,因此愈來愈多的公司開始嘗試單頁應用。單頁應用就將原來的多個頁面作成一個html,JS根據url的變化切換DOM的內容。這樣不用再去請求服務器的整個html內容,只須要請求對應的json數據,所以速度會快不少。
Vue-Router爲前端路由提供了封裝和簡化,並結合組件的使用。讓咱們能夠一個url對應一個組件,輕鬆編寫大型的SPA應用。
<router-view> 顯示當前路徑所對應的組件內容 <router-link to="要跳轉去的組件的路徑">
總結:
根實例 : let vm = new Vue({參數}) el template data methods computed watch props 生命週期鉤子 vue中屬性 v-model v-show v-if v-else-if v-else v-for v-html v-text 使用屬性: :屬性名稱 綁定事件:@事件名稱 全局組件和局部組件 父子組件之間通信 父-->子 : props 子 --> 父: $emit(事件名稱) @click.native 組件綁定原生事件 動態組件: <component :is=組件的名稱