##一、走進Vuejavascript
#一、what -- 什麼是Vue 漸進式 JavaScript 框架、能夠獨立完成先後端分離式web項目的JavaScript框架 #二、why -- 爲何要學習Vue 三大主流框架之一:Angular React Vue 先進的前端設計模式:MVVM 能夠徹底脫離服務器端,之前端代碼複用的方式渲染整個頁面:組件化開發 #三、special -- 特色 1)單頁面 - 硬件要求低 2)組件化開發 3)數據驅動 4)數據的雙向綁定 5)虛擬DOM 6)輕量級 #四、how -- 如何使用Vue - 開發版本:[vue.js](https://vuejs.org/js/vue.js) - 生產版本:[vue.min.js] <div id="app"> {{ }} </div> <script src="js/vue.min.js"></script> //下載到本引入vue <script> new Vue({ el: '#app' }) </script>
##二、Vue實例css
##2-一、el實例html
new Vue({ el: '#app' }) // 實例與頁面掛載點一一對應 // 一個頁面中能夠出現多個實例對應多個掛載點 // 實例只操做掛載點內部內容
##2-二、data數據前端
<div id='app'> {{ msg }} </div> <script> var app = new Vue({ el: '#app', data: { msg: '數據', } }) console.log(app.$data.msg); console.log(app.msg); </script> <!-- data爲插件表達式中的變量提供數據 --> <!-- data中的數據能夠經過Vue實例直接或間接訪問-->
##2-三、methods 方法vue
<style> .box { background-color: orange } </style> <div id='app'> <p class="box" v-on:click="pClick">測試</p> <p class="box" v-on:mouseover="pOver">測試</p> </div> <script> var app = new Vue({ el: '#app', methods: { pClick () { // 點擊測試 }, pOver () { // 懸浮測試 } } }) </script> <!-- 瞭解v-on:爲事件綁定的指令 --> <!-- methods爲事件提供實現體-->
##2-四、computed 計算屬性java
<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>監聽多個變量</title></head><body><divid="app"><inputtype="text"v-model="a_val"><inputtype="text"v-model="b_val"><inputtype="text"v-model="c_val"><p>{{val_fn}}</p></div></body><scriptsrc="js/vue.js"></script><script>newVue({el:'#app',data:{a_val:'',b_val:'',c_val:'',},//computed內部書寫方法-管理能夠監聽多個變量的方法//1)方法名能夠直接做爲變量被渲染,值爲方法的返回值//2)在方法名被渲染後(在頁面中使用了),方法內部的全部變量都會被監聽//3)computed用來解決一個變量值依賴一個或多個變量值computed:{val_fn(){//this.a_val;//this.b_val;//this.c_val;console.log('該方法被調用了');returnthis.a_val+this.b_val+this.c_val;}}})</script></html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <p> 姓:<input type="text" v-model="last_name"> </p> <p> 名:<input type="text" v-model="first_name"> </p> <p> 姓名:{{ full_name }} </p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { last_name: '', first_name: '', }, computed: { full_name () { return this.last_name + ' ' + this.first_name; } } }) </script> </html>
##2-五、watch 監聽屬性node
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>監聽屬性</title> </head> <body> <div id="app"> <p> 姓名:<input type="text" v-model="full_name"> </p> <p> 姓:<input type="text" v-model="last_name"> </p> <p> 名:<input type="text" v-model="first_name"> </p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { full_name: '', last_name: '', first_name: '', }, // watch內部書寫方法 - 管理 監聽綁定的屬性(提早要存在) 的方法 // 1)方法名 被監聽的變量名(屬性) // 2) 在方法名被渲染後,方法名錶明的屬性值改變,綁定的方法就會被調用 // 3)watch用來解決多個變量值依賴一個變量值 watch: { full_name () { console.log('被調用了'); // full_name變量值改變,要完成的任何邏輯均可以書寫在此方法中 let name = this.full_name.split(' '); this.last_name = name[0]; this.first_name = name[1]; } } }) </script> </html>
##2-六、delimiters 分隔符ios
<div id='app'> ${ msg } //修改後的分隔符 </div> <script> new Vue({ el: '#app', data: { msg: 'message' }, delimiters: ['${', '}'] }) </script>
##三、生命週期鉤子web
表示一個vue實例從建立到銷燬的這個過程,將這個過程的一些時間節點賦予了對應的鉤子函數 鉤子函數: 知足特色條件被回調的方法 #重點掌握兩個方法 created mounted #vue api 連接 生命週期 https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90 #生命週期圖示: 可直接查看官網
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vue組件的生命週期鉤子</title> </head> <body> <div id="app"> <h1>一個vue組件從建立到銷燬整個生命週期過程當中一些時間節點回調的方法</h1> <local-tag></local-tag> </div> </body> <script src="js/vue.js"></script> <script> let localTag = { template: ` <div> <h2 @click="btnClick">{{ msg }}</h2> </div> `, data () { return { msg: '局部組件', x: 'x', y: 'y' } }, methods: { btnClick () { console.log(this.msg) }, zzz() {} }, beforeCreate () { console.log('組件開始建立,數據和事件都爲建立'); console.log(this.msg); console.log(this.btnClick); console.log(this.$data); }, pppp: [1, 2, 3], created () { console.log('組件已經建立完畢,數據與事件都準備就緒'); console.log(this.msg); console.log(this.btnClick); console.log(this.$data); console.log(this.$options.methods); console.log(this.$options.pppp); }, }; new Vue({ el: '#app', components: { localTag, } }) </script> </html>
##四、Vue指令ajax
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>文本指令</title> </head> <body> <div id="app"> <!--一、插值表達式:在內部直接寫變量或變量表達式--> <p>{{ msg }}</p> <p>{{ (num + 1 - 3) / 2 }}</p> <!--二、v-text v-html v-once 三個文本指令 --> <!--v-text:純文本--> <p v-text="msg"></p> <!--v-html:能夠解析標籤--> <p v-html="'<b>加粗文本</b>'"></p> <p v-html="htmlMSG" @click="changeMsg"></p> <!--v-once:插值表達式渲染文本,once來限制文本不可修改--> <!--插值表達式中一個變量被限制,整個結果都被限制--> <p v-once="htmlMSG">{{ htmlMSG + msg }}</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: 'message', num: 10, htmlMSG: '<b>加粗文本</b>' }, methods: { changeMsg: function () { this.htmlMSG = '<i>加粗文本</i>'; this.msg = '11111111111111'; } } }) </script> </html>
<style type="text/css"> [v-cloak] { display: none; } </style> <div id="app" v-cloak> {{ msg }} </div> <script src="js/vue.min.js"></script> <script type="text/javascript"> new Vue({ el: "#app", data: { msg: "message" } }) </script> <!-- 避免頁面閃爍-->
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>事件指令</title> <style> [aaa*='2'] { color: red; } [v-cloak] { display: none; } </style> </head> <body> <div id="app" v-cloak aaa="123"> <!-- v-on指令: 1)明確事件名 2)明確事件函數 v-on:事件名="事件函數" --> <!--一、基礎的事件綁定--> <p v-on:click="clickAction">單擊</p> <p v-on:dblclick="dblclickAction">雙擊</p> <!--二、綁定事件並傳參--> <ul> <li v-on:click="liAction(0)">{{ li1 }}</li> <li v-on:click="liAction(1)">222</li> <li v-on:click="liAction(2)">333</li> </ul> <!--三、傳遞事件對象--> <p v-on:click="sysAction1">不傳自定義參數</p> <p v-on:click="sysAction2(888, $event)">傳自定義參數</p> <!--四、v-on: 能夠簡寫爲 @ --> <p @click="clickAction">單擊</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { li1: '111' }, methods: { clickAction: function () { alert('點擊') }, dblclickAction () { alert('雙擊') }, liAction (index) { // alert('li被點擊了'); // alert(this.li1); alert(index); }, sysAction1 (ev) { console.log(ev) }, sysAction2 (num, ev) { console.log(num); console.log(ev); } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>屬性指令</title> <style> .box { width: 200px; height: 200px; background-color: orange; } .wrap { width: 100px; height: 100px; background-color: red; } .kiss { width: 150px; height: 150px; background-color: cyan; } .x { width: 300px; } .y { height: 300px; } .z { background-color: brown; } </style> </head> <body> <div id="app"> <!-- v-bind屬性指令 :屬性名="屬性變量",v-bind: 能夠簡寫爲: --> <!--eg: v-bind:class='myClass' | v-bind:style='myStyle' | v-bind:aaa='myAAA' --> <div class="box" v-bind:style="myStyle" @click="changeColor('pink')"></div> <!--一、操做單個樣式:w變量的值就是爲屬性寬提供數據的--> <div class="box" v-bind:style="{'width': w}" @click="changeWidth"></div> <!--二、操做多個樣式: more_style是一個對象變量,能夠賦值多個key:value樣式--> <div class="box" v-bind:style="more_style" @click="changeStyle"></div> <!--三、v-bind: 能夠簡寫爲 :,能夠綁定全部系統和自定義屬性,屬性一旦綁定,後方就是變量 --> <div :aaa="AAA">簡寫v-bind</div> <!--四、操做單個類名--> <!--直接賦值:c1就是變量,變量的值就是類名--> <div :class="c1" @click="changeClass"></div> <!--布爾切換:該div有一個kiss類名,kiss_able的true或false決定kiss是否生效--> <div :class="{kiss: kiss_able}"></div> <!--五、操做多個類名: [變量1, ..., 變量n] 每一個變量的值都是該標籤的類名 --> <div :class="[x, y, {z: is_z}]"></div> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { myStyle: 'background-color: red;', w: '400px', more_style: { width: '100px', height: '100px', borderRadius: '50%', backgroundColor: 'cyan' }, AAA: 'BBB', c1: 'wrap', kiss_able: true, x: 'x', y: 'y', // z: 'z', is_z: true }, methods: { changeColor (color) { this.myStyle = 'background-color: ' + color + ';' }, changeWidth () { this.w = '500px' }, changeStyle () { this.more_style.borderRadius = '30%' // this.more_style = { // width: '200px', // height: '200px', // borderRadius: '50%', // backgroundColor: 'tan' // } }, changeClass () { if (this.c1 === 'box') { this.c1 = 'wrap'; } else { this.c1 = 'box'; } // 布爾類型值來回切換 this.kiss_able = !this.kiss_able; } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <!-- v-model 表單指令 v-model="變量" 變量給value屬性提供值 --> <!--一、數據的雙向綁定--> <input type="text" v-model="val"> <input type="text" v-model="val"> <p>{{ val }}</p> <form action=""> <!--二、普通輸入框: 直接綁定變量便可 --> <input type="password" v-model="val"> <!--三、單選框--> <!--radio_val的值是多個單選框中一個的value值,表明該單選框默認選中--> <p> <label for="male">男</label> <input id="male" type="radio" value="male" v-model="radio_val" name="sex"> <label for="female">女</label> <input id="female" type="radio" value="female" v-model="radio_val" name="sex"> <button @click="alertValue">單選框提交給後臺的value</button> <span>{{ radio_val + '被選中' }}</span> </p> <!--四、獨立使用的複選框 --> <!--sure_val的值爲true|false,決定該單個複選框是否選中--> <p> <input type="checkbox" name="sure" value="贊成" v-model="sure_val"> <span>{{ sure_val }}</span> </p> request.GET.get('sure', None) <!--五、複選框--> <!--hobby_val的值是數組,裏面用來存放複選框全部選項的值,值存在表明該選框選中--> <p> 男<input type="checkbox" value="male" name="hobby" v-model="hobby_val"> 女<input type="checkbox" value="female" name="hobby" v-model="hobby_val"> 哇塞<input type="checkbox" value="?" name="hobby" v-model="hobby_val"> <span>{{ hobby_val }}</span> </p> <p> <input type="submit"> </p> </form> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { val: '', radio_val: 'male', sure_val: true, hobby_val: ['?', 'male'] }, methods: { alertValue () { alert(this.radio_val) } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> [v-cloak] { display: none; } .box { width: 200px; height: 200px; } .b1 {background-color: orange;} .b2 {background-color: cyan;} .r {background-color: red;} .b {background-color: blue;} .g {background-color: green;} </style> </head> <body> <div id="app" v-cloak> <!-- v-if | v-show 條件指令: v-if="變量" | v-show="變量" --> <!--一、v-if | v-show比較:二者綁定的變量值都是 true|false--> <p> <button @click="toggleAction(true)">顯示</button> <button @click="toggleAction(false)">隱藏</button> </p> <!--v-if在隱藏時,不被渲染 | v-show在隱藏時,採用display: none存在--> <div class="box b1" v-if="is_show"></div> <div class="box b2" v-show="is_show"></div> <!--二、v-if、v-else-if、v-else 分支家族 --> <p> <button @click="toggleShow('red')">紅</button> <button @click="toggleShow('blue')">藍</button> <button @click="toggleShow('green')">綠</button> </p> <div class="box r" v-if="color == 'red'"></div> <div class="box b" v-else-if="color == 'blue'"></div> <div class="box g" v-else></div> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { is_show: false, color: 'red' }, methods: { toggleAction(is_show) { this.is_show = is_show; }, toggleShow(color) { this.color = color; } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>循環指令</title> </head> <body> <div id="app"> <div>{{ arr }}</div> <hr> <ul> <li>{{ arr[0] }}</li> <li>{{ arr[1] }}</li> <li>{{ arr[2] }}</li> </ul> <hr> <!-- v-for 循環指令: v-for="ele in 容器變量" --> <!--一、array的循環--> <ul> <li v-for="s in arr">{{ s }}</li> </ul> <hr> <!--key屬性是vue的屬性,表示爲改標籤在內存中創建緩存的依據--> <ul> <li v-for="(s, i) in arr" :key="s" b="b">第{{ i }}個:{{ s }}</li> </ul> <hr> <!--二、對象的循環--> <ul> <li v-for="v in person">{{ v }}</li> </ul> <hr> <ul> <li v-for="(v, k) in person">{{ k }}:{{ v }}</li> </ul> <hr> <ul> <li v-for="(v, k, i) in person">{{ k }}:{{ v }}:{{ i }}</li> </ul> <hr> <!--name: * | sex:*--> <!--name: * | sex:*--> <!--name: * | sex:*--> <p v-for="stu in stus"> <span v-for="(v, k, i) in stu"> <b v-if="i != 0"> | </b> <b>{{ k }}:{{ v }}</b> </span> </p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { arr: ['aaa', 'bbb', 'ccc'], person: { 'name': 'Bob', 'age': 18, 'sex': '男' }, stus: [ { 'name': 'Alex', 'sex': '哇塞' }, { 'name': 'Egon', 'sex': '哇哦' }, { 'name': 'Jason', 'sex': '我去' } ] } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>todolist</title> <style> li:hover { cursor: pointer; color: red; } </style> </head> <body> <div id="app"> <input type="text" v-model="msg_val"> <button @click="sendMsg">留言</button> <ul> <li v-for="(msg, i) in msgs" @click="deleteMsg(i)">{{ msg }}</li> </ul> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { // msgs: ['第一條留言', '第二條留言'], msgs: localStorage.msgs ? localStorage.msgs.split(',') : [], msg_val: '', }, methods: { sendMsg () { // 1)數據爲空直接結束 if (!this.msg_val) return; // 2)數據添加到留言數組中 // this.msgs.push(this.msg_val); // 尾增 this.msgs.unshift(this.msg_val); // 首增 // 數據同步到前臺數據庫 localStorage.msgs = this.msgs; // 3)清空輸入框 this.msg_val = ''; }, deleteMsg (index) { // console.log(index); this.msgs.splice(index, 1); // 數據同步到前臺數據庫 localStorage.msgs = this.msgs; } } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>路飛導航案例</title> <style> body { margin: 0; height: 3000px; } ul { margin: 0; padding: 0; list-style: none; } </style> <style> .footer { width: 100%; height: 120px; background-color: rgba(0, 0, 0, 0.8); } </style> <style> .header { width: 100%; background-color: #ccc; position: fixed; } .header-slogan { width: 1200px; font: normal 14px/36px '微軟雅黑'; color: #333; margin: 0 auto; } .header-nav { width: 1200px; margin: 0 auto; /*background-color: orange;*/ } .header-nav:after { content: ""; display: block; clear: both; } .header-logo, .header-menu { float: left; } .header-owner { float: right; } .header-logo { width: 118px; height: 36px; background: url("img/header-logo.svg") no-repeat; } .header-menu { margin-left: 40px; } .header-menu li { float: left; margin-top: 26px; cursor: pointer; margin-right: 20px; } .header-menu li:hover { color: #444; padding-bottom: 5px; border-bottom: 2px solid #444; } .header-owner { padding-top: 26px; } .active { color: #444; padding-bottom: 5px; border-bottom: 2px solid #444; } </style> <style> .body-box { width: 1200px; height: 2000px; margin: 0 auto; } .box-normal-course { background-color: pink } .box-light-course { background-color: deeppink } .box-super-course { background-color: hotpink } </style> </head> <body> <div id="app"> <div class="header"> <div class="header-slogan">老男孩IT教育集團 | 幫助有志向的年輕人經過努力學習得到體面的工做和生活!</div> <div class="header-nav"> <h1 class="header-logo"></h1> <ul class="header-menu"> <li :class="{active: page == 'normal'}" @click="togglePage('normal')">免費課</li> <li :class="{active: page == 'light'}" @click="togglePage('light')">輕課</li> <li :class="{active: page == 'super'}" @click="togglePage('super')">學位課</li> </ul> <div class="header-owner"> <div v-if="is_logout"> <span>登錄</span> | <span>註冊</span> </div> <div v-else> <span>Owen</span> | <span>我的中心</span> </div> </div> </div> </div> <div class="body"> <div class="body-box box-normal-course" v-if="page == 'normal'"></div> <div class="body-box box-light-course" v-else-if="page == 'light'"></div> <div class="body-box box-super-course" v-else></div> </div> <div class="footer"></div> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { is_logout: true, page: 'normal' }, methods: { togglePage(page) { this.page = page; } } }) </script> </html>
##五、前端數據庫
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>前臺數據庫</title> </head> <body> <h1>前臺數據庫</h1> </body> <script> // window.localStorage // 永久存儲倉庫 // window.sessionStorage // 臨時存儲倉庫 // 存,存完註釋 // localStorage['name'] = 'Owen' // 取 console.log(localStorage.name); // 存,存完註釋 // sessionStorage.age = 18; // 取 console.log(['age']); // localStorage.msgs = [] // 清空 localStorage.clear(); localStorage.clear(); // localStorage.arr = [1, 2, 3]; // localStorage.obj = {'1': 1}; </script> </html>
##六、組件
#組件規則 每個組件都是一個vue實例 每一個組件均具備自身的模板template,根組件的模板就是掛載點 每一個組件模板只能擁有一個根標籤 子組件的數據具備做用域,以達到組件的複用
##6-一、根組件
<div id="app"> <h1>{{ msg }}</h1> </div> <script type="text/javascript"> // 經過new Vue建立的實例就是根組件(實例與組件一一對應,一個實例就是一個組件) // 每一個組件組件均擁有模板,template var app = new Vue({ // 根組件的模板就是掛載點 el: "#app", data : { msg: "根組件" }, // 模板: 由""包裹的html代碼塊,出如今組件的內部,賦值給組件的$template變量 // 顯式書寫模塊,就會替換掛載點,但根組件必須擁有掛載點 template: "<div>顯式模板</div>" }) // app.$template </script>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <h1 id="app"> {{ msg }} </h1> <div id="main"> {{ msg }} </div> </body> <script src="js/vue.js"></script> <script> // 1、new Vue建立的是vue實例,一個實例就是一個vue組件,new出了的實例稱之爲根組件 // 注:在實際開發中一個頁面只有一個根組件 // 2、每一個組件均由 html模板 css樣式 js邏輯 組成 // html模板: template,根組件的模板就採用掛載點便可,無需建立自身template // 注:掛載點是必須的(做爲虛擬DOM渲染替換的依據),掛載點能夠讀取,做爲根組件的模板,使用根組件無需書寫template // 3、根組件內部能夠註冊使用n個子組件,子組件必須擁有本身的 html模板 css樣式 js邏輯 // 若是建立子組件 | 如何使用子組件 | 父子組件間的通訊 let app = new Vue({ el: '#app', data: { msg: 'app的msg', c: 'red' }, // template: '<ul>{{ msg }}</ul>', template: `<h1 id="app" :style="{color: c}" @click="action"> {{ msg }} </h1> `, methods: { action () { alert(this.msg) } } }); let main = new Vue({ el: '#main', data: { msg: 'main的msg' } }); // 知識點:利用原生js完成兩個組件的交互 // 獲取組件的數據 // console.log(app.msg); // 修改組件的數據 // app.msg = '12345'; main.msg = app.msg; </script> </html>
##6-二、局部組件
<div id="app"> <local-tag></local-tag> <local-tag></local-tag> </div> <script> var localTag = { data () { return { count: 0 } }, template: '<button @click="btnAction">局部{{ count }}</button>', methods: { btnAction () { this.count ++ } } } new Vue({ el: "#app", components: { 'local-tag': localTag } }) </script>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>局部組件</title> <style> .box { width: 200px; text-align: center; border: 1px solid black; border-radius: 10px; overflow: hidden; float: left; } .box img { width: 100%; } .box p { margin: 0; } .box span:hover { cursor: pointer; color: orange; } </style> </head> <body> <div id="app"> <!--<div class="box">--> <!--<img src="http://a.hiphotos.baidu.com/image/h%3D300/sign=e543b919a151f3dedcb2bf64a4eff0ec/4610b912c8fcc3cebba8b8e09c45d688d53f20fc.jpg" alt="">--> <!--<p>野獸</p>--> <!--</div>--> <!--<box></box>--> <!--<box></box>--> <!--<box-tag></box-tag>--> <!--<box-tag></box-tag>--> <!-- 問題:數據 父組件 => 子組件 父組件根據數組數據(box_data)渲染多個子組件,遍歷獲得的數據(box_obj)是渲染子組件的, 如何將遍歷的數據傳遞給子組件 --> <box-tag v-for="box_obj in box_data"></box-tag> </div> </body> <script src="js/vue.js"></script> <script> // 後臺的數據 let data = [ { img_url: 'img/001.jpg', img_title: '野獸1' }, { img_url: 'img/001.jpg', img_title: '野獸2' }, { img_url: 'img/001.jpg', img_title: '野獸3' } ]; // 建立局部組件 => 在根組件中註冊 => 解析{}中的vue語法 => 造成組件 let box = { template: ` <div class="box"> <img src="img/001.jpg" alt=""> <p> <span @click="btnClick">點擊了{{ num }}下</span> <p>野獸</p> </p> </div> `, // data: { // 錯誤的 // num: 0 // }, // data: function () { // 每一個複用的子組件都應該有本身的一套數據,因此要用一個局部做用域存儲,保證數據的隔離性 // return { // data的值仍是字典,因此函數的返回值是字典便可 // num: 0 // } // }, data () { return { num: 0 } }, methods: { btnClick () { // alert(123) this.num += 1; } } }; new Vue({ el: '#app', components: { // box, // key與value變量同名 boxTag: box, // js支持的駝峯命名法與html的-鏈接有語法對應 // 'box-tag': box, }, data: { box_data: data } // 僞代碼:頁面的data數據能夠由後臺提供,前臺獲取後賦值給 vue data成員中的變量,vue就能夠渲染到頁面中 // $.ajax({ // success: function (data) { // this.box_data = data // } // }) }) </script> </html>
##6-三、全局組件
<div id="app"> <global-tag></global-tag> <global-tag></global-tag> </div> <script> Vue.component('global-tag', { data () { return { count: 0 } }, template: '<button @click="btnAction">全局{{ count }}</button>', methods: { btnAction () { this.count ++ } } }) new Vue({ el: "#app" }) </script>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>全局組件</title> </head> <body> <div id="app"> <!--<p-tag></p-tag>--> <!--<p-tag></p-tag>--> <g-tag></g-tag> <g-tag></g-tag> </div> </body> <script src="js/vue.js"></script> <script> let pTag = { template: ` <p> <span @click="action">{{ num }}</span> </p> `, data () { return { num: 0 } }, methods: { action() { this.num++; } } }; // 全局組件,經過 Vue.component('組件名', 組件對象主體); Vue.component('gTag', { template: ` <p> <span @click="action">{{ num }}</span> </p> `, data () { return { num: 0 } }, methods: { action() { this.num++; } } } ); new Vue({ el: '#app', components: { // pTag, } }) </script> </html>
##6-四、父子組件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>父子組件</title> <style> body, h1, h2 { margin: 0; } </style> <style> .header { height: 120px; background-color: orange; } .body { height: 800px; background-color: pink; } .footer { height: 180px; background-color: brown; } </style> </head> <body> <div id="app"> <view-tag v-if="page == 'tag'" @click="action"></view-tag> <view-tag-2 v-else-if="page == 'tag2'"></view-tag-2> </div> </body> <script src="js/vue.js"></script> <script> // 小組件 let headerTag = { template: ` <div class="header"> <h1 style="text-align: center; line-height: 120px">頭</h1> </div> `, }; let footerTag = { template: ` <div class="footer" > <h2 style="text-align: center; line-height: 180px">尾</h2> </div> `, }; // 頁面組件 let viewTag = { template: ` <div class="view-tag"> <header-tag></header-tag> <div class="body" style="background-color: lawngreen"></div> <footer-tag></footer-tag> </div> `, components: { headerTag, footerTag, } }; let viewTag2 = { template: ` <div class="view-tag"> <header-tag></header-tag> <div class="body" style="background-color: cyan"></div> <footer-tag></footer-tag> </div> `, components: { headerTag, footerTag, } }; // 根組件 new Vue({ el: '#app', data: { // 問題:數據 子組件 => 父組件 // page的值須要在父組件中修改,單擊事件只能在子組件中觸發 // 子組件觸發事件後將要修改的值傳出給父組件,在父組件中完成數據的修改 page: 'tag' }, components: { viewTag, viewTag2, }, methods: { action () { alert('給組件標籤綁定事件沒法激活') } } }) </script> </html>
##6-五、數據父傳子
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>父傳子</title> </head> <body> <div id="app"> <!--總結: 1)父組件模板中寫子組件標籤 2)父組件的數據綁定給子組件標籤的自定義屬性 3)在子組件內部經過props拿到自定義屬性 4)使用自定義屬性就能夠得到父組件的數據 --> <sub-tag :a="msg"></sub-tag> </div> </body> <script src="js/vue.js"></script> <script> let subTag = { // 子組件經過props實例成員獲取自身自定義屬性 props: ['a'], template: ` <div> <h1>{{ a }}</h1> </div> ` }; new Vue({ el: '#app', data: { msg: '父級數據' }, components: { subTag, } }) </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>父傳子案例</title> <style> .box { width: 200px; text-align: center; border: 1px solid black; border-radius: 10px; overflow: hidden; float: left; } .box img { width: 100%; } .box p { margin: 0; } .box span:hover { cursor: pointer; color: orange; } </style> </head> <body> <div id="app"> <box-tag v-for="box_obj in box_data" :box_obj="box_obj"></box-tag> </div> </body> <script src="js/vue.js"></script> <script> let boxTag = { props: ['box_obj'], template: ` <div class="box"> <img :src="box_obj.img_url" alt=""> <p> <span @click="btnClick">點擊了{{ num }}下</span> <p>{{ box_obj.img_title }}</p> </p> </div> `, data () { //data要定義爲函數形式,函數就存在了做用域,這樣就能夠達到隔離性 return { num: 0 } }, methods: { btnClick () { this.num += 1; } } }; // 後臺的數據 let back_data = [ { img_url: 'img/001.jpg', img_title: '野獸1' }, { img_url: 'img/002.jpg', img_title: '野獸2' }, { img_url: 'img/003.jpg', img_title: '野獸3' } ]; new Vue({ el: '#app', data: { box_data: back_data }, components: { boxTag, } }) </script> </html>
##6-五、數據子傳父
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <h1>{{ title }}</h1> <sub-tag @send_val="recv_val"></sub-tag> </div> </body> <script src="js/vue.js"></script> <script> let subTag = { template: ` <div> <input type="text" v-model="val"> <button @click="changeTitle">修改</button> </div> `, data () { return { val: '' } }, methods: { changeTitle () { if (!this.val) return; // 若是有數據,將數據發生給父組件 this.$emit('send_val', this.val); this.val = ''; } } }; new Vue({ el: '#app', data: { title: '父組件標題' }, components: { subTag }, methods: { recv_val (val) { this.title = val; } } }) </script> </html>
##七、Vue-CLI項目搭建
##7-一、環境搭建
#一、安裝node 官網下載安裝包,傻瓜式安裝:https://nodejs.org/zh-cn/ #二、安裝cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org #三、安裝腳手架 cnpm install -g @vue/cli #四、若是安裝出現問題 可執行 npm cache clean --force
##7-二、項目建立
1、建立項目 vue create 項目名 // 要提早進入目標目錄(項目應該建立在哪一個目錄下) // 選擇自定義方式建立項目,選取Router, Vuex插件
啓動 cnpm run serve / ctrl+c // 要提早進入項目根目錄 訪問: http://localhost:8080/
##7-二、建立好的vue項目怎麼移動到新的環境
1、拷貝文件除了node_modules該文件夾,其他文件拷貝到新得環境中 2、cmd進入新的項目目錄,執行cnpm install 重新安裝依賴 3、經過pycharm打開新建的vue項目 四、在pycharm中編輯該項目,點擊edit編輯,新建(+號)服務、選擇npm
5、安裝vue頁面腳本
若是沒有提示安裝的話 取setting中pluging
六、安裝完成重啓pycharm
##7-三、認識項目
node_modules:項目依賴 public:公用文件 favicon.ico:頁面標籤圖標 index.html:項目的惟一頁面(單頁面) src:項目開發文件目錄 assets:靜態資源 css|js|img components:小組件 *.vue views:視圖組件 *.vue App.vue:根組件 main.js:主腳本文件 程序入口文件 router.js:路由腳本文件 - vue-router store.js:倉庫腳本文件 - vuex *.xml|json|js:一系列配置文件 README.md:使用說明
import Vue from 'vue' // node_modules下的依賴直接寫名字 import App from './App.vue' // ./表明相對路徑的當前目錄,文件後綴軍能夠省略 import router from '@/router.js' // @ 表明src的絕對路徑 import store from './store' // 在main中配置的信息就是給整個項目配置 // 已配置 vue | 根組件App | 路由 | 倉庫 // 之後還能夠配置 cookie | ajax(axios) | element-ui Vue.config.productionTip = false; // Tip小提示 // 配置reset.css import '@/assets/css/reset.css' // new Vue({ // router, // store, // render: h => h(App) // }).$mount('#app') new Vue({ el: '#app', router: router, store, // render: function (fn) { // return fn(App) // } // 解釋:function (h) {return 1} | (h) => {return 1} | h => 1 render: readTemplateFn => readTemplateFn(App) });
template> <!-- 模板區域 --> </template> <script> // 邏輯代碼區域 // 該語法和script綁定出現 export default { } </script> <style scoped> /* 樣式區域 */ /* scoped表示這裏的樣式只適用於組件內部, scoped與style綁定出現 */ </style>
##7-四、項目功能
##路由功能
{ path: '/', name: 'home', // 路由的重定向 redirect: '/home' } { // 一級路由, 在根組件中被渲染, 替換根組件的<router-view/>標籤 path: '/one-view', name: 'one', component: () => import('./views/OneView.vue') } { // 多級路由, 在根組件中被渲染, 替換根組件的<router-view/>標籤 path: '/one-view/one-detail', component: () => import('./views/OneDetail.vue'), // 子路由, 在所屬路由指向的組件中被渲染, 替換該組件(OneDetail)的<router-view/>標籤 children: [{ path: 'show', component: () => import('./components/OneShow.vue') }] }
<!-- router-link渲染爲a標籤 --> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> | <router-link :to="{name: 'one'}">One</router-link> | <!-- 爲路由渲染的組件佔位 --> <router-view />
// router的邏輯轉跳 this.$router.push('/one-view') // router採用history方式訪問上一級 this.$router.go(-1)
##路由案例
<template> <div> <h1 :class="{active:is_active}" @click="btnClick">owen組件</h1> </div> </template> <script> export default { data (){ return { is_active : false } }, methods:{ btnClick(){ this.is_active = !this.is_active } } } </script> <style scoped> .active{ color: red; } </style>
<!-- views/About.vue --> <template> <div class="about"> <h1>This is an about page</h1> <h2>好</h2> <!-- 使用組件 --> <owen-comp></owen-comp> <OwenComp></OwenComp> </div> </template> <script> // import OwenComp from '../components/OwenComponent' import OwenComp from '@/components/OwenComponent' // 導入組件,組件名隨意 export default { components: { OwenComp, // 註冊組件 } } </script>