Vue.js - 1
Vue.js - 2javascript
例: <div id="app"> <!-- 原數據輸出 i am tom --> <p>{{msg}}</p> <!-- msg是原數據 | upper是過濾器名 --> <!-- 原數據過濾後輸出 I am tom --> <p>{{msg | upper}}</p> </div> <script> // 全局過濾器的結構,利用.filter關鍵字,第一個參數是自定義的過濾器名, // 第二個參數是一個回調函數,回調函數的第一個參數是原數據. Vue.filter('upper', function (value) { // 截取原數據的第一個字符並轉換爲大寫字母 + 從第一個字符以後截取的字符串. return value.slice(0, 1).toUpperCase() + value.slice(1) }); new Vue({ el: "#app", data: { msg: "i am tom" }, }) </script>
<!-- 帶參數的過濾器 --> 例: <div id="app"> <!-- 這裏過濾器傳進來的參數是upper --> <!-- 根據js中寫的邏輯那麼就輸出 I am jerry --> <p>{{msg | selectCase('upper')}}</p> </div> <script> // 'selectCase'是自定義過濾器名,第二個參數是一個回調函數, // 回調函數的第一個參數是原數據,第二個參數這裏作條件判斷用. Vue.filter('selectCase', function (value, select) { //若是回調函數中第二個參數 == upper 就將原數據中的第一個字符轉換爲大寫字母, //反之若是回調函數中第二個參數 == lower 就將原數據中的第一個字符轉換爲小寫字母 if (select == 'upper') { return value.slice(0, 1).toUpperCase() + value.slice(1) } else if (select == 'lower') { return value.slice(0, 1).toLowerCase() + value.slice(1) } }); new Vue({ el: "#app", data: { msg: "i am jerry" }, }) </script>
<!-- 多個過濾器能夠連用 --> 例: <div id="app"> <!--多個過濾器能夠連用--> <!-- 第一次過濾:原數據 -> I am jerry 第一次過濾:基於上次過濾結果 -> i am jerry 最後一次過濾後輸出 i am jerry-How are you --> {{msg | upper | selectCase('lower') | str}} </div> <script> // 過濾器1 Vue.filter('upper', function (value) { return value.slice(0, 1).toUpperCase() + value.slice(1) }); // 過濾器2 Vue.filter('selectCase', function (value, select) { if (select == 'upper') { return value.slice(0, 1).toUpperCase() + value.slice(1) } else if (select == 'lower') { return value.slice(0, 1).toLowerCase() + value.slice(1) } }); // 過濾器3 Vue.filter('str', function (value) { return value + "-How are you" }); new Vue({ el: "#app", data: { msg: "i am jerry" }, }) </script>
例: <div id="app"> <!-- msg原數據 lower過濾器 輸出 i am tom --> <p>{{msg | lower}}</p> </div> <script> new Vue({ el: "#app", data: { msg: "I am tom" }, // 局部定義過濾器 // 跟 el data平級 定義一個filters filters: { // lower是自定義過濾器名,後面跟上一個函數,value一樣是原數據. 'lower': function (value) { return value.slice(0, 1).toLowerCase() + value.slice(1) } } }) </script>
<!-- 全局定義自定義指令 --> <div id="app"> <!-- 加載頁面input框自動獲取焦點 --> <input type="text" v-focus> </div> <script> // 自定義指令的關鍵字是.directive; // 第一個參數是自定義指令名,要取消v-,在標籤上把v-加上; // 第二個參數是一個對象,對象的內部是自定義指令運行的階段,階段key對應一個函數; // 函數的第一個參數是元素節點,第二個參數是一些必要的屬性參數,在函數內部來進行自定義指令的邏輯. Vue.directive('focus',{ inserted:function (el, binding) { el.focus(); } }); new Vue({ el: "#app", data: {} }) </script>
<!-- 全局定義自定義指令 --> <div id="app"> <!-- 黃色 --> <div v-color>猜個人顏色</div> <!-- 紅色 --> <div v-color="color">猜個人顏色</div> </div> <script> // bind和inserted是咱們自定義指令的兩個經常使用的階段. // bind執行在inserted以前,是在指令綁定到元素時執行,或者叫編譯這個指令時執行. // 他們的運行相似於事件的機制,就是當指令綁定到dom時,執行bind後邊的函數. // 當將原dom對象用Vue編譯好之後(例如v-if,v-for都須要用Vue編譯才能在正常瀏覽器中顯示). // vue將編譯後的對象,替換掉原節點,替換好以後,觸發inserted後邊的函數, // vue的運行過程,是先薰染頁面,而後再獲取頁面的結構進行編譯. // 編譯成的對象叫作虛擬dom. // 編譯完成真實的dom對象後,替換掉頁面的dom結構. /* 總結:bind階段:指令初次綁定到dom元素時,調用bind後面的函數(只調用一次) inserted階段:Vue將原dom對象編譯好,再替換掉原dom元素,再調用inserted後面的函數. */ Vue.directive('color',{ //inserted執行在bind以後 inserted(el,binding){ alert("inserted"); el.style.backgroundColor="yellow"; el.style.backgroundColor=binding.value; console.log(binding.value); // red }, // bind執行在inserted以前 bind:function (el, binding) { alert("bind"); el.style.backgroundColor="yellow"; } }); new Vue({ el: "#app", data: { color:"red" } }) </script>
<div id="app"> <!--局部定義自定義指令--> <input type="text" v-fo> </div> <script> new Vue({ el: "#app", data: {}, // 局部定義自定義指令 directives:{ 'fo':{ inserted:function (el, binding) { el.focus(); } } } }) </script>
<!-- 簡單的例子開始 --> 例1: <div id="app"> <!-- {{}}中的複雜方法 輸出 dlrow olleh --> <p>{{ message.split('').reverse().join('') }}</p> <!-- 使用computed屬性替換掉的 輸出 dlrow olleh --> <p>{{ myMsg }}</p> </div> <script> new Vue({ el: "#app", data: { message: "hello world" }, // 使用computed屬性,替換掉{{}}中的複雜方法 computed: { myMsg: function () { //以空字符串截取成一個數組再反轉過來以空字符串轉換成字符串 return this.message.split('').reverse().join('') }, }, </script>
<!--加法運算的功能,p標籤時兩個input框的計算結果,而且input框改變時,同時改變p標籤結果--> 例2: <div id="app"> <!-- 由於輸入的是字符串因此要轉換爲number類型再進行運算 --> <input type="text" v-model.number="input1"> + <input type="text" v-model.number="input2"> = <!--equal是使用computed屬性計算出來的 --> <span>{{ equal }}</span> --- <!--equal2是經過methods函數內部邏輯計算出來的,運算結果同上--> <span>{{ equal2() }}</span> </div> <script> new Vue({ el: "#app", data: { input1: 0, input2: 0 }, // 使用computed屬性,替換掉{{}}中的複雜方法 computed: { equal: function () { return this.input1 + this.input2 }, }, // 在函數裏也能夠進行邏輯運算 methods: { equal2:function () { return this.input1 + this.input2 }, } </script>
<!--需求:咱們但願把數據大於0的項顯示出來,把小於0的項過濾掉--> 例3: <div id="app"> <ul> <li v-for="item in changedArr">{{item}}</li> </ul> </div> <script> new Vue({ el: "#app", data: { arr: [1, 2, 3, 4, 5, -1, -2, -3] }, // 使用computed屬性,替換掉{{}}中的複雜方法 computed: { // 過濾後的數組 changedArr: function () { return this.arr.filter(function (item, index) { //該函數返回結果是true的項組成的新數組 return item > 0 }) } }, </script>
Component 組件html
1. 寫法一:使用Vue.extend方法定義組件,使用 Vue.component方法註冊組件vue
<div id="app"> <!-- 這裏的標籤必須與全局註冊的標籤一致 --> <tmp1></tmp1> </div> <script type="text/javascript"> // 1. 寫法一:使用Vue.extend方法定義組件,使用 Vue.component方法註冊組件 //定義組件 var tmp1 = Vue.extend({ template:"<div><a href='#'>註冊</a></div>" }); //全局註冊組件 Vue.component('tmp1',tmp1); new Vue({ el:"#app", data:{} }); </script>
2.寫法二: 使用 Vue.component方法定義註冊組件一步到位java
<div id="app"> <!-- 這裏的標籤必須與全局註冊的標籤一致 --> <tmp2></tmp2> </div> <script type="text/javascript"> //定義和註冊組件一步到位 Vue.component('tmp2',{ template:"<div><a href='#'>tmp2</a></div>" }) new Vue({ el:"#app", data:{} }); </script>
3.寫法三:將組件內容定義到template模板中ios
<!--將組件內容定義到template模板中 --> <template id="tmp3"> <div><a href='#'>tmp3</a></div> </template> <div id="app"> <tmp3></tmp3> </div> <script type="text/javascript"> Vue.component('tmp3',{ template:"#tmp3" }) new Vue({ el:"#app", data:{} }); </script>
4.寫法四:將組件內容定義到類型爲 x-template的script模板中git
<!-- 將組件內容定義到類型爲 x-template的script模板中 --> <script type="x-template" id="tmp4"> <div><a href='#'>tmp4</a></div> </script> <div id="app"> <tmp4></tmp4> <login-To></login-To> </div> <script type="text/javascript"> Vue.component('tmp4',{ template:"#tmp4" }) // 命名時的注意點:使用駝峯形式命名時,須要把view層的標籤改爲中劃線鏈接的形式 Vue.component('loginTo',{ template:"#tmp4" }) new Vue({ el:"#app", data:{} }); </script>
<!-- 定義組件id爲tmp的組件模板 --> <template id="tmp"> <div> Hello World <!-- login組件必須放在內部設置一個根節點 --> <!-- template不算根節點 --> <login></login> </div> <!-- 在account組建中使用login子組件 --> </template> <div id="app"> <account></account> </div> <script type="text/javascript"> //定義和註冊account組件 Vue.component("account",{ template:"#tmp", //在account組件中定義和註冊一個login子組件 //這裏面的組件是局部組件 components:{ 'login':{ template:"<p>登陸</p>" } } }) new Vue({ el:"#app", data:{} }); </script>
<!-- 組件模板 --> <template id="temp"> <div @click = "login()"> Hello World <!-- 定義的子組件只能在父組件中使用,不然無論用,子組件的事件不會冒泡到父元素身上 --> <login @click = "login()"></login> <!-- .stop禁止事件冒泡到父元素身上 --> <button @click.stop = "login()">點我</button> </div> </template> <div id="app"> <!-- 使用組件 --> <account></account> </div> <!--子組件只能在父組件的模板中使用, 組件跟組件的做用域是相互獨立的 組件跟組件全部的屬性都是獨立的,包括methods,filters,directives,data 這也是局部定義屬性的意義. --> <script type="text/javascript"> //定義和註冊組件 Vue.component("account",{ template:"#temp", components:{ 'login':{ template:"<button>登陸</button>" } }, // 注意:原來在new Vue()中定義的data是一個對象 // 可是在組件中定義的data是一個方法,而且在這個方法中必定要return一個對象 data:function(){ return { msg: "我是account組件中的msg!" }; }, //定義一個方法 methods:{ login:function(){ alert(this.msg); } } }); new Vue({ el:"#app", data:{} }); </script>
Vue能夠藉助於vue-resource或者axios來實現AJAX請求(axios不支持jsonp),
同源策略:A網頁設置的 Cookie,B網頁不能打開,除非這兩個網頁"同源"。所謂"同源"指的是"三個 相同"。
協議相同
域名相同
端口相同
例:http://xxx.com:80/login.html
協議:http
域名:xxx.com
端口:80github
http請求報文ajax
瀏覽器與服務器數據交互是遵循http協議的,當瀏覽器要訪問服務器的時候,瀏覽器須要將相關請求數據提交給服務器(例如:瀏覽器信息,url地址,參數等),一般是經過請求報文來提交的npm
請求報文的格式分爲:json
一、請求報文行 二、請求報文頭 三、請求報文體
http響應報文
當瀏覽器請求服務器的時候,服務器須要將數據返回給瀏覽器,這種數據是經過響應報文響應回瀏覽器的
響應報文的格式分爲:
一、響應報文行 二、響應報文頭 三、響應報文體
就是利用<script>標籤沒有跨域限制的「漏洞」(歷史遺蹟啊)來達到與第三方通信的目的。
<script> function test(data) { console.log(data); } </script> <script src="http://vue.studyit.io/api/jsonp?callback=test"> </script>
CORS須要瀏覽器和服務器同時支持。目前,全部瀏覽器都支持該功能,IE瀏覽器不能低於IE10。
整個CORS通訊過程,都是瀏覽器自動完成,不須要用戶參與。對於開發者來講,CORS通訊與同源的AJAX通訊沒有差異,代碼徹底同樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感受。
所以,實現CORS通訊的關鍵是服務器。只要服務器實現了CORS接口,就能夠跨源通訊。
Vue與後臺Api進行交互一般是利用vue-resource(其中的一種方法)來實現的,本質上vue-resource是經過http來完成AJAX請求響應的
get請求地址:http://vue.studyit.io/api/get...
post請求地址:http://vue.studyit.io/api/add... 參數:name:'奔馳'
jsonp請求地址:http://vue.studyit.io/api/jsonp
vue結合vue-resource寫法步驟
一、經過 https://cdn.jsdelivr.net/vue.resource/1.2.1/vue-resource.min.js 下載到vue-resource文件 二、在html頁面中經過script標籤導入vue-resource.min.js 文件後,就會自動的在Vue對象實例上初始化 $http 三、使用 // 全局Vue對象寫法 Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback); Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback); // 在Vue對象中的寫法 this.$http.get('/someUrl', [options]).then(successCallback, errorCallback); this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
vue-resource get請求
寫法格式: this.$http.get('請求的url', [可選參數對象,使用{}傳參]).then(成功回調函數, 失敗回調函數); 成功回調函數參數對象主要屬性說明: 一、url : 請求的原始url 二、body: 響應報文體中的數據(咱們一般用這個屬性獲取服務器返回的數據) 三、其餘屬性請看文檔 舉例: this.$http.get('http://vuecms.ittun.com/api/getlunbo?id=1').then(function(res){console.log(res.body)}, function(err){//err是異常數據});
vue-resource post請求
寫法格式: this.$http.post('請求的url',[可選參數請求報文體對象body,使用{}傳參], [可選參數對象,使用{}傳參]).then(成功回調函數, 失敗回調函數); 成功回調函數參數對象主要屬性說明: 一、url : 請求的原始url 二、body: 響應報文體中的數據(咱們一般用這個屬性獲取服務器返回的數據) 三、其餘屬性請看文檔 注意點: $http.post()方法中的第二個參數固定寫成:{emulateJSON:true},不然可能形成服務器沒法接收到請求報文體中的參數值 舉例: this.$http.post('http://vuecms.ittun.com/api/adddata?id=1' //請求的url ,{content:'hello'} //請求報文體中傳入的參數對象,多個使用逗號分隔 ,{emulateJSON:true} //固定寫法,保證服務器能夠獲取到請求報文體參數值 ).then(function(res){console.log(res.body)}, function(err){//err是異常數據});
vue-resource jsonp請求
jsonp請求主要用來解決ajax跨域請求問題,使用jsonp實現跨域首先要保證服務器api支持jsonp請求的格式 寫法格式: this.$http.jsonp('請求的url', [可選參數對象,使用{}傳參]).then(成功回調函數, 失敗回調函數); 成功回調函數參數對象主要屬性說明: 一、url : 請求的原始url 二、body: 響應報文體中的數據(咱們一般用這個屬性獲取服務器返回的數據) 三、其餘屬性請看文檔 舉例: this.$http.jsonp('http://vuecms.ittun.com/api/getlunbo?id=1').then(function(res){console.log(res.body)}, function(err){//err是異常數據});
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; text-decoration: none; } .title { margin: 0 auto; width: 100px; height: 100px; } h2 { text-align: center; margin: 50px; font-family: "宋體"; color: #333; font-size: 26px; } a { color: #d8505c; } table { border: 1px solid #999; border-collapse: collapse; width: 800px; margin: 20px auto; text-align: center; } table th { background: skyblue; border: 1px solid #999; padding: 5px; } table td { border: 1px solid #999; padding: 5px; } .add { width: 800px; margin: 20px auto 0 auto; text-align: center; font-size: 0; } .add input { outline: none; border: none; width: 200px; height: 30px; border: 1px solid #ccc; padding-left: 10px; } .add .addInp { border-right: transparent; } .add .search { margin-top: 10px; } .add button { border: none; width: 50px; height: 32px; background: skyblue; color: #FFF; vertical-align: top; } </style> <!-- 引入Vue.js文件 --> <script src="./js/vue.js"></script> <!-- https://cdn.jsdelivr.net/vue.resource/1.2.1/vue-resource.min.js 下載到vue-resource文件 --> <script src="./js/vue-resource.js"></script> </head> <body> <div id="app"> <div class="add"> <h2>產品管理</h2> <!-- v-focus 掛載上自定義指令 --> <input type="text" class="addInp" v-model.trim = "value" placeholder="請輸入產品名稱" @keyup.enter = "add()" v-focus > <!-- 點擊添加按鈕調用add函數添加數據 --> <button @click = "add()">添加</button><br> <!-- 篩選數據列表 --> <input type="text" class="search" placeholder="請輸入篩選內容" v-model = "filterValue" > </div> <table> <thead> <th>編號</th> <th>名稱</th> <th>建立時間</th> <th>操做</th> </thead> <tbody> <!-- 用v-for遍歷arr數組中的每個對象,並把相應數據渲染到頁面上展現 --> <tr v-for = "(item,index) in changeArr"> <td>{{index + 1}}</td> <td>{{item.name}}</td> <td>{{item.ctime | timefmt}}</td> <!-- 點擊刪除調用del函數刪除加數據 注意:須要傳入參數index --> <td><a href="javascript:;" @click = "del(item.id)">刪除</a></td> </tr> </tbody> </table> </div> <script type="text/javascript"> Vue.filter('timefmt',function(value) { value = new Date(value); var year = value.getFullYear(); var month = value.getMonth() + 1; var day = value.getDate(); var hour = value.getHours(); var minute = value.getMinutes(); var second = value.getSeconds(); //二次處理 day = day<10?"0"+day:day; hour = hour<10?"0"+hour:hour; minute = minute<10?"0"+minute:minute; second = second<10?"0"+second:second; return year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second; }); new Vue({ //規定做用域 el:"#app", //放置全部數據 data:{ arr:[ // {name: '寶馬',ctime: new Date}, // {name: '奔馳',ctime: new Date}, // {name: '奧迪',ctime: new Date} ], //用於獲取input中的數據 value:"", filterValue:"" }, created:function(){ this.getData(); }, methods:{ //渲染數據到頁面上 getData:function(){ //肯定url var url = "http://vue.studyit.io/api/getprodlist"; this.$http.get(url).then(function(res){ //提取數據 var data = res.body; //判斷獲取到的數據是否正確 if(data.status != 0){ alert("獲取數據失敗"); return; } //將獲取到的數據放入到data中 this.arr = data.message; },function(err){ console.log(err); }); }, //添加數據 add:function(){ //非空判斷 if(this.value == ""){ alert("輸入內容不能爲空!"); return; } // this指的是Vue實例對象 // 查重複數據 for(var i=0;i<this.arr.length;i++){ //若是數據中的每一項的名稱跟輸入的名稱同樣的時候提醒已添加過, //並及時return掉不在執行後續代碼 if(this.arr[i].name == this.value){ alert('此條數據你已經添加過了!') return; } } // 肯定url var url = "http://vue.studyit.io/api/addproduct"; //post請求 this.$http.post(url,{name:this.value},{emulateJSON:true}).then(function(res){ //先提取數據 var data = res.body; if(data.status == 0){ alert(data.message); // 從新調用獲取數據方法用於刷新數據 this.getData(); }else { alert("數據添加失敗"); } },function(err){ console.log(err); }); this.value = ""; }, // 刪除數據 del:function(id){ //點擊刪除按鈕,從當前索引開始刪除一個(至關於刪除自己) if(confirm('肯定要刪除這條數據嗎?')){ //肯定url var url = "http://vue.studyit.io/api/delproduct/"+id //獲取數據 this.$http.get(url).then(function(res){ //提取數據 var data = res.body; if(data.status == 0){ alert(data.message); this.getData(); }else { alert("數據刪除失敗"); } }) } }, }, //局部 自定義指令 directives:{ "focus":{ inserted:function(el){ el.focus(); } } }, //利用computed屬性來進行邏輯計算 computed:{ //changeArr就是改變後的新數據數組 'changeArr':function(){ //內部獲取不到this var that = this; //返回過濾出來的新數組 return this.arr.filter(function(ele,index){ //根據輸入的字符查找對應索引的內容 !=-1就是能夠查找到 return ele.name.indexOf(that.filterValue) != -1; }) } } }); </script> </body> </html>