之前寫CRM都是Django前后端一起寫的,在大部分項目中實際上前后端是分離的,因此我們需要學習一個前端框架來進行前端頁面的編寫,這里選擇了Vue進行學習,好了開始學習吧.
特點: 1.局部作用域 2.不會存在變量提升 3.變量不能重復聲明
特點: 1.局部作用域 2.不會存在變量提升 3.不能重復聲明,只聲明常量 不可變的量
// 通過反引號 ${變量名}來插值 let name = 'liu'; let res = `我是${name}`; console.log(res); ---> 我是liu
// 箭頭函數等同於add1 = function(x, y){return x+y;} let add1 = (x, y) => { return x+y; }; // 更簡單的使用 let add2 = (x, y) => x+y; console.log(add1(3,2)); ---> 5 console.log(add2(3,2)); ---> 5
// 這是對象中使用箭頭函數,此時的this指向的是person的父級對象(上下文,window) var person1 = { name: 'liu', age: '20', fav: () => { console.log(this); } }; person1.fav(); ---> Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …} // 為了解決箭頭函數this指向的問題 推出來一種寫法 對象的單體模式, 此時的this指向的是person對象 var person2 = { name: 'liu', age: '20', fav(){ console.log(this); } }; person2.fav(); ---> {name: "liu", age: "20", fav: ƒ}
// 基於原型的模式創建對象(prototype,繼承當前父類) function Person1(name,age){ this.name = name; this.age = age; } Person1.prototype.showName = function(){ console.log(this.name); }; var p1 = new Person1('liu', 18); p1.showName(); class Person2{ // 構造器 當你創建實例的時候 constructor()方法會立刻調用 通常這個方法初始化對象的屬性,類似py的__init__方法 constructor(name,age){ this.name = name; this.age = age; } showName(){ console.log(this.name); } } var p2 = new Person2('liu', 18); p2.showName();
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> // 在html中引入: <script src='./vue.js'></script>
// 模板語法, 可以插入任何你想插入的內容,除了if-else if-else用三元運算符代替 <div id="box"> <!--模板語法(內部不能寫if else if-else用三元運算符代替)--> <!--去data中找到msg的值展示在頁面--> <h3>{{ msg }}</h3> <!--直接運算得到結果展示在頁面上--> <h3>{{ 1+2+3 }}</h3> <!--字符,對象都能直接被渲染到頁面--> <h3>{{ {name: 'xiaohua'} }}</h3> <!--取出person對象的屬性name值--> <h3>{{ person.name }}</h3> <!--三元運算符計算--> <h3>{{ 1>2?'對':'錯' }}</h3> <!--翻轉字符串,得到nohtyp evol,證明{{}}中可以使用js語法--> <h3>{{ str1.split('').reverse().join('') }}</h3> </div>
// 實例化Vue new Vue({ el: '#box', // 綁定id為box的標簽,固定寫法el data:{ msg: '測試', str1: 'love python', person:{ name: 'liu', age: 18 } } })
v-text相當於innerText
v-html相當於innerHTML
<!--直接將msg當成字符串讀取展示--> <div v-text="msg"></div> <!--讀取后解析成標簽展示,這個比較常用--> <div v-html="msg"></div>
new Vue({ el: '#box', data(){ // data中是一個函數,函數返回一個對象,可以為空,但必須返回,data中的數據發生改變頁面引用相關的值也會發生改變,因為data是observer,持續監聽 return { msg: "<h4>你好</h4>" } } })
<div id="box"> <!--執行add方法並將值展示在頁面--> {{ add(1, 2) }} <!--給button按鈕綁定click事件,方法是changeShow--> <button v-on:click = 'changeShow'>點擊顯示隱藏</button> <!--isShow為true就顯示,為false就隱藏--> <div class="t1" v-show="isShow"></div> <!--官網例子,如果隨機數大於0.5就顯示Now you see me, 否則就顯示Now you don't--> <div v-if="Math.random() > 0.5"> Now you see me </div> <div v-else> Now you don't </div> </div>
// 數據驅動視圖 new Vue({ el: '#box', data(){ return{ isShow: true } }, // 方法都在這里面定義 methods: { add(x, y){ return x+y }, changeShow(){ // 點擊按鈕就取反然后賦值,所以點擊就是一直顯示隱藏 this.isShow = !this.isShow } } })
v-if和v-show 等於 true都是表示顯示,false表示隱藏,那區別是啥呢?
v-if vs v-show v-if 是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。 v-if 也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。 相比之下,v-show 就簡單得多——不管初始條件是什么,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。 一般來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,
則使用 v-show 較好(也可以通過增加class或刪除class實現);如果在運行時條件很少改變,則使用 v-if 較好。
上面是官網說法,實際上簡單來講就是v-show就是改變display屬性,而v-if則是對dom的創建和刪除.
v-bind可以綁定標簽中任何屬性 比如:img標簽的src,a標簽的href,id,class,name等 v-on 可以監聽 js中所有事件 簡寫: v-bind:src 等價於 :src v-on:click 等價於 @click
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .t1{ width: 200px; height: 200px; background-color: #ff0000; } .active{ background-color: #0f0; } </style> </head> <body> <div id="box"> <!--第一種寫法--> <!--<button v-on:mouseenter="changeGreen" v-on:mouseLeave="changeRed">改變顏色</button>--> <!--綁定src和alt屬性,使用從服務器返回的動態數據--> <!--<img v-bind:src="imgSrc" v-bind:alt="imgAlt">--> <!--如果isActive為true就把active加到class里面,為false就不加--> <!--<div class="t1" v-bind:class="{active:isActive}"></div>--> <!--第二種簡寫,以后都用簡寫--> <button @mouseenter="changeGreen" @mouseLeave="changeRed">改變顏色</button> <!--綁定src和alt屬性,使用從服務器返回的動態數據--> <img :src="imgSrc" :alt="imgAlt"> <!--如果isActive為true就把active加到class里面,為false就不加--> <div class="t1" :class="{active:isActive}"></div> </div> </body> <script src="vue.js"></script> <script> //數據驅動視圖 設計模式 MVVM Model(數據) View(前端展示) ViewModel(類似v-bind方法) new Vue({ el: '#box', data(){ // img相關的動態數據 return { imgSrc: "timg.jpg", imgAlt: '圖片', isActive: true, } }, methods: { // 鼠標進入離開的執行方法 changeGreen(){ this.isActive = false; }, changeRed(){ this.isActive = true; } } }) </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box"> <!--先判斷返回的狀態是否正確,如果正確才顯示整個ul列表--> <ul v-if="data.status == 'ok'"> <!--循環用戶列表,index表示索引,從0開始,一定要綁定key,有id就需要用id綁定,沒有則用index, 綁定key是為了避免修改數據后vue自動內部遍歷,綁定之后修改了哪個數據就只修改哪一個,避免性能損耗,v-for的優先級最高--> <li v-for="(item, index) in data.user_list" :key="item.id"> <h3>{{ index }} -- {{ item.id }} -- {{ item.name }} -- {{ item.age }}</h3> </li> </ul> <!--for循環遍及對象, 注意順序,值在第一個--> <div v-for="(value, name, index) in object"> {{ index }} -- {{ name }}: {{ value }} </div> </div> </body> <script src="vue.js"></script> <script> new Vue({ el:'#box', data(){ return { data: { status: 'ok', user_list: [ {id: 1, name: 'liu', age: '18'}, {id: 2, name: 'xiao', age: '28'}, {id: 3, name: 'bai', age: '38'}, ] }, object:{ name: 'liu', age: '18', } } } }) </script> </html>
1.輪播圖實現
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box" style="text-align: center;"> <div> <img :src="imageSrc[currentNum].image_url" alt=""> </div> <button @click="prevImage">上一張</button> <button @click="nextImage">下一張</button> </div> </body> <script src="vue.js"></script> <script> let vm = new Vue({ el: '#box', data(){ return { imageSrc:[ {id:1, image_url: 'images/1.jpg'}, {id:2, image_url: 'images/2.jpg'}, {id:3, image_url: 'images/3.jpg'}, ], currentNum: 0, } }, methods: { prevImage(){ this.currentNum--; if (this.currentNum < 0){ this.currentNum = this.imageSrc.length-1; } }, nextImage(){ this.currentNum++; if (this.currentNum >= this.imageSrc.length){ this.currentNum = 0; } } }, // 生命周期鈎子,vue實例創建后執行 created(){ // 通過箭頭函數將this指向了Vue對象,實現了每兩秒自動輪播 setInterval(() => { this.currentNum++; if (this.currentNum >= this.imageSrc.length){ this.currentNum = 0; } },2000) } }) </script> </html>
2.音樂播放器實現
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>音樂播放器</title> <style> li.active{ color: #0079f4; } </style> </head> <body> <div id="box"> <!--src綁定當前的索引music_url,@onended播放完成 會自動調用endMusicHandler方法--> <audio :src="musicData[currentIndex].music_url" controls autoplay @onended="endMusicHandler"></audio>
<ul> <!--循環musicData,當前currentIndex和index相等時就播放該歌曲並高亮顯示--> <li v-for="(item, index) in musicData" :key="item.id" :class="{active:index==currentIndex}" @click="musicHandler(index)"> <p>{{ item.name }}</p> </li> </ul> </div> </body> <script src="./js/jquery-3.3.1.min.js"></script> <script src="vue.js"></script> <script> var music_list = [ { id: 1, name: '拿走了什么', music_url: './mp3/happy.mp3' }, { id: 2, name: '逍遙嘆', music_url: './mp3/h1.mp3' }, { id: 3, name: '情歌', music_url: './mp3/h2.mp3' } ]; let vm = new Vue({ el: '#box', data(){ return { musicData:[], currentIndex: 0 } }, methods:{ // 接收當前用戶選擇的index,並賦值給currentIndex musicHandler(index){ this.currentIndex = index; }, endMusicHandler(){ this.currentIndex++; // 如果當前用戶選擇的index>=musicData的長度就證明到最后了,因此又去到第一首 if (this.currentIndex >= this.musicData.length){ this.currentIndex = 0 } } }, created(){ this.musicData = music_list } }) </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box"> <p>{{ msg }}</p> <button @click="changeHandler">點擊修改</button> </div> </body> <script src="vue.js"></script> <script> new Vue({ el:'#box', data(){ return { msg: 'liu', age: 18 } }, methods:{ changeHandler(){ this.msg = 'haha'; } }, watch: { // watch偵聽單個屬性,如果想監聽多個屬性 聲明多個屬性的監聽(例如msg, age) 'msg': function (values) { if (values == 'haha') { this.msg = "hhh"; } }, 'age':function () { } } }) </script> </html>
2.計算屬性 computed, 可以同時監聽多個屬性(計算屬性是基於它們的響應式依賴進行緩存的。只在相關響應式依賴發生改變時它們才會重新求值。)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box"> <!--直接調用計算屬性myMsg--> <p>{{ myMsg }}</p> <button @click="changeHandler">點擊修改</button> </div> </body> <script src="vue.js"></script> <script> new Vue({ el:'#box', data(){ return { name: 'liu', age: 18 } }, methods:{ changeHandler(){ this.name = 'haha'; this.age = 20; } }, computed: { // 計算屬性默認只有getter方法 myMsg: function () { // 這里可以寫很多業務邏輯,比如額外增加年齡 this.age += 2; return `我的名字是${this.name},年齡是${this.age}` } } }) </script> </html>