前端、django的重點簡單描述:javascript
""" 一、BBS:先後臺不分離的web項目 前臺頁面主要是經過後臺邏輯完成渲染 二、Django:Python Web 框架 HttpResponse | ORM | 模板語言 | Forms | Auth 三、前端:HTML5 CSS3 JavaScript jQuery Bootstrap HTML5:頁面架構 CSS3:選擇器 樣式 佈局 JS:ES DOM BOM => 選擇器拿到標籤,操做標籤,標籤事件完成交互 DOM驅動 => Vue數據驅動 """
先後端不分離值得是前端的數據都是由後端用語法渲染出來的,好比Django的render、redirect等,前端頁面都是由它們渲染好而後返回的。先後端分離值得是前端後端服務器不一樣,各寫各的,僅僅只進行數據的交互。先後端分離對於Django來講稍微麻煩一點,由於csrf跨站請求僞造的存在,Django沒法從不是它渲染的頁面中拿到csrf_token,這就意味着先後端分離時,Django須要註釋掉csrf中間件,而後須要咱們本身寫對應的驗證。css
vue框架:html
# Angular React Vue # js漸進式框架:一個頁面小到一個變量,大到整個頁面,都可以有vue控制,vue也能夠控制整個項目 # 思考:vue如何作到一次引入控制整個項目 => 單頁面應用 => vue基於組件的開發 # vue的工做原理:vue如何渲染一個頁面 # vue的組件概念 # vue路由的概念 # vue的ajax概念 # 學習曲線:vue的指令 vue的實例成員 vue組件 vue項目開發
vue的優勢:前端
""" 1.單頁面:高效 2.虛擬DOM:頁面緩存 3.數據的雙向綁定:數據是具備監聽機制 4.數據驅動:從數據出發,不是從DOM出發 """
""" 1.下載vue.js:https://vuejs.org/js/vue.js 2.在要使用vue的html頁面經過script標籤引入 3.在html中書寫掛載點的頁面結構,用id表示 4.在自定義的script標籤實例化Vue對象,傳入一個大字典 5.在字典中經過 el與掛載點頁面結構綁定,data爲其經過數據 """
固然可使用cdn,也能夠直接在官網將vue的代碼複製下來, 而後新建一個js文件黏貼便可。具體步驟以下:vue
不管在使用一個框架仍是一門開發語言,最重要的就是要學會看官方的文檔,建議天天學習一下英語,達到可以閱讀英語文檔的能力。vue文檔連接:https://cn.vuejs.org/v2/guide/index.htmljava
vue是經過new來實例化一個對象,而後該對象裏面經過el來添加掛載點,data來給變量提供數據,methods來給掛載點提供事件。python
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue初始</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- {{ vue變量 }} 插值表達式 裏面的大括號最好在前面加個空格,增長瀏覽器的兼容性 --> <h1>{{ msg1 }}</h1> <h2>{{ msg2 }}</h2> </div> <!-- vue掛載點一次只能掛載一個,好比不少標籤都繼承同一個類,使用類選擇器時, vue只會掛載找到的第一個標籤,因此最好都使用標籤選擇掛載點 --> <!--<div class="app">--> <!--<h1>{{ msg1 }}</h1>--> <!--<h2>{{ msg2 }}</h2>--> <!--</div>--> </body> <!--將script寫在body下面比較保險,能夠不用考慮加載時從上往下執行可能發生的問題--> <script src="vue.js"></script> <script> // Vue new Vue({ el: '#app', //掛載點 data: { // 給各變量提供數據 變量名:變量的值 //vue的實例data中鍵值對,其實 鍵 都是字符串,只是省略了引號 msg1: 'h1的內容', msg2: 'h2的內容', }, methods:{ //爲掛載點提供事件 函數名: function(){} } }) </script> </html>
vue是經過如下方式來給標籤綁定事件:jquery
<!--綁定事件語法 v-on:事件名='函數名' --> <p v-on:click="clickMe">點我</p> <!--綁定事件語法簡寫 @事件名='函數名' --> <p @click="clickMe2">你也點我一下</p>
而後在vue對象的methods中寫函數名與對應實現體的邏輯便可,具體代碼以下:web
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue完成簡單的事件</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!--綁定事件語法 v-on:事件名='函數名' --> <p v-on:click="clickMe">點我</p> <!--綁定事件語法簡寫 @事件名='函數名' --> <p @click="clickMe2">你也點我一下</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', methods: { // 爲掛載點提供事件 clickMe : function () { alert(1111) }, clickMe2: function () { alert(2222) } } }) </script> </html>
vue操做樣式是經過控制標籤的屬性來實現的,控制樣式經過如下方式:ajax
<!-- 屬性指令:用vue綁定屬性,將屬性內容交給vue處理 --> <!-- 語法:v-bind:屬性名="變量" (v-bind: 能夠簡寫爲 :) --> <p @click="clickMe" v-bind:style="col">點擊當場變綠</p>
固然還能夠給樣式寫成字典的形式,經過不一樣變量控制不一樣的樣式:
<!-- 一個{}:{}內一個個屬性有一個個變量單獨控制 --> <!--這裏只需在data中定義col與fs兩個變量的值便可--> <p @click="clickMe" v-bind:style="{color: col,'font-size': fs}">點擊當場變綠</p>
注意,以上font-size不加引號時須要寫爲駝峯體:fontSize。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue操做樣式</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <p @click="clickMe" v-bind:style="col">點擊當場變綠</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { // 須要以字典的形式改值,由於style是color:red;的形式 col: {color: 'green'} }, methods: { clickMe: function () { //this表明的是整個vue對象 this.col = {color: 'red'} } } }) </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>操做樣式</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- 一個{}:{}內一個個屬性有一個個變量單獨控制 --> <p @click="clickMe" v-bind:style="{color: col,'font-size': fs}">點擊當場變綠</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { fs: '20px', col: 'green', }, methods: { clickMe: function () { this.col = 'red'; this.fs = '25px'; } } }) </script> </html>
vue經過如下方式來實現文本指令:
<!-- 插值表達式就是 v-text --> <p>{{ msg1 }}</p> <p v-text="msg2"></p> <!-- 能夠解析html標籤 --> <p v-html="msg3"></p> <!-- 必須賦初值,渲染的結果永遠不會發生改變 --> <p v-once="msg3" @click="clickMe">{{ msg3 }}</p>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文本指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- 插值表達式就是 v-text --> <p>{{ msg1 }}</p> <p v-text="msg2"></p> <!-- 能夠解析html標籤 --> <p v-html="msg3"></p> <!-- 必須賦初值,渲染的結果永遠不會發生改變 --> <p v-once="msg3" @click="clickMe">{{ msg3 }}</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { msg1:'**msg1**', msg2:'<h2>msg2</h2>', msg3:'<h2>msg3</h2>', }, methods:{ clickMe:function () { // var msg = this.$data.msg3; // 實例中要訪問一階變量好比el、data等,須要加$,this.$el, // 通常要訪問二階的直接this.二階變量 便可 this.msg3 = '<h2>msg3666</h2>' } } }) </script> </html>
前面稍微提了如下vue簡單的事件綁定,這裏再來看看:
<!-- v-on:事件名="函數名" 能夠簡寫爲 @事件名="函數名" (v-on: => @)--> <p v-on:click="action1">{{ msgs[0] }}</p> <p @click="action2">{{ msgs[1] }}</p>
實際上,當綁定事件的時候是能夠給函數傳參的,在函數名後面加個括號表示傳參,並且默認是有一個event對象傳過去的,當加了括號以後,不管你傳多少參數,都須要加一個參數$event,否則event對象就會失效。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <ul id="app"> <!-- v-on:事件名="函數名" 能夠簡寫爲 @事件名="函數名" (v-on: => @)--> <!-- 事件的傳參 --> <li @click="action(111)">列表項1</li> <li @click="action(222)">列表項2</li> <li @click="action(333)">列表項3</li> <li @click="actionMouse">列表項4</li> <!-- 鼠標事件的對象:直接寫函數名,默認將鼠標事件對象傳入 --> <div @click="func1">func1</div> <!-- 鼠標事件的對象:一旦添加(),就必須手動傳參,$event就表明鼠標事件對象 --> <div @click="func2($event, 'abc')">func2</div> </ul> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', methods:{ action:function (num) { alert(num) }, actionMouse:function (event) { console.log(event) }, func1: function (ev) { console.log(ev) }, func2: function (ev, msg) { console.log(ev); console.log(msg) } } }) </script> </html>
vue屬性指令經過如下方式實現:
<!-- 屬性指令:用vue綁定屬性,將屬性內容交給vue處理 --> <!-- 語法:v-bind:屬性名="變量" (v-bind: 能夠簡寫爲 :) --> <p class="" style="" v-bind:owen="oo" :jason="jj"></p>
當「」中再以''將變量放在裏面是,變量就再也不時變量,而是常量:
<!-- br'是變量 --> <p :class="[c1, 'br']"></p> <!-- 'br' 固定寫死的數據,再也不是變量 --> <p :class="[c1, 'br']"></p>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>屬性指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> div { width: 100px; height: 100px; } .gDiv { background-color: green; } .rDiv { background-color: red; } .br { border-radius: 50%; } </style> </head> <body> <div id="app"> <div @click="clickMe" :class="c1"></div> <!-- 屬性指令:用vue綁定屬性,將屬性內容交給vue處理 --> <!-- 語法:v-bind:屬性名="變量" (v-bind: 能夠簡寫爲 :) --> <div :class="[c1, c2]"></div> <!-- 'br' 固定寫死的數據,再也不是變量 --> <div :class="[c1, 'br']"></div> </div> </body> <script src="vue.js"></script> <script> new Vue({ el:'#app', data:{ c1: 'rDiv', c2: 'br' }, methods:{ clickMe:function () { if(this.c1=='rDiv'){ this.c1='gDiv' }else { this.c1 = 'rDiv' } } } }) </script> </html>
屬性指令是經過on-bind或者是簡寫:來實現,可是在form表單中,value屬性要使用on-model來實現控制:
<!-- 表單指令:v-model="變量" --> <input type="text" v-model="val"> <!-- 單選框 v-model綁定的變量是單選框中某一個input的value --> <p> 男: <input v-model="r_val" value="male" type="radio" name="sex"> 女: <input v-model="r_val" value="female" type="radio" name="sex"> </p>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表單指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <!-- 表單指令:v-model="變量" --> <form id="app"> <p>username<input v-model="val" type="text" name="username"></p> <p>re_username<input v-model="val" type="text" name="re_username"></p> <div> <!-- 單選框 v-model綁定的變量是單選框中某一個input的value --> 男<input v-model="sex" type="radio" name="sex" value="male"> 女<input v-model="sex" type="radio" name="sex" value="female"> </div> <div> <!-- 複選框 v-model綁定的變量是一個列表,列表存存放0到任意個複選框的value --> 男<input v-model="hobby" type="checkbox" name="hobby" value="male"> 女<input v-model="hobby" type="checkbox" name="hobby" value="female"> 哇塞<input v-model="hobby" type="checkbox" name="hobby" value="ws"> </div> <button>提交</button> </form> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data:{ val:'', sex:'male', hobby:['male', 'female'], } }) </script> </html>
條件指令分爲兩種:
<!-- 條件指令 v-show | v-if--> <!-- v-show:消失是以 display: none渲染 當v-show的值爲false時觸發 --> <div v-show="s1"></div> <!-- v-if:消失時不會被渲染渲染,因此建議創建緩存, 用key屬性 --> <div class="wrap red" v-if="tag==0" :key="0"></div> <div class="wrap green" v-else-if="tag==1" :key="1"></div> <div class="wrap blue" v-else key="2" :key="'2"></div> <!-- v-if相關分支操做,在未顯示狀況下,是不會被渲染到頁面中 --> <!-- 經過key全局屬性操做後,渲染過的分支會創建key對應的緩存,提升下一次渲染速度 -->
條件指令中v-show和v-if的循環,裏面是能夠直接寫false或true的,他們會自動解析爲布爾值,不會將它們當作變量。
v-show不寫條件默認是false,即display:none隱藏標籤。
v-else會默認與v-if等有條件的分支綁定。
v-else-if必須有條件才和有條件v-if分支綁定。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>模板</title> </head> <body> <div id="app"> <p v-if="r1" key="p_r1">if條件</p> <p v-show="r2">show條件</p> <!--{{ num + 1 - 5 * 2 + '好的' }}--> <ul> <!--v-else會默認與v-if等有條件的分支綁定--> <!--v-else-if必須由條件才和有條件v-if分支綁定--> <!--能夠刪除各分支的條件來進行驗證--> <li v-if="tag == 1">111</li> <li v-else-if="tag == 2">222</li> <li v-else>333</li> </ul> <ul> <li @click="action('a')">a</li> <li @click="action('b')">b</li> <li @click="action('c')">c</li> </ul> <ul> <li v-show="flag == 'a'">aaa</li> <li v-show="flag == 'b'">bbb</li> <li v-show="flag == 'c'">ccc</li> </ul> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { num: 10, r1: false, r2: false, tag: 2, flag: 'a' }, methods: { action: function (s) { this.flag = s } } }) </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>條件指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> .wrap { width: 300px; height: 100px; } .red {background-color: red;} .green {background-color: green;} .blue {background-color: blue;} </style> </head> <body> <div id="app"> <!-- 條件指令 v-show | v-if--> <!-- v-show:消失是以 display: none渲染 當v-show的值爲false時觸發 --> <div v-show="s1"></div> <ul> <li @click="action(0)" style="float: left">red</li> <li @click="action(1)" style="float: left">green</li> <li @click="action(2)" style="float: left">blue</li> </ul> <!-- v-if:消失時不會被渲染渲染,因此建議創建緩存, 用key屬性 --> <div class="wrap red" v-if="tag==0" key="0"></div> <div class="wrap green" v-else-if="tag==1" key="1"></div> <div class="wrap blue" v-else key="2" key="'2"></div> <!-- v-if相關分支操做,在未顯示狀況下,是不會被渲染到頁面中 --> <!-- 經過key全局屬性操做後,渲染過的分支會創建key對應的緩存,提升下一次渲染速度 --> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data:{ tag:0, s1:false }, methods:{ action:function (tag) { this.tag=tag } } }) </script> </html>
循環指令語法以下:
<!-- v-for="item in items" --> <!-- 遍歷的對象: 數組[] 對象(字典){} -->
當遍歷數組時,能夠用兩個參數來獲取值與索引:
<!-- n爲遍歷的元素值 --> <ul> <li v-for="n in list">{{ n }}</li> </ul> <!-- n爲遍歷的元素值, index爲索引 --> <ul> <li v-for="(n, index) in list">{{ n }}{{ index }}</li> </ul>
當遍歷自定義對象{}時,能夠有三個參數:
<!-- v-for變量對象{}時,接收三個值時,第一個爲元素值,第二個爲元素鍵,第三個爲元素索引 --> <ul> <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li> </ul>
在不少時候,爲了增長渲染的速度,須要創建緩存:
<!-- 通常列表渲染須要創建緩存 --> <!-- 列表渲染是循環,須要賦值變量給key,使用key須要v-bind:處理 --> <!-- v-for變量數組[]時,接收兩個值時,第一個爲元素值,第二個爲元素索引 --> <ul> <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li> </ul>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>循環指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- v-for="item in items" --> <!-- 遍歷的對象: 數組[] 對象(字典){} --> <ul> <!-- 只遍歷數組的值 --> <li v-for="num in nums">{{ num }}</li> </ul> <ul> <!-- 遍歷數組的值與索引 --> <li v-for="(num, index) in nums">{{ num }} {{ index }}</li> </ul> <ul> <!-- 自定義對象(字典)的 值、鍵、索引 --> <li v-for="(v, k, index) in dic">{{ v }} {{ k }} {{ index }}</li> </ul> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data:{ nums:[5, 2, 3, 1, 4], dic:{ name: 'json', age: '18', gender: 'male' } }, }) </script> </html>
<div id="app"> <h1>{{ msg }}</h1> <!-- v-for="item in items" --> <!-- 遍歷的對象: 數組[] 對象(字典){} --> <ul> <li>{{ list[0] }}</li> <li>{{ list[1] }}</li> <li>{{ list[2] }}</li> <li>{{ list[3] }}</li> <li>{{ list[4] }}</li> </ul> <!-- n爲遍歷的元素值 --> <ul> <li v-for="n in list">{{ n }}</li> </ul> <!-- 通常列表渲染須要創建緩存 --> <!-- 列表渲染是循環,須要賦值變量給key,使用key須要v-bind:處理 --> <!-- v-for變量數組[]時,接收兩個值時,第一個爲元素值,第二個爲元素索引 --> <ul> <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li> </ul> <ul> <li>{{ dic['name'] }}</li> <li>{{ dic.age }}</li> <li>{{ dic.gender }}</li> </ul> <!-- v-for變量對象{}時,接收三個值時,第一個爲元素值,第二個爲元素鍵,第三個爲元素索引 --> <ul> <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li> </ul> <!-- 遍歷的嵌套 --> <div v-for="(person, index) in persons" :key="index" style="height: 21px;"> <div v-for="(v, k) in person" :key="k" style="float: left;">{{ k }} : {{ v }} </div> </div> </div> <script type="text/javascript"> new Vue({ el: "#app", data: { msg: "列表渲染", list: [1, 2, 3, 4, 5], dic: { name: 'zero', age: 88888, gender: 'god' }, persons: [ {name: "zero", age: 8}, {name: "egon", age: 78}, {name: "liuXX", age: 77}, {name: "yXX", age: 38} ] } }) </script>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>發表評論示例</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> span { margin-left: 100px; } /*利用僞類選擇器,鼠標懸浮是將字體顏色變爲紅色*/ span:hover { color: red; } </style> </head> <body> <div id="app"> <input type="text" v-model="val"> <button @click="action">提交評論</button> <ui> <!--將索引拿出當作事件函數的參數,方便刪除--> <li v-for="(msg, index) in msgs">{{ msg }}<span @click="del(index)">X</span></li> </ui> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { val: '', //存放即將發表的評論內容 msgs: ['hello', 'world'], //存放評論 }, methods:{ action:function () { //其實splice可完成數組的增刪改,他有三個參數,第一個是從哪一個索引開始(不包含當前索引) //第二個參數是操做幾個值,第三個參數是將操做的值替換爲何,不寫則替換爲空,至關於刪除 this.msgs.splice(0,0,this.val); this.val = '' //輸入評論框置空 }, del:function (index) { this.msgs.splice(index,1) //刪除留言 } } }) </script> </html>
前面實例成員用到了el、data、methods,接下來再補充一下computed、watch,它們的做用都是監聽,可是監聽的對象是相反的,computed監聽函數內的變量,watch監聽函數外的變量。
監聽方法內全部的變量,返回值給綁定的變量,該變量無需在data中聲明,只要裏面監聽的變量值發生變化,就會立刻執行一次該函數。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>實例成員之computed</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> 姓:<input type="text" v-model="first_name"> 名:<input type="text" v-model="last_name"> <p style="margin-top: 5px">姓名:<input type="text" v-model="full_name"></p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el:'#app', data:{ first_name: '', last_name: '', }, /* 計算 -- 監聽方法內全部的變量,返回值給綁定的變量,該變量無需在data中聲明, 只要裏面監聽的變量值發生變化,就會立刻執行一次該函數 */ computed:{ full_name:function () { return this.first_name + this.last_name } } }) </script> </html>
監聽綁定的變量,綁定的變量必須在data中聲明,只要監聽的變量值發生變化,就會立馬執行該函數,該函數的返回值是沒有任何意義的,因此不須要return。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>實例成員之watch</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <p>姓名:<input type="text" v-model="full_name"></p> 姓:<input type="text" v-model="first_name"> 名:<input type="text" v-model="last_name"> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data:{ first_name:'', last_name:'', full_name:'' }, watch:{ /* 監聽綁定的變量,綁定的變量必須在data中聲明, 只要監聽的變量值發生變化,就會立馬執行該函數, 該函數的返回值是沒有任何意義的,因此不須要return */ full_name:function () { //前端支持切分空 'abc' ->> ['a', 'b', 'c'] //python不支持切分空,會報錯,不過能夠經過list('abc')達到一樣的效果 let name = this.full_name.split(''); this.first_name = name[0]; this.last_name = name[1]; } } }) </script> </html>
使用Django時,前往模板渲染語法用的是{{ }},而vue的插值表達式也是同樣,因此一塊兒使用時會存在衝突的問題。這時候就須要用到delimiters來改變插值表達式的語法:
// 爲解決與前端模板語法的衝突,可使用delimiters自定義插值表達式的語法 // delimiters:['插值表達式前半部分', '後半部分'] delimiters:['${', '}']
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>解決插值表達式衝突</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <p>{{ msg }}</p> <p>${ msg }</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { msg: 'hello world' }, // 爲解決與前端模板語法的衝突,可使用delimiters自定義插值表達式的語法 delimiters:['${', '}'] }) </script> </html>
組件的概念:
每一個組件均具備自身的模板template,根組件的模板就是掛載點
每一個組件模板只能擁有一個根標籤
子組件的數據具備做用域,以達到組件的複用
使用vue時,實際項目中大多使用局部組件。局部組件與全局組件都擁有各自的名稱空間,這是經過將成員data的值賦予一個return 字典 的的function來實現的。
根組件就是咱們使用掛載點生成的vue實例:
<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>
其中html與body不能做爲掛載點,由於顯式書寫模塊會替換掛載點,而html與body是不能被替換,會報錯。這裏掛載點使用通用選擇器時會從上往下,將找到的第一個標籤做爲掛載點,而第一個標籤就是html標籤,因此通用選擇器*不能使用。
局部組件是經過定義變量,變量的值爲一個大字典,而字典中書寫的形式同vue實例中的書寫形式相同。局部組件與全局組件的模板能夠是是在template中書寫的部分,而不會使用掛載點,掛載點用於根組件。
局部組件使用前要在父組件的components中註冊,而後使用時當作一個自定義標籤使用便可。
let localTag = { template:` <p @click="action">點了我{{ count }}下</p> `, // 1.data要達到組件的複用,必須爲每一個組件提供一個名稱空間(做用域) // 2.data的值就是一個存放數據的字典 // 須要知足1和2,data值爲一個能夠產生名稱空間的函數的返回值,返回值是字典 data:function () { return { count: 0 } }, methods:{ action:function () { this.count++ } } }; //父組件 new Vue({ el: '#app', // 局部組件必須在父組件的components中註冊 components:{ // 註冊局部組件的別名: 局部組件原名 //當取的名字與局部組件名字相同時能夠這麼簡寫 localTag: localTag // 簡寫:localTag } })
template中要書寫多行html代碼時,使用ESC鍵下面的 `` 便可。
局部組件
let localTag = { template:` <p @click="action">點了我{{ count }}下</p> `, // 1.data要達到組件的複用,必須爲每一個組件提供一個名稱空間(做用域) // 2.data的值就是一個存放數據的字典 // 須要知足1和2,data值爲一個能夠產生名稱空間的函數的返回值,返回值是字典 data:function () { return { count: 0 } }, methods:{ action:function () { this.count++ } } };
全局組件經過經過Vue的一個方法來實現,使用時也是當自定義標籤來使用,不須要去父組件中註冊。
Vue.component(組件名, {組件主體});
全局組件與局部組件的取名都採用駝峯體的形式,而html中是不區分大小寫的,因此在標籤中建議使用 - 語法命名,對應js中就是駝峯命名:即local-tag等於localTag。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>全局組件</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> p { width: 100px; height: 100px; border: solid; } </style> </head> <body> <div id="app"> <!--在標籤中建議使用 - 語法命名,對應js中就是駝峯命名--> <global-tag></global-tag> <global-tag></global-tag> </div> </body> <script src="vue.js"></script> <script> //全局組件 Vue.component(組件名, {組件主體}); // 全局組件無需註冊 Vue.component('globalTag', { template:` <p @click="action">點了我{{ count }}下</p> `, data:function () { return { count: 0 } }, methods:{ action:function () { this.count++ //this.count += 1 } } }); //父組件 new Vue({ el:'#app', }) </script> </html>
父組件向子組件傳輸數據時,是經過在自定義屬性來實現的,以下:
<global-tag :hello="msg"></global-tag>
子組件名爲globalTag,在其中定義自定義屬性hello,由於該標籤是在父組件中,因此變量msg的值由父組件來提供,而後在子組件中經過props:['hello']來然內部可使用hello變量,而hello屬性的值又來自於父組件的msg變量,這就實現了父組件傳輸數據給子組件。注意:props內部走的其實是反射,因此它存儲值的列表中必須都是字符串的形式。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- local-tag就能夠理解爲自定義標籤,使用msg變量值由父組件提供 --> <!-- local-tag標籤表明的是子組件,owen爲標籤的自定義屬性 --> <!-- 在子組件內部能拿到owen,就能夠拿到父組件的信息 --> <global-tag :hello="msg"></global-tag> </div> </body> <script src="vue.js"></script> <script> //全局組件,是Vue的子組件 Vue.component('globalTag', { // 子組件拿自定義屬性 props:['hello'], template:` <p @click="action">{{ hello }}</p> `, }); //父組件 new Vue({ el:'#app', data:{ msg: '這是父組件的信息' } }) </script> </html>
首先子組件向父組件傳輸數據時,要知道何時傳,因此就須要使用事件。子組件中經過事件,在事件函數中使用this.$emit('自定義事件名', 給父組件的數據),而子組件是當作自定義標籤的方式在父組件中使用的,因此自定義事件的函數須要父類提供,而此時自定義事件的函數就能結束子組件傳輸的參數,也就是emit中第二個參數攜帶的數據。
this.$emit('alter', this.msg) <!--經過@子組件自定義事件名,在父組件的事件函數中拿到子組件的傳參--> <local-tag @alter="get_title"></local-tag> <!--父組件經過事件函數拿到子組件傳輸的數據--> get_title: function (msg) { this.msg = msg
具體事例以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>組件間的交互-子傳父</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!--經過@子組件自定義事件名,在父組件的事件函數中拿到子組件的傳參--> <local-tag @alter="get_title"></local-tag> <p>{{ msg }}</p> </div> </body> <script src="vue.js"></script> <script> let localTag = { //template中只能有一個根標籤 template:` <div> <input type="text" v-model="msg"> <button @click="action">修改父組件信息</button> </div> `, data: function(){ return { msg: '' } }, methods:{ action:function () { //$emit('自定義事件名', '參數') this.$emit('alter', this.msg) } }, // watch:{ // msg:function () { // this.$emit('alter', this.msg) // } // } }; new Vue({ el: '#app', data: { msg: '這是父組件的信息' }, methods: { get_title: function (msg) { this.msg = msg } }, components:{ localTag } }) </script> </html>