Java學習筆記-全棧-web開發-24-Vue


1. 開發環境 VSCode

插件安裝

  • Chinese Language
  • ESlint :嚴格語法工具
  • Live Server :vue的雙向數據綁定,如果只是靜態的html文件無法看到效果,開啓服務器插件
  • open in browser :右鍵通過瀏覽器查看
  • Vetur:Vue的代碼提示、高亮

前端代碼太多縮進,建議這裏設置成2個空格。
在這裏插入圖片描述
跨平臺方案(一次代碼,多平臺使用):
Vue->Weex->uniapp

2. vue介紹

2.1 vue與原生js(或jquery)的優勢

jq利用DOM操作,降低了ajax請求函數的複用性(js與html耦合性太高)。
而vue通過框架提供的指令實現數據雙向綁定,我們只需要關注業務邏輯,而不需要直接操作DOM元素。

2.2 MVVM

MVVM是前端視圖層的分層,(僅相當於MVC中的V);
將視圖層分爲:Model,View,ViewModel

如果將MVC和MVVM結合,如下圖(MVC中的M和V與MVVM中的MV不是一個東西)
在這裏插入圖片描述

model 是數據, data
view 是模板
vm 是 vm = new Vue();
vm 用了連接數據和視圖, 視圖的輸入框綁定了v-model, 用戶輸入後會改變data;
model改變也會同步視圖更新相關的依賴, 雙向綁定就是vm起了作用

Vue與後端模板引擎的區別就在於:
後端模板引擎從後端控制器的Model中獲取數據,然後通過形如th:text="${}"的指令將數據渲染到html中。
Vue從JavaScript中獲取數據,然後通過形如v-text="msg"的指令將數據綁定到html中。

3. 常用指令

{{}} v-text v-html

{{}}只替換佔位符,v-text會替換標籤中的內容。{{}}中可以寫js代碼
v-html的v-text的區別就在於v-html會解析html代碼;

如果網速比較慢,{{}}替換之前會一閃而過。解決辦法如下
<style>
[v-clock]{
	display:none;
}
</style>

title屬性 v-bind v-on

設置title屬性的標籤,鼠標放上去後會浮出title。

v-bind用於與js中的vue實例中的data中的數據進行綁定(綁定的對象不能是普通字符串),可以縮寫爲冒號:

v-bind可以綁定爲任意原有html屬性值,如src、style等等

<a :href="url"></a>
<a :class="flag?'red':'blue'"></a>

也用於使行內可以使用js代碼(參考vue中的css)

v-on用於與與js中的vue實例中的methods中的方法進行綁定,可以縮寫爲@

數據雙向綁定 v-model

<body>
	<div>
	<h1>{{msg}}</h1>
	<input type="text" v-model="msg">
	</div>
</body>

<script>
	var vue = new Vue({
		el:'#app',//綁定目標
		data:{
			msg:'我是msg'
		}
	})
</script>

當我們在input中輸入數據的時候,h1內的數據也會改變。
最重要的是,其實vue實例中的msg也被修改了

v-model實現了表單元素和model中數據的雙向綁定
但是v-model只能用於表單元素,如果將其使用到其他標籤上,則v-model就是自定義指令了==

v-bind只能實現單向綁定,model中的(vue實例中的數據)數據被更改時,v-bind綁定位置也會實時修改,但是v-bind綁定的位置發生變化時,model中的數據不會發生變化
即:v-model可實現html修改js數據,v-bind只能實現js修改html數據。


v-model.number能夠限制數據爲number
v-model.trim能夠去除前後空格
v-model.lazy懶加載,對於輸入框只有按回車或者onblur(失去焦點)纔會同步更新

雙向綁定小案例-計算器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <input type="text" v-model="number1">
    <select v-model="opt">
      <option value="+">+</option>
      <option value="-">-</option>
      <option value="x">x</option>
      <option value="÷">÷</option>
    </select>
    <input type="text" v-model="number2">
    <button @click="handel">=</button> <!--如果無參,方法可以不加括號-->
    <input type="text" v-model="result">


  </div>
  
</body>
<script src="js/vue.js"></script>
<script>
  var vue = new Vue({
    el:'#app',
    data:{
      number1:0,
      number2:0,
      result:0,
      opt:'+',
    },
    methods:{
      handel(){
        if(this.opt=="+"){
          this.result=parseInt(this.number1)+parseInt(this.number2);
        }else if (this.opt="-") {
          this.result=parseInt(this.number1)-parseInt(this.number2);
        }else if (this.opt="x") {
          this.result=parseInt(this.number1)*parseInt(this.number2);
        }else if (this.opt="÷") {
          this.result=parseInt(this.number1)/parseInt(this.number2);
      }
      }
    }
  })

</script>
</html>

Vue中常用的css

red,big,size是通過類名定義好的style
flag是vue實例中的data字段

<div class="red">傳統用法</div>
<div :class="['red','big']">通過bind使引號中可以寫js代碼</div>
<div :class="flag?'size':'big'">通過bind使引號中可以寫js代碼使用三元運算符</div>
<div :class="'size'=true">命名默認爲Bool值,設爲true則生效</div>
<div :class="myStyle">通過bind使引號中可以寫js代碼使用三元運算符</div>

<script>
	var vue=new Vue({
		data:{
			myStyle:{'red':true,'size':true,'big':true}
		}
		
	})
</script>

v-for

simpleList是vue實例中的data中的一個數組。

<p v-for="{item,index} in simpleList">
索引:{{index}}
數據:{{item}}
</p>

index可要可不要
simplelist裏面可以是鍵值對等其他複雜類型,然後通過.運算符訪問其內的數據即可。

如下圖:
在這裏插入圖片描述

<p v-for="(obj,i) in objectList">
{{obj.id}}
{{obj.name}}
</p>

數字range

<p v-for="i in 10"></p>

會生成從1到10(而不是從0到9)

注意
建議給每個v-for都加上:key,且key不綁定默認生成的index
因爲:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <input type="text" v-model="id">
    <input type="text" v-model="name">

    <p v-for="(obj,i) in objectList">
      <input type="checkbox"> id:{{obj.id}}----name:{{obj.name}}
    </p>
    <button @click='handel'>添加</button>
  </div>
  
</body>
<script src="js/vue.js"></script>
<script>
  var vue = new Vue({
    el:'#app',
    data:{
      id:'',
      name:'',
      objectList:[
        {id:1,name:'張三'},
        {id:2,name:'張四'},
        {id:3,name:'張五'},
        {id:4,name:'張六'},
      ]
        
    },
    methods:{
      handel(){
        var obj={id:this.id,name:this.name}
        this.objectList.unshift(obj);
      }
    }
  })

</script>
</html>

如果先選中任意一個,比如張三,當你通過unshift添加一個新的到前面時,選中框會滑到張四(向下滑落)
綁定key就不會出現這個問題。如果綁定的key是自帶的index,也會出現這個問題


v-for="(item,i)in objList"會報錯,因爲in前面沒有空格

v-if v-show

v-if和v-show控制標籤顯示時,v-if會將渲染頁面的標籤直接進行刪除/添加操作,而v-show是更改標籤的display屬性。

v-show一定會渲染,v-if則不一定,因此,如果用戶可能根本就看不到這個,則用v-if。

v-if後可以用v-else和v-else-if,用法類似

自定義指令

new Vue({
	el:
	data:
	directives:{ //自定義指令
		change:{ //指令名稱
			bind:function(){},  //指令綁定到元素
			update:function(){},  //更新時回調
			unbind:function(){},  //解除時回調
		}
	}
})

4. 表格綜合增刪應用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    id<input type="text" v-model="id">
    name<input type="text"v-model="name">
    sex<input type="text" v-model="sex">
    <button @click="add">添加</button>
    <table v-for="(obj,index) in objectList" :key="obj.id">
        <tr>
            <td>ID</td>
            <td>name</td>
            <td>sex</td>
            <td>操作</td>
          </tr>
      <tr>
        <td>{{obj.id}}</td>
        <td>{{obj.name}}</td>
        <td>{{obj.sex=='1'?'男':'女'}}</td>
        <td><button type="button" @click="deleteUser(obj.id)">刪除</button></td>
      </tr>    
    </table>

  </div>
  
</body>
<script src="js/vue.js"></script>
<script>
  var vue = new Vue({
    el:'#app',
    data:{
      id:'',
      name:'',
      sex:'',
      objectList:[
        {id:1,name:'張三',sex:'1'},
        {id:2,name:'張四',sex:'1'},
        {id:3,name:'張五',sex:'0'},
        {id:4,name:'張六',sex:'0'},
      ]
        
    },
    methods:{
      add(){
        var obj={id:this.id,name:this.name,sex:this.sex}
        this.objectList.push(obj);
      },
      deleteUser(objId){
        let index = this.objectList.findIndex(item => {
          if(item.id===objId){
            return true;
          }
        });
        this.objectList.splice(index,1) //從index位置刪除一個元素
      },
    }
  })

</script>
</html>

5. vue過濾器

就像是:將參數傳入一個filter管道(函數),出來管道的返回值。


<td>{{obj.sex | myfilter}}</td>

<script>
var vue = new Vue({
	filters:{
		myfilter(sex){
			if(sex=='1'){
				return '男';
			}else{
				return 'nv';
			}
		}
	}
})

</script>

6. vue生命週期

在這裏插入圖片描述幾個重要點:
created:methods和data的最早使用函數
beforeMount:尚未掛載(渲染)模板
mounted:操作DOM的最早時刻(此時模板已經渲染了,由於Vue實際不用操作DOM,因此此時是進行頁面渲染之後的操作)
剩下的方法圖中已經說明的很清楚了;

注意,並沒有“正在”這個時間段,只有before=>之前,-ed=>之後。

7. vue組件(核心)

模塊化:從代碼角度分析的,方便代碼分層開發,保證每個模塊功能單一
組件化:從UI角度分析的,如分頁組件、輪播圖組件。

7.1 extend創建組件

注意,script中使用駝峯命名,在html中必須改成小寫,且用 - 連接

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>extend創建組件</title>
</head>
<body>
  <div id="app">
    <!-- 注意,script中使用駝峯命名,在html中必須改成小寫,且用 - 連接 -->
    <my-component></my-component>
  </div>
  
</body>
<script src="js/vue.js"></script>
<script>

  //創建
  var myComponent = Vue.extend({
    template:'<h1>這是用extend創建的組件</h3>'
  });
  //聲明
  Vue.component('myComponent',myComponent);


  var vue = new Vue({
    el:'#app',
    data:{
        
    },
  })

</script>
</html>

聲明和創建可以合併

  Vue.component('myComponent',Vue.extend({
    template:'<h1>這是用extend創建的組件</h3>'
  }));

extend也可以省略

  Vue.component('myComponent',{
    template:'<h1>這是用extend創建的組件</h3>'
  });

7.2 使用template創建組件(重點)

  1. 創建vue實例,綁定一個el標籤
  2. 創建template標籤,給template一個id(注意不是給template中的根節點給id)
  3. 聲明Vue.component,綁定template的ID
  4. 在vue實例綁定的el中使用template
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>template</title>
</head>
<body>
  <div id="app">
    <my-Component></my-Component>
  </div>
  
  <template id="mytemp">
    <div>
      <p>hhh</p>
      <h1>big head</h1>
    </div>
  </template>

</body>
<script src="js/vue.js"></script>
<script>

  Vue.component('myComponent',{
    template:`#mytemp`
  })


  var vue = new Vue({
    el:'#app',
    data:{
        
    },
  })

</script>
</html>

組件本身也是一個對象,因此可以直接創建組件對象

var login={
	template:'<p>組件對象</p>'
}

7.3 組件中的data和methods

首先是data,注意,組件的存在是爲了提高複用性,而data:{}的寫法,會導致多個組件共用一個data,提高了耦合性。因此,組件中的data,必須是一個函數,並且返回一個對象
例子:爲什麼data必須是函數

Vue.component('mycomponent',{
	template:'#temp1',
	template:'#temp2',
	data(){
		return {
		msg:0
		}
	}
})

如果使用這個,則temp1和temp2都共用

組件中的methods跟vue實例中的相同。

7.4 私有組件

將組件定義在vue實例中,則只有與vue實例綁定的el才能使用該組件

<div id="d1">
<!--這個生效-->
<my-comp></my-comp>
</div>
<!--這個不會生效-->
<div id="d2">
<my-comp></my-comp>
</div>

<template id="temp">私有temp</template>

<script>

var vue = new Vue({
	el:'#d1',
	components:{
		'myComp':{
			template:'#temp'
		}
	}

})
</script>

注意自定義component標籤的名字需要用引號

7.5 組件切換

利用v-if切換(兩三個組件間的切換)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <button @click="flag=true">登錄</button>
    <button @click="flag=false">註冊</button>
    <login v-if="flag"></login>
    <register v-else></register>
  </div>
  
  <template id="login">
    <div>登錄組件
    </div>
  </template>

  
  <template id="register">
      <div>註冊組件
      </div>
    </template>
</body>
<script src="js/vue.js"></script>
<script>

  Vue.component('login',{
    template:`#login`
  })

  
  Vue.component('register',{
    template:`#register`
  })

  var vue = new Vue({
    el:'#app',
    data:{
        flag:true,
    },
  })

</script>
</html>

更一般的切換方式(重要)

利用佔位符component標籤綁定component的名字,然後通過點擊更改component名字屬性實現組件切換。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <button @click="componentName='login'">登錄</button>
    <button @click="componentName='register'">註冊</button>
    
    <!-- 這個component只是佔位符,通過:is綁定真正的component -->
    <component :is="componentName"></component>
  </div>
  
  <template id="login">
    <div>登錄組件
    </div>
  </template>

  
  <template id="register">
      <div>註冊組件
      </div>
    </template>
</body>
<script src="js/vue.js"></script>
<script>

  Vue.component('login',{
    template:`#login`
  })

  
  Vue.component('register',{
    template:`#register`
  })

  var vue = new Vue({
    el:'#app',
    data:{
        componentName:'login'
    },
  })

</script>
</html>

7.6 組件間的數據傳遞

父組件向子組件傳遞屬性

vue實例是一個父組件,先看vue實例中的數據如何傳遞給vue實例中的私有組件(即子組件)。
子組件中有一個專門用於訪問父組件屬性的一個對象:props

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <my-component :parent-msg="msg"></my-component>
  </div>

  <template id="temp">
    <div>
      <p>{{msg}}</p>
      <!-- 這個不會顯示 -->
      <p>{{parentMsg}}</p>
    </div>
  </template>

</body>
<script src="js/vue.js"></script>
<script>

  var vue = new Vue({
    el:'#app',
    data:{
      msg:'我是父組件中的數據'
    },
    components:{
      'my-component':{
        template:'#temp',
        data(){
          return {
            msg:'我是子組件中的數據'
          }
        },
        props:{
          'parent-msg':{
              type:String,
              default:null
          }
        }
      }
    }
  })

</script>
</html>

關鍵邏輯:

  • 在私有組件(子組件)的props中聲明要使用一個屬性名parent-msg
  • 在子組件html代碼中使用該屬性名{{parentMsg}} 雙花括號中改成駝峯
  • 在組件調用的地方進行數據綁定:將parentMsg綁定到父組件屬性msg中 ----> :parent-msg=“msg”

props可以定義爲數組props:[‘parentMsg’],當它定義爲對象時,是標準寫法。

注意凡是標籤內的駝峯式都改成-連接,凡是{{}}中的都改成駝峯

props中的數據是隻讀的,不要用子組件去更改父組件中的數據

父組件向子組件傳遞方法

根據父組件向子組件傳遞屬性的做法,與傳遞屬性有點不太一樣,這個比較繞

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <p>{{msg}}</p>
    <my-component @parent-change="changeMsg"></my-component>
  </div>

  <template id="temp">
    <div>
      <button @click="there_is_son_method">修改</button>
    </div>
  </template>

</body>
<script src="js/vue.js"></script>
<script>

  var vue = new Vue({
    el:'#app',
    data:{
      msg:'我是父組件中的數據'
    },
    methods:{
      changeMsg(){
        this.msg="被修改了"
      }
    },
    components:{
      'my-component':{
        template:'#temp',
        methods:{
          there_is_son_method(){
            this.$emit('parent-change')
          }
        }
      }
    }
  })

</script>
</html>

關鍵步驟

  • 子組件中聲明一個方法there_is_son_method
  • 子組件html代碼中調用這個方法
  • 這個方法體中使用$emit聲明使用父組件中的方法,假定命名爲parent-change(這個並沒有直接引用到父組件方法中,可以理解爲:vue假定父組件對子組件是不可見的,因此此處不能直接引用父組件)
  • 在組件被調用處,將parent-change與父組件中的方法綁定起來

(個人理解)父子組件間的數據傳遞,都是通過子組件聲明父組件屬性/方法,然後在html代碼中實現父子屬性/方法的綁定

$emit

$emit表示聲明使用父組件的方法,第一個參數是假定的父組件名稱,後面的都是參數

父組件調用子組件的方法

首先學習ref


下面這個是js的寫法,操作dom元素

<div id="div1"></div>
<script>
let data = document.getElementById("div1").innerText;
</script>

下面是vue操作dom元素的方法

<div ref="div1"></div>
<script>
let data = this.$refs.div1.innerText
</script>

可以讓父組件通過ref找到子組件,然後調用子組件的方法

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <button @click="parentFunc">父組件調用子組件</button>
    <my-component ref="refname"></my-component>
  </div>

  <template id="temp">
  </template>

</body>
<script src="js/vue.js"></script>
<script>

  var vue = new Vue({
    el:'#app',
    methods:{
      parentFunc(){
        console.log("父組件方法")
        this.$refs.refname.childFunc()
      }
    },
    components:{
      'my-component':{
        template:'#temp',
        methods:{
          childFunc(){
            console.log("子組件被調用")
          }
        }
      }
    }
  })

</script>
</html>

關鍵步驟:

  • 子組件被調用的地方加上ref屬性(即自定義標籤名處,而不是聲明子組件的template上)
  • 父組件中通過$refs找到該ref的dom元素,然後調用子組件方法

7.7 注意點

  • 組件只有一個屬性值,但是屬性值中可以寫任意html代碼,而且,必須只能有一個根節點(最外層必須要有一個標籤包裹着)
  • 用``包裹組件屬性值,其內如果用到變量,則用${變量名}模板語法。
  • 駝峯與短橫線
    • {{}}不能用-,只能用駝峯法
    • 標籤命名只能用-連接,不能用駝峯法
    • :子組件引用名=“父組件實際名”,子組件引用名只能用-連接,不能用駝峯法
    • vue認爲駝峯寫法和短橫寫法是同一個對象

7.8 小結

在這裏插入圖片描述

8. 路由

需要使用vue-router包,當導入這個包之後,window全局就有了VueRouter這個構造函數。

什麼是路由
後端:對於普通的網站,所有超鏈接都對應一個url,指向服務器資源
前端:對於單頁面應用,主要通過url的#(hash)來實現不同頁面的切換,通過hash實現的(相當於a標籤)

每個路由是一個對象(用{}定義),每個對象都包含兩個屬性:path:表示路由的url,component:表示路由的跳轉目標組件

8.1 初試路由

步驟:

  • 創建路由對象
  • 將路由對象聲明到vue實例中
  • 創建組件
  • html中使用router-view給組件佔位
  • html中使用router-link實現組件切換
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">

    <!-- 定製調用路由 -->
    <router-link to="/login" tag="button">登錄</router-link>
    <router-link to="/register">註冊</router-link>
    <!-- 這是一個佔位符,改變路由的時候,會顯示指定組件 -->
    <router-view></router-view>
  </div>

  <template id="login"><div>登錄組件</div></template>
  <template id="register"><div>註冊組件</div></template>

</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>
  var login = {
    template:'#login'
  }

  var register = {
    template:'#register'
  }

  let routerObj = new VueRouter({
    routes:[
      {path:'/',redirect:'/login'},//這個不是重定向請求,僅僅是重定向組件
      {path:'/login',component:login},
      {path:'/register',component:register},
    ]
  })

  var vue = new Vue({
    el:'#app',
    router:routerObj
  })

</script>
</html>

8.2 路由傳參(重點)

前後端未分離時:

  • 頁面A被點擊,傳遞id到後端控制器,後端查出數據,轉發給頁面B,頁面B渲染數據

前後端分離(Vue):

  • 頁面A被點擊,傳遞id給頁面B,頁面B在created時期根據id將數據查出,頁面B渲染數據。

方法一:使用路由時/login?name=zs&psw=123的形式傳參,然後$route.query.name獲取
方法二:定義路由時設置 /register/:name/:psw ,使用router-link時/register/ls/123,然後$route.params.name獲取

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">

    <!-- 定製調用路由 -->
    <router-link to="/login?name=zs&psw=123" tag="button">登錄</router-link>
    <router-link to="/register/ls/123">註冊</router-link>
    <!-- 這是一個佔位符,改變路由的時候,會顯示指定組件 -->
    <router-view></router-view>
  </div>

  <template id="login"><div>登錄組件
    <P>{{$route.query.name}}</P>
    <P>{{$route.query.psw}}</P>
  </div></template>
  <template id="register"><div>註冊組件
    <p>{{$route.params.name}}</p>
    <p>{{$route.params.psw}}</p>
  </div></template>

</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>
  var login = {
    template:'#login'
  }

  var register = {
    template:'#register'
  }

  let routerObj = new VueRouter({
    routes:[
      {path:'/',redirect:'/login'},//這個不是重定向請求,僅僅是重定向組件
      {path:'/login',component:login},
      {path:'/register/:name/:psw',component:register},
    ]
  })

  var vue = new Vue({
    el:'#app',
    router:routerObj
  })

</script>
</html>

8.3 路由的嵌套

routers裏面使用children再聲明路由,就是路由嵌套。
children與path同級

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <router-view></router-view>
  </div>

  <template id="index">
    <div>
      <h1>首頁</h1>
      <router-link to="index/login" tag="button">點擊登錄</router-link>
      <router-view></router-view>
    </div>
  </template>

  <template id="login">
    <div>
      <p>登錄組件</p>
      <!-- 使用子路由的時候,必需且僅需加上上一級父路由 -->
      <router-link to="login/success" tag="button">提交登錄</router-link>
      <router-view></router-view>
    </div>
  </template>

  <template id="success">
    <div>
      <p>登錄成功</p>
    </div>
  </template>

</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>
  var login = {
    template:'#login'
  }

  var success = {
    template:'#success'
  }

  var index = {
    template:'#index'
  }

  let routerObj = new VueRouter({
    routes:[
      {path:'/',redirect:'/index'},//這個不是重定向請求,僅僅是重定向組件
      {path:'/index',component:index,
        children:[{
          // 斜槓/表示從根路徑匹配,而子路由不能加/,而且實際上會默認給子路由加上父路由
          path:'login',component:login,
          children:[{
            path:'success',component:success
          }]
        }]
      }]

  })

  var vue = new Vue({
    el:'#app',
    router:routerObj
  })

</script>
</html>

注意問題:

  • children必須是數組(內部實現使用了 for:each遍歷)
  • 使用子路由的時候,必需且僅需加上上一級父路由(如上述例子index->login->success,而success只的router-link只需要寫“login/success”而不需要寫成“index/login/success”)
  • 嵌套路由的跳轉,頁面會同時顯示父路由綁定的template(因爲組件中必須帶上template佔位)

8.4 router和route

router是VueRouter的實例,是全局對象,包含了所有路由的一些關鍵對象和屬性;
route是一個特定路由對象,是局部對象,比如監聽器監控路由的時候就是用route,表示監控當前跳轉的路由。

8.5 編程式路由(重點)

也就是:通過js實現路由跳轉

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    用戶名<input type="text" v-model="name"><br>
    密碼<input type="password" v-model="psw"><br>
    <button @click="toGetLogin">get登錄</button>
    
    <br>
    用戶名<input type="text" v-model="name"><br>
    密碼<input type="password" v-model="psw"><br>
    <button @click="toPostLogin">Post登錄</button>

    <!-- 凡是路由跳轉,都得給佔位 -->
    <router-view></router-view>
  </div>

  <template id="login"><div>
    <p>登錄成功</p><br>
    <P>歡迎使用path+query方式:{{$route.query.name}}</P>
    <P>歡迎使用name+params方式:{{$route.params.name}}</P>
  </div></template>

</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>
  var login = {
    template:'#login'
  }

  let routerObj = new VueRouter({
    routes:[
      {path:'/',redirect:'/login'},//這個不是重定向請求,僅僅是重定向組件
      {name:'login',path:'/login',component:login},
    ]
  })

  var vue = new Vue({
    el:'#app',
    data:{
      name:'張三',
      psw:'123456'
    },
    methods:{
      toGetLogin(){
        this.$router.push({
          path:'/login',
          query:{
            name:this.name,
            psw:this.psw
          }
        })
      },
      toPostLogin(){
        this.$router.push({
          name:'login',
          params:{
            name:this.name,
            psw:this.psw
          }
        })
      }
    },
    router:routerObj
  })

</script>
</html>

知識點:

  • query傳參,方法中只需要path,瀏覽器的url中可以看到?&的參數
  • params傳參,方法必須使用name,瀏覽器中的url看不見參數
  • params不能和path同時使用

9. 名稱拼接數據綁定

假設有對象:firstname、lastname、fullname,如何實現:當firstname和lastname改變時,同步改變fullname?

data中不能直接實現fullname:firstname+lastname

9.1 監聽器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div>firstname: {{firstname}}</div>
    <div>lastname: {{lastname}}</div>
    <div>fullname: {{fullname}}</div>
    <input type="text" v-model="firstname">
    <br>
    <input type="text" v-model="lastname">
    <br>
    <input type="text" v-model="fullname">
  </div>

</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>


  var vue = new Vue({
    el:'#app',
    data:{
      firstname:'',
      lastname:'',
      fullname:'',
    },
    watch:{
      firstname(newVal,oldVal){  //監聽器默認參數,第一個表示監聽對象的新值,第二個爲舊值
        this.fullname = newVal+this.lastname
      },
      lastname(newVal,oldVal){
        this.fullname = this.firstname+newVal
      }
    }
  })

</script>
</html>

凡是’firstname’:funtion(){}都可以簡寫爲firstname(){}

使用監聽器的好處:

  • 開發者只需要關注model之間的關係,而不需要關注用戶的操作對view的影響。

監聽路由

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <router-view></router-view>
  </div>

  <template id="index">
    <div>
      <h1>首頁</h1>
      <router-link to="index/login" tag="button">點擊登錄</router-link>
      <router-view></router-view>
    </div>
  </template>

  <template id="login">
    <div>
      <p>登錄組件</p>
      <!-- 使用子路由的時候,必需且僅需加上上一級父路由 -->
      <router-link to="login/success" tag="button">提交登錄</router-link>
      <router-view></router-view>
    </div>
  </template>

  <template id="success">
    <div>
      <p>登錄成功</p>
    </div>
  </template>

</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>
  var login = {
    template:'#login'
  }

  var success = {
    template:'#success'
  }

  var index = {
    template:'#index'
  }

  let routerObj = new VueRouter({
    routes:[
      {path:'/',redirect:'/index'},//這個不是重定向請求,僅僅是重定向組件
      {path:'/index',component:index,
        children:[{
          // 斜槓/表示從根路徑匹配,而子路由不能加/,而且實際上會默認給子路由加上父路由
          path:'login',component:login,
          children:[{
            path:'success',component:success
          }]
        }]
      }]

  })

  var vue = new Vue({
    el:'#app',
    router:routerObj,
    watch:{
      '$route.fullPath'(newVal,oldVal){
        console.log('用戶從',oldVal,'跳轉到',newVal)
      }
    }
  })

</script>
</html>

注意看watch部分

在這裏插入圖片描述
通過路由監聽,可以實現後端攔截器的功能:監聽路由的url是否爲登錄url,如果不是,則檢查用戶是否登錄過,若沒登陸過,則重定向到登錄路由。

9.2 computed

用監聽器實現數據拼接太麻煩了,有更好的方式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <div>firstname: {{firstname}}</div>
    <div>lastname: {{lastname}}</div>
    <div>fullname: {{sumName}}</div>
    <input type="text" v-model="firstname">
    <br>
    <input type="text" v-model="lastname">
    <br>
    <input type="text" v-model="sumName">
  </div>

</body>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
<script>


  var vue = new Vue({
    el:'#app',
    data:{
      firstname:'',
      lastname:'',
      fullname:'',
    },
    computed:{
      sumName(){
        return this.firstname+this.lastname
      }
    }
  })

</script>
</html>

注意:

  • 雖然computed中定義的是方法,但是它的使用方式,一定是屬性,決不能帶括號
  • 計算屬性中的任意屬性變化了,則會立即進行計算
  • 計算屬性的結果會被緩存,計算屬性中的屬性沒有改變時,不會進行計算

computed的get和set

還可以將computed當做對象使用,調用他的get和set方法。
get:當計算computed目標時調用
set:當設置computed目標時調用

需求:
計算器a+b=c,c爲計算屬性,要求更改ab時,得出c----get。
要求更改c的時候,得出a和b----set

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <input type="text" v-model.number="a">
    +
    <input type="text" v-model.number="b">
    =
    <input type="text" v-model.number="sum">
  </div>

</body>
<script src="js/vue.js"></script>
<script>


  var vue = new Vue({
    el:'#app',
    data:{
      a:0,
      b:0,
      c:0,
    },
    computed:{
      sum:{
        get(){
          return this.a + this.b
        },
        set(val){
          this.a=val-this.b;
          this.b=val-this.a;
        }
      }
    }
  })

</script>
</html>

10. Webpack

10.1 準備工作 – node 和 npm

node是JavaScript的運行時環境(類似於Tomcat是Java的一個運行環境),node爲js提供了更強大的操作方式,
如:

  • 在瀏覽器中,js無法寫服務接口,node提供了後端代碼編寫功能(寫後臺、操作數據庫)
  • 在瀏覽器中,js無法操作文件,node提供了文件操作

但不會真的用node寫後臺,更多的是用它來寫前端配置,如:跨域代理

此處node僅用於提供編寫vue的環境。

初步使用,官網下載node,一路下一步即可。然後將nodejs整個文件夾加入到環境變量中

然後在cmd中查看node是否配置成功

node -v

並查看npm版本

npm -v

npm是node提供的一個包管理工具,類似於maven。
通過npm安裝依賴包,就不需要在頁面上使用script標籤引入了。

npm配置淘寶鏡像:

npm config set registry https://registry.npm.taobao.org

10.2 開始webpack

問:網頁中的靜態文件過多會怎樣?
答:靜態文件需要發起二次請求來引入,過多的時候會導致網頁很慢很卡
問:網頁中有哪些靜態文件?
答:js、css、圖片、

如何解決上述問題?
合併、壓縮、精靈圖(將小圖合併爲一張圖,因此只需要請求一次)、base64編碼、webpack

概念理解(配置文件中)

  • 入口(entry):webpack應該從哪個地方開始進行打包
  • 輸出(output):打包之後的路徑,打包之後會輸出bundles,默認爲./dist(因此可以不配置)
  • loader:讓webpack能夠處理非js文件,webpack默認只能處理js文件
    • test屬性:用於標識被對應的loader進行轉換的某些文件(正則表達式)
    • use屬性:標識轉換時使用哪個loader
  • 插件(plugins):常用於打包優化和壓縮,使用某個插件,通過==const pluginName = require(‘插件名’)==引入
  • mode:development或者production,設置開發環境(調試編碼)還是生產環境(上線)

import和export

import 導入
export導出
vue不像java,需要使用某個模塊時,不僅僅需要import導入該模塊,而且需要在該模塊中將所需對象export向外暴露,否則import是無法生效的。
export default一個模塊有且僅有一個

10.3 創建webpack項目(學習)

  1. 創建一個空文件夾webpackStudy,用VSCode打開該文件夾

  2. 打開cmd終端,執行npm init,後面出現的各種初始化信息按需選擇,我只填了個test項目名,其中默認的入口文件是index.js,然後一直回車到底,生成對應的package.json文件,用於打包配置。

  3. 安裝webpack,先全局環境,後開發環境(可以先用webpack -v查看全局是否安裝過)

    webpack -v
    npm i webpack -g
    npm i webpack --save-dev
    

    可以看到package.json中的devDependencies已經導入了webpack

  4. 創建src文件夾,(src表示源碼目錄),在scr下創建入口文件index.js和index.html (node_modules是node的依賴包,不要管也不要動)

    alert('我是index');
    

    我用的 !+回車 自動生成的html代碼

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>index</title>
    </head>
    <body>
      <h1>我是首頁</h1>
    </body>
    </html>
    
  5. 根目錄創建webpack.config.js文件

    //導入內置的路徑處理模塊
    const path = require('path');
    
    const config = {
      entry: path.resolve(__dirname,'src/index.js'),
      output: {
        // path: path.resolve(__dirname,'dist'),//輸出路徑,默認就是dist
        filename:'bundle.js' //輸出文件名,默認index.js
      
      }, 
    };
    
    module.exports = config;
    

    意思是配置入口文件,

  6. 更改終端啓動命令,在package.js中將scripts修改爲如下

    {
      "name": "test",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "dev":"webpack"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "webpack": "^4.41.5"
      }
    }
    

    scripts用於配置npm run命令,上述更改意思是當npm run dev時,等價於npm run webpack,簡化代碼,可以自定義

  7. 執行npm run dev查看效果,控制檯會要求下載webpack-cli,輸入yes進行安裝。隨後可以看到多了dist文件夾,裏面有打包好的main.js,但是,並沒有將index.html打包,因爲webpack只支持js,因此需要插件

  8. 安裝webpack生成html文件的插件:

    npm i html-webpack-plugin --save-dev
    

    在webpack.config.js中聲明使用該插件

    //導入內置的路徑處理模塊
    const path = require('path');
    
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    
    const config = {
      entry: path.resolve(__dirname,'src/index.js'),
      output: {
        // path: path.resolve(__dirname,'dist'),//輸出路徑,默認就是dist
        filename:'bundle.js' //輸出文件名,默認index.js
      
      }, 
      plugins: [
        new HtmlWebpackPlugin({
          template: path.resolve(__dirname,'src/index.html'),
        })
      ],
    };
    
    module.exports = config;
    
    

    然後npm run dev,可以看到dist下生成了index.html,打開該index,能夠看到“我是首頁”的h1標題,也能看到alert彈窗

  9. 配置實施熱部署
    安裝 npm i webpack-dev-server --save-dev
    將原本package中的scripts中的"dev":"webpack-dev-server --open --hot " 後面還可以跟 --port 8888實現更改端口,默認8080
    運行npm run dev
    注意webpack-dev-server不會實現實時打包,而是存放在內存中,當編碼完畢再執行webpack進行打包

  10. 配置打包css文件:
    給index.html中的h1加一個class=“my”,在src下創建css/index.css,裏面寫

    .my{
      color: red
    }
    

    在index引入這個css文件

    alert('我是index');
    
    import './css/index.css'
    

    然後運行項目會發現沒作用,打開控制檯報了一堆錯誤,還是那句話:因爲webpack只支持js。因此需要安裝loader

    npm i --save-dev style-loader css-loader
    

    在webpack.config.js中創建models節點,裝載loader

    //導入內置的路徑處理模塊
    const path = require('path');
    
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    
    const config = {
      entry: path.resolve(__dirname,'src/index.js'),
      output: {
        // path: path.resolve(__dirname,'dist'),//輸出路徑,默認就是dist
        filename:'bundle.js' //輸出文件名,默認index.js
      
      }, 
      plugins: [
        new HtmlWebpackPlugin({
          template: path.resolve(__dirname,'src/index.html'),
        })
      ],
      module:{//註冊第三方模塊
        rules:[
          {test: /\.css$/,use: ['style-loader','css-loader']}//配置處理css
        ]
      }
    };
    
    module.exports = config;
    

    然後運行項目發現css起作用了。
    (如果是UI框架,則直接在index.html中導入即可)

  11. 開始vue編寫,將index.js中的代碼全部註釋
    安裝vue和loader

    npm -i vue vue-loader vue-template-compiler --save-dev
    

    在webpack.config.js中註冊組件和loader(僅僅展示了關鍵代碼)

    const VueLoaderPlugin = require('vue-loader/lib/plugin');
    
    plugins: [
        new HtmlWebpackPlugin({
          template: path.resolve(__dirname,'src/index.html'),
        }),
        new VueLoaderPlugin(),
      ],
      module:{//註冊第三方模塊
        rules:[
          {test: /\.css$/,use: ['style-loader','css-loader']},//配置處理css
          {test: /\.vue$/,use: 'vue-loader'},//配置處理vue
        ]
      }
    

    index.html中給一個vue容器

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

    創建template/login.vue

    <template>
      <div>
        <h1>登錄組件</h1>
        <div>{{msg}}</div>
      </div>
    </template>
    
    <script>
    export default{
      data(){
        return{
          msg: 'Hello login'
        }
      },
      methods:{
    
      },
      filters:{
    
      },
      computed:{
    
      }
    }
    </script>
    
    <style scoped>
    /* 必須加scoped,表示僅在本組件中生效,否則會產生樣式污染 */
    </style>
    

    在index.js中導入

    import Vue from 'vue/dist/vue.esm.js' 
    import login from './templates/login.vue'
    
    var vm = new Vue({
      el: '#app',
      rander: c => c(login),  //意思是,傳入的是一個函數c,返回值是c(login),註冊組件並渲染
    })
    
  12. vue路由的使用:
    安裝路由
    npm i vue-router --save-dev
    src下創建router/index.js

    import Vue from 'vue/dist/vue.esm.js'
    import login from '../templates/login.vue'
    import VueRouter from 'vue-router'
    
    Vue.use(VueRouter)
    
    var router = new VueRouter({
      routes:[
        {path: '/login', component: login}
      ]
    })
    
    export default router
    

    src下的index.js導入該路由

    import Vue from 'vue/dist/vue.esm.js' 
    import app from './app.vue'
    
    import router from './router'
    
    
    var vm = new Vue({
      el: '#app',
      rander: c => c(app),  //意思是,傳入的是一個函數c,返回值是c(app),註冊組件並渲染
      router: router,
    })
    

11. vue-cli(核心)

11.1 創建項目

  1. 全局安裝 npm i -g @vue/[email protected]
  2. 查看版本 vue -V (V要大寫)
  3. 進入到項目目錄下,使用vue ui命令打開創建項目窗口
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
    然後點擊創建項目,不保存預設。
  4. 然後用彈出來的儀表盤,下載相關依賴(注意不是插件)
    我們需要axios和element-ui
    在這裏插入圖片描述
  5. 用vscode將該項目打開(腳手架在package中的scripts中配置的是serve運行項目,可以將其改成dev)
  6. 根目錄創建vue.config.js配置文件
    // vue.config.js 配置說明
    // 這裏只列一部分,具體配置參考文檔
    module.exports = {
        // baseUrl :'/' 
        // 將部署應用程序的基本URL
        // 默認情況下,Vue CLI假設您的應用程序將部署在域的根目錄下。
        // https://www.my-app.com/。如果應用程序部署在子路徑上,則需要使用此選項指定子路徑。例如,如果您的應用程序部署在https://www.foobar.com/my-app/,集baseUrl到'/my-app/'.
    
        // baseUrl: '/',
    
        //   lintOnSave:{ type:Boolean default:true } 問你是否使用eslint
        lintOnSave: false,
        // productionSourceMap:{ type:Bollean,default:true } 生產源映射
        // 如果您不需要生產時的源映射,那麼將此設置爲false可以加速生產構建
        productionSourceMap: false,
        // devServer:{type:Object} 3個屬性host,port,https
        // 它支持webPack-dev-server的所有選項
    
        devServer: {
            port: 8085, // 端口號
            open: true, //配置自動啓動瀏覽器
            // proxy: 'http://localhost:4000' // 配置跨域處理,只有一個代理
            proxy: {
                '/': {
                    target: 'http://localhost:8080',
                    ws: true,
                    changeOrigin: true
                }
            },  // 配置多個代理
        }
    }
    
  7. 然後 npm run dev ,可以看到vue啓動的頁面
  8. src下創建utils文件夾,創建request.js配置axios,這是一個官方推薦的配置,主要是通過request攔截器在發起請求之前進行加密等處理,通過response攔截器在頁面響應請求之前處理數據。
    import axios from 'axios'
    const service = axios.create({
      baseURL: '/',
      timeout: 5000 // 默認請求超時時間5s
    })
    
    // request 攔截器
    service.interceptors.request.use(
      config => {
        return config
      },
      error => {
        return Promise.reject(error)
      }
    )
    
    // response 攔截器
    service.interceptors.response.use(
      response => {
        const res = response.data
        return res
      },
      error => {
      }
    )
    
    export default service
    
    
  9. 在src下創建api文件夾,編寫api.js,用於編寫api方法,如增刪改查
    import request from '../utils/request'
    const group_name = 'department'
    export default {
      departmentList() {   //查詢列表接口
        return request({
          //反引號中可以使用模板表達式,可以任意換行
          url: `/${group_name}/departmentList`,
          method: 'get'
        })
      },
      save(department){  //保存接口
        return request({
          url:`/${group_name}/save`,
          method: 'post',
          data:department
        })
      }
    }
    

11.2 element-ui

  1. 將App.vue中的nav和style刪除,將view中的vue文件刪除,將router的index.js中與home和about頁面相關的都註釋掉
  2. 引入element-ui,main.js中
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    
    import ElementUI from 'element-ui';
    import 'element-ui/lib/theme-chalk/index.css';
    Vue.use(ElementUI);
    
    Vue.config.productionTip = false
    
    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app')
    
  3. 然後去element-ui官方文檔查看示例代碼盡情複製修改

11.3 編寫步驟

  1. 在component或者view下創建組件(view是頁面級組件、component是小組件)
  2. 在router/index.js中導入該組件,並註冊路由
  3. 在其他頁面引入該路由,通過路由訪問該組件;或者在其他頁面下import該組件,通過組件形式訪問該組件;
方式一:通過路由訪問該組件
<router-link to="/login">登錄</router-link>
方式二:通過導入組件訪問(引入、聲明、使用)
<template>
  <div id="login">
    <LoginForm/> 這裏使用組件
  </div>
</template>

<script>
// 這裏引入組件
import LoginForm from '@/components/LoginForm.vue' 

export default {
  name: 'Login',
  //這裏聲明組件
  components: {
    LoginForm
  }
}
</script>

12. 跨域

跨域:當請求方和響應方的ip或端口不同時,就是跨域;出於安全起見,瀏覽器不允許跨域請求

解決方案:

  1. 後端通過過濾器放行 options 請求,設置 Access-Control-Allow-Origin 頭部解決跨域(瀏覽器會先發options請求“探路”)
  2. 使用Nginx做代理,由於跨域問題只出現在客服端對服務端,而服務端對服務端是不存在的,因此通過Nginx實現:客戶端請求Nginx,Nginx請求服務端,避免了客戶端請求服務端,解決跨域(生產環境
  3. 使用node.js解決跨域(vue中使用webpack解決),就是上面的vue.config.js中的proxy配置,而request.js中的baseURL的/,就是指這個代理地址(適用於開發環境,因爲併發能力太差

13. UI框架

PC端:

  • bootstrap:底層依賴jQuery,不符合vue思想
  • layUI:雖然使用時不需要引入jQuery,但是底層使用了jQuery,而且非常依賴DOM操作
  • iView:專職於vue的UI框架
  • ant-design-vue:螞蟻金服開源的針對vue開發的UI框架,jeecg就是用這個
  • elementUI:目前vue開發者使用最多的UI框架,餓了麼(阿里)開源

移動端

  • MUI:半原生開發
  • MintUI:功能較少
  • AntUI:螞蟻金服開源,支付寶風格,封裝不太好
  • vant:封裝較好

js重點

var定義的變量,沒有塊的概念,可以跨塊訪問, 不能跨函數訪問。
let定義的變量,只能在塊作用域裏訪問,不能跨塊訪問,也不能跨函數訪問。
const用來定義常量,使用時必須初始化(即必須賦值),只能在塊作用域裏訪問,而且不能修改。

list.push(obj)  將obj添加到數組後面
list.unshift(obj) 將obj添加到數組前面

不要使用關鍵字給函數命名,如delete

學習一下ES6的語法。

null表示有這個對象,但是爲空
undefined表示壓根沒有這個對象

VSCode編碼語法

!回車:生成html框架
select>option4:生成有4個選項的select標籤
table>tr
3>td*5:生成三行五列的table

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章