Vue


Vue

一、Vue概述

(一)Vue是什么

Vue.js(讀音 /vjuː/, 類似於 view) 是一套構建用戶界面的漸進式框架。Vue 只關注視圖層, 采用自底向上增量開發的設計。
Vue 的目標是通過盡可能簡單的 API 實現響應的數據綁定和組合的視圖組件。
Vue.JS是優秀的前端 JavaScript 框架

image

(二)為什么學習Vue

隨着項目業務場景的復雜,傳統模式(html+jquery)已無法滿足需求,就出現了Angular/React/Vue等框架
企業需求、主流框架之一、易用、靈活、高效

(三)Vue能做什么

最大程度上解放了 DOM 操作
單頁web項目開發
傳統網站開發

什么是工具(庫)、什么是框架

1.庫(插件):是一種封裝好的特定方法集合,對項目的侵入性較小,提供給開發者使用,控制權在使用者手中,如果某個庫無法完成某些需求,可以很容易切換到其它庫實現需求 (jquery)

2.框架:是一套架構,會基於自身特點向用戶提供一套相當完整的解決方案,而且控制權在框架本身;對項目的侵入性較大,使用者要按照框架所規定的某種特定規范進行開發,項目如果需要更換框架,則需要重新架構整個項目

二、Vue核心特征

① 解耦視圖與數據
② M-V-VM模型 關注模型和視圖
M:即Model,模型,包括數據和一些基本操作。
V:即View,視圖,頁面渲染結果
VM:即View-Model,模型和視圖間的雙向操作
③ 雙向數據綁定

(一)MVVM之前

開發人員從后端獲取需要的數據模型,然后要通過DOM操作Model渲染到View中。而后當用戶操作視圖,我們還需要通過DOM獲取View中的數據,然后同步到Model中

(二)MVVM之后

而MVVM中的VM要做的事情就是把DOM操作完全封裝起來,開發人員不用再關心Model和View之間是如何互相影響的:

  • 只要我們Model發生了改變,View上自然就會表現出來。
  • 當用戶修改了View,Model中的數據也會跟着改變
    把開發人員從繁瑣的DOM操作中解放出來,把關注點放在如何操作Model上

image

三、Vue入門

(一)下載安裝

vue是一個前端框架,也是其實是一個js文件,下載vue.js文件並在頁面中引入
vue.js的下載方式:
① 可以引入在線的vue.js(公共的CDN服務)
	<!-- 開發環境版本,包含了用幫助的命令行警告 -->
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	或
	<!-- 生產環境版本,優化了尺寸和速度 -->
	<script src="https://cdn.jsdelivr.net/npm/vue"></script>
② 可以離線下載vue.js
	開發版本: https://vuejs.org/js/vue.js
	生產版本: https://vuejs.org/js/vue.min.js

③ npm包資源管理器,可以下載vue.js  (前端專用)
	初始化:npm init -y
	安裝vue:npm install vue --save
	注:切記重啟計算機

(二)第一個vue

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
     <div id="app">
         <h2>{{name}},歡迎你!</h2>
     </div>
     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
     <script type="text/javascript">
         //生成一個Vue實例
         var app=new Vue({
             el:"#app",//el ,即是element。要渲染的頁面元素
             data:{//數據
                 name:"優就業"
             }
         })
     </script>
</body>
</html>

Vue參數詳解:
	1. body中,設置Vue管理的視圖<div id="app"></div> 
	2. 引入vue.js
	3. 實例化Vue對象 new Vue();
	4. 設置Vue實例的選項:如el、data...
		new Vue({選項:值});
	5. 在<div id='app'></div>中通過{{ }}使用data中的數據

四、Vue常見指令

指令 (Directives) 是帶有 v- 前綴的特殊attribute。是Vue框架提供的語法,擴展了html標簽的功能、大部分的指令的值是js的表達式。用於取代DOM操作

(一)v-textv-html

類似innerText和innerHTML
	① v-text:更新標簽中的內容
	② v-html:更新標簽中的內容/標簽
案例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-text、v-html</title>
    <script src="js/vue.js"></script>
</head>
<body>
    
    <div id="app">
        <!-- 
            插值表達式  {{}}
            v-text  不識別html文本們只能原樣輸出,直接覆蓋原本標簽的內容
            v-html  能識別html文本,直接覆蓋原本標簽的內容
        -->
            <p v-text="a">您好</p>
            <p v-html="b"></p>
            <p v-html="c"></p>
            <p>你好,{{msg}}</p>
    </div>
</body>
<script>

    let app =  new Vue({
        el:"#app",
        data:{
            msg:"helloworld",
            a:'hi',
            b:'hello',
            c:'<h1>嗨</h1>'
        }
    });
</script>
</html>

(二)v-ifv-show

根據表達式的boolean值進行判斷是否渲染該元素
案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="vue.js"></script>
</head>
<body>
    <!-- v-if  v-show 都可以用於顯示或者隱藏元素 
        區別:
            v-if 使用注釋 隱藏元素
            v-show 使用樣式 display:none 隱藏元素
    -->
    <div id="app">
        <p v-if="show">{{name}}</p>
        <p v-show="show">{{name}}</p>
    </div>
</body>

<script>
    let app = new Vue({
        el:"#app",
        data:{
            name:'張三',
            show:true
        }
    })
</script>
</html>

(三)v-on

① 作用:使用 v-on 指令綁定 DOM 事件,並在事件被觸發時執行一些 JavaScript 代碼。
② 語法:
	 v-on:事件名.修飾符 = "methods中的方法名";
	 v-on的簡寫方法: @事件名.修飾符 = "methods中的方法名";
③ 案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-on</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        <p>當前計數: {{count}}</p>
        <!-- <button type="button" v-on:click="jia()">+</button>
        <button type="button" v-on:click="jian()">-</button> -->

        <!-- <button type="button" @click="jia()">+</button>
        <button type="button" @click="jian()">-</button> -->


        <button type="button" @click="count++">+</button>
        <button type="button" @click="count--">-</button>
    </div>
</body>

<script>

    let app =  new Vue({
       el:"#app",
       data:{
            count:0
       },
       methods:{
            jia(){
                this.count++;
            },
            jian(){
                this.count--;
            }
       }
    });
</script>
</html>

v-on綁定事件案例:

image

練習-顯示隱藏

內容顯示時,按鈕是隱藏功能。隱藏內容后,按鈕是顯示功能,顯示、隱藏共用一個按鈕.

image

image

代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-on</title>
    <script src="vue.js"></script>
</head>
<body>
        <div id="app">
                <p v-show="condition">你能看見我嗎</p>
                <button @click="change()">{{btn}}</button>
        </div>

        
</body>
<script>
    let app = new Vue({
        el:"#app",
        data:{
            btn:'隱藏',
            condition:true
        },
        methods:{
            change(){
               this.btn =  this.btn=="隱藏" ?"顯示":"隱藏";
               this.condition = this.btn=="隱藏"?true:false;
            }
        }
        
    })
</script>
</html>

(四)v-for

① 作用:列表渲染,當遇到相似的標簽結構時,就用v-for去渲染
② 格式:
	    (item,index) in 數組或集合 
	 	參數item:數組中的每個元素 
	 	參數index:數組中元素的下標

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-for</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        <!-- 
            遍歷固定次數、固定內容
            <p v-for="(item, index) in 100">好好學習,天天向上</p>
         -->


         <!-- 遍歷數組-->
         <p v-for="(stu, index) in stuArr">{{index}}--{{stu.name}}--{{stu.age}}</p>
    </div>
</body>

<script>

    let app =  new Vue({
       el:"#app",
        data:{
            stuArr:[
                {
                    id:1,
                    name:'張三',
                    age:20
                },
                {
                    id:2,
                    name:'李四',
                    age:22
                },
                {
                    id:3,
                    name:'王五',
                    age:25
                }
            ]
        }
    });
</script>
</html>

(五)v-bind

① 作用: 可以綁定標簽上的任何屬性
② 格式:v-bind:屬性="值"
③ 簡寫格式::屬性="值"
④ 屬性值一部分進行替換的格式::屬性="'常量值' + vue對象data中的數據"
⑤ 案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-bind</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app">
        <!-- 如果直接寫屬性名 , 不認識vue中定義的變量 -->
       <a href="addr">京東</a>

       <!-- 通過v-bind綁定的屬性,能識別vue中定義的變量、方法-->
       <a v-bind:href="addr">百度</a>

       <a :href="addr2">中公</a>

       <a :href="'http://'+addr3">淘寶</a>
    </div>
</body>

<script>

    let app =  new Vue({
       el:"#app",
       data:{
            addr:"http://www.baidu.com",
            addr2:"http://www.offcn.com",
            addr3:"www.taobao.com"
       }
    });
</script>
</html>

練習-點擊換樣式

藍色

color:blue;

border:1px solid blue;

box-shadow:0px 0px 3px black;

紅色

color:red;

border:1px solid red;

box-shadow:0px 0px 3px black;

image

image-20210721201241401


(六)v-model

① 作用:表單元素的綁定
② 特點:雙向數據綁定
	(1)vue對象中的數據發生變化可以更新到界面
	(2)通過界面可以更改vue對象中數據
	(3)v-model 會忽略所有表單元素的 value、 checked 、 selected 特性的初始值而總是將 Vue 實 例的數據作為數據來源。應該在data選項中聲明初始值。
③ 案例:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-model</title>
    <script src="vue.js"></script>
</head>
<body>
    <div id="app">
        
            請輸入您的個人信息:
            姓名:<input type="text" v-model="name"  /> 年齡: <input type="text"  v-model="age">  

            <hr>
            請核對您的個人信息 <br>
            姓名: {{name}}  <br>
            年齡: {{age}}
    </div>
      
</body>
<script>
    let app = new Vue({
        el:"#app",
        data:{
            name:'張三',
            age:20
        }
    })
</script>
</html>

(七)計算屬性

計算屬性可以時刻關注在vue中定義的關聯的變量。  當這些關聯的變量值發生變化,計算屬性也會發生變化.

代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>計算屬性</title>
    <script src="js/vue.js"></script>
</head>
<body>
    
    <div id="app">
        <input type="text" v-model="num1" /> +  <input type="text" v-model="num2" /> 

        <p>
            <span>{{num1}}</span>   +    <span>{{num2}}</span>  = <span>{{sum}}</span>
           
        </p>

        <p>
            <span>{{num1}}</span>   *    <span>{{num2}}</span>  = <span>{{cheng}}</span>
        </p>
    </div>

</body>
<script>

    const app = new Vue({
        el:'#app',
        data:{
            num1:0,
            num2:0
        },
        computed:{
            sum(){
               return this.num1*1 + this.num2*1;  
            },
            cheng(){
                return this.num1 * this.num2;
            }
        }
    });
</script>
</html>

image-20210406114151765

案例說明:

1.修改數量、移除書籍后,總價會發生變化

2.當一本書籍都沒有了,提示購物車為空,表格消失

image-20210723114412260

代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>作業</title>

    <script src="vue.js"></script>
</head>
<body>
    
    <div id="app">
        <table v-show="items.length>0"  width="700" style="text-align: center;" border="1" cellspacing="0" cellpadding="0">
            <tr>
                <th></th>
                <th>書籍名稱</th>
                <th>出版日期</th>
                <th>價格</th>
                <th>購買數量</th>
                <th>操作</th>
            </tr>

            <tr v-for="(item, index) in items">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td>{{item.date}}</td>
                <td>¥{{item.price}}</td>
                <td><button v-on:click="--item.count">-</button>{{item.count}}<button @click="++item.count">+</button></td>
                <td><button @click="items.splice(index,1)">移除</button></td>
            </tr>

        </table>
        
        <p v-show="items.length>0">總價:¥{{sum}}</p>

        <p v-show="items.length==0">購物車為空</p>
    </div>
</body>

<script>
    let app = new Vue({
        el:'#app',
        data:{
            items:[
                {id:1,name:'<<算法導論>>',date:'2006-9',price:85,count:1},
                {id:2,name:'<<UNIX編程藝術>>',date:'20016-2',price:59,count:1},
                {id:3,name:'<<編程珠璣>>',date:'2003-1',price:39,count:1},
                {id:4,name:'<<代碼大全>>',date:'2012-7',price:128,count:1}
            ]
        },
        methods: {
            jian(book){
                if(book.count>1)
                    book.count--;
            },
            jia(book){
                book.count++;
            },
            remove(index){
                this.items.splice(index,1);
            }
        },
        computed:{
            sum(){
                let sum = 0;
                for(let i = 0 ; i < this.items.length;i++){
                   let book =  this.items[i];
                   sum+=book.price * book.count;
                }
                return sum;
            }
        }
    });
</script>

</html>

五、Vue的生命周期

	每個 Vue 實例在被創建時都要經過一系列的初始化過程 :創建實例,裝載模板,渲染模板等等。Vue為生命周期中的每個狀態都設置了鈎子函數(監聽函數)。每當Vue實例處於不同的生命周期時,對應的函數就會被觸發調用。

image

image

鈎子函數:
如:created代表在vue實例創建后;我們可以在Vue中定義一個created函數,代表這個時期的構造函數:

六、組件

(一)定義全局組件

我們通過Vue的component方法來定義一個全局組件。
Vue.component(組件名,{組件參數})
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
 <script src="js/vue.js"></script>


</head>
<body>
 <div id="app">
    <con></con>
    <con></con>
 </div>
</body>
<script>

 let con = Vue.component("con",{
     template:`<div><p>次數{{count}}</p>
     <button type="button" @click="--count">-</button>
     <button type="button" @click="++count">+</button></div>`,
     data(){
        return {
             count:0
        }
     }

 });
 let app = new Vue({
     el:'#app'

 })
</script>
</html>

特點:
- 組件其實也是一個Vue實例,因此它在定義時也會接收:data、methods、生命周期函數等
- 不同的是組件不會與頁面的元素綁定,否則就無法復用了,因此沒有el屬性。
- 但是組件渲染需要html模板,所以增加了template屬性,值就是HTML模板
- 全局組件定義完畢,任何vue實例都可以直接在HTML中通過組件名稱來使用組件了。
- data的定義方式比較特殊,必須是一個函數。

注:
	定義組件要在Vue對象之前聲明
	模板template中只能有一個root(根)

(二)定義局部組件

	一旦全局注冊,就意味着即便以后你不再使用這個組件,它依然會隨着Vue的加載而加載。因此,對於一些並不頻繁使用的組件,我們會采用局部注冊。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="js/vue.js"></script>


</head>

<body>
    <div id="app">
        
    </div>

    <div id="app1">
        <con></con>
        <con></con>
    </div>
</body>
<script>


let con =  {
                template: `<div><p>次數{{count}}</p>
        <button type="button" @click="--count">-</button>
        <button type="button" @click="++count">+</button></div>`,
                data() {
                    return {
                        count: 0
                    }
                }
            }

    let app = new Vue({
        el: '#app'

    })

    

    let app1 = new Vue({
        el: '#app1',
        components: {
            con: con
        }
    })
</script>

</html>
- components就是當前vue對象組件集合。
  - 其key就是子組件名稱
  - 其值就是組件對象的屬性
- 效果與剛才的全局注冊是類似的,不同的是,這個conn組件只能在當前的Vue實例中使用

注:定義組件要在Vue對象之前聲明

七、Vue的Ajax(axios)

在Vue.js中發送網絡請求本質還是ajax,我們可以使用插件方便操作。

(一)安裝

下載axios.js
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
用離線版的axios.js

(二)axios請求

GET請求



axios.get('/user?id=12345')
 .then(response => {
     console.log(response.data);
 });

axios.get('/user?id=12345').then(function(response){
    
})


POST請求

axios.post('/user', "name=迪麗熱巴&age=23") .then(response => {
        console.log(response.data);
    });

(三)跨域問題

什么是跨域?
指的是瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對javascript施加的安全限制。
什么是同源策略?
是指協議,域名,端口都要相同,其中有一個不同都會產生跨域,在請求數據時,瀏覽器會在控制台中報一個異常,提示拒絕訪問。
跨域問題怎么出現的?
開發一些前后端分離的項目,比如使用 Servlet + Vue 開發時,后台代碼在一台服務器上啟動,前台代碼在另外一台電腦上啟動,此時就會出現問題。
  比如:

    后台 地址為 http://192.168.70.77:8081
    前台 地址為 http://192.168.70.88:8080
  此時 ip 與 端口號不一致, 不符合同源策略,造成跨域問題。

image

處理思路

使用CORS,全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
值得注意的是,目前主流瀏覽器都支持cors,會自動發出cors請求。在簡單請求下,cors請求和同源請求的區別主要是瀏覽器的請求頭信息中會多了一個origin字段。 這個字段表示本次請求來自哪個源(協議 + 域名 + 端口)。服務器根據這個值,決定是否同意這個請求。

因此在后續解決方案中,主要是服務器需要處理orgin這個請求頭字段,同意跨域請求。

如何解決:
	后台解決(自定義過濾器)

    
package com.offcn.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter("/*")
public class CorsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        // 不使用*,自動適配跨域域名,避免攜帶Cookie時失效
        String origin = request.getHeader("Origin");
        response.setHeader("Access-Control-Allow-Origin", origin);

        // 自適應所有自定義頭
        String headers = request.getHeader("Access-Control-Request-Headers");
        response.setHeader("Access-Control-Allow-Headers", headers);
        response.setHeader("Access-Control-Expose-Headers", headers);

        // 允許跨域的請求方法類型
        response.setHeader("Access-Control-Allow-Methods", "*");
        // 預檢命令(OPTIONS)緩存時間,單位:秒
        response.setHeader("Access-Control-Max-Age", "3600");
        // 明確許可客戶端發送Cookie,不允許刪除字段即可
        response.setHeader("Access-Control-Allow-Credentials", "true");

        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM