爲什麼使用vue
大量的html css以及js文件難以管理
vue的招聘
介紹
簡單來說,Vue是一套渲染UI的強大前端框架。
數據:響應式
vue特點
主要特性:
- 學習曲線非常平緩,只要有html/css,js基礎即可上手
- 漸進式,可以在服務端項目中部分使用vue
- 響應式的支持,讓我們從傳統的JQuery的面向DOM編程,轉變爲面向數據編程
- 組件化,可以把頁面分成很多組件,每個組件都有自己的html css以及js
- 豐富的語法支持
- 優雅的單文件組件
- 完善的組件動畫支持
- 成熟的生態,比如vue-cli,VueRouter,Vuex等相關配套的工具
其中,最重要最核心的特性就是:響應式和組件化。
安裝
-
通過
<script></script>
引用<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
-
通過vue-cli安裝全套開發環境,項目開發推薦
快速嚐鮮
<head>
<meta charset="UTF-8">
<title>快速入門</title>
<script src="./lib/vue.js"></script>
</head>
<body>
<div id="app">{{msg}}</div>
<script type="text/javascript">
let vue = new Vue({
el:"#app",
data:{
msg:"hello"
}
})
</script>
</body>
vue是響應式的,只要數據發生變化就會自動更新數據顯示
vue指令
vue有很多指令可以實現數據和控件的綁定
指令帶有前綴 v-
,以表示它們是 Vue 提供的特殊特性。它們會在渲染的 DOM 上應用特殊的響應式行爲
v-bind
<div id="app">
<span v-bind:title="msg">鼠標懸浮</span>
<input type="text" v-bind:value="msg">
</div>
<script type="text/javascript">
let vue = new Vue({
el:"#app",
data:{
msg:"hello"
}
})
</script>
注意:v-bind:value
可以簡寫爲:value
v-model
v-model一般用在input textarea select中,實現輸入框和應用狀態的雙向綁定
-
不使用v-model的實現
<!--普通實現--> <div> <input type="text" id="input" onkeyup="handKeyUp()"><br> span中顯示內容<br> <span id="span"></span> </div> <script type="text/javascript"> function handKeyUp(e) { //查找輸入框控件 let inputValue = document.getElementById('input').value //查找span控件 let spanEle = document.getElementById('span') //設置span控件的值 spanEle.innerText = inputValue } </script>
-
使用v-model實現
<div id="app"> <input type="text" v-model="msg"><br> span中顯示內容<br> <span>{{msg}}</span> </div> <script type="text/javascript"> let vue = new Vue({ el:"#app", data:{ msg:"" } }) </script>
思考一下:v-bind能不能實現?
v-for
v-for
指令可以綁定數組的數據來渲染一個項目列表
-
普通實現
<div id="app"> 于謙的愛好: <ol id="ol"> </ol> </div> <script type="text/javascript"> //網絡請求 let hobbies = ['抽菸','喝酒','燙頭'] //獲取列表的控件 let olEle = document.getElementById('ol') //定義innerhtml屬性 let inHtml = '' //循環數組 hobbies.forEach((item,index,arr)=>{ inHtml += '<li>'+item+'</li>' }) //設置裏面的html olEle.innerHTML = inHtml </script>
-
v-for實現
<div id="app"> 于謙的愛好: <ol> <li v-for="item in hobbies">{{item}}</li> </ol> </div> <script type="text/javascript"> let vue = new Vue({ el:"#app", data:{ hobbies:['抽菸','喝酒','燙頭'] } }) </script>
v-if
條件判斷
<div id="app">
<div v-if="isShow">控制顯示或者隱藏</div>
<button @click="isShow = !isShow">切換顯示狀態</button>
</div>
<script type="text/javascript">
let vue = new Vue({
el:"#app",
data:{
isShow:true
}
})
</script>
注意:v-on:click
可以簡寫爲@click
-
v-on:click
vue處理點擊事件
簡寫
@click
<button v-on:click="shouldShow = !shouldShow">顯示或者隱藏</button> <button @click="shouldShow = !shouldShow">顯示或者隱藏</button>
v-once
一次性插值
<div id="app">
<span v-once>{{msg}}</span>
</div>
<script type="text/javascript">
let data = {
msg: "hello world"
}
let vue = new Vue({
el: "#app",
data: data
})
</script>
vue實例
每個 Vue 應用都是通過用 Vue
函數創建一個新的 Vue 實例開始的
<script type="text/javascript">
let vm = new Vue({
// 選項
})
</script>
MVC模式
MVP模式
MVVM模式
數據和方法
<div id="app">
<span>{{msg}}</span><br>
<button @click="handClick">按鈕</button>
</div>
<script type="text/javascript">
let data = {
msg: "hello world"
}
let vue = new Vue({
el: "#app",
data: data,
methods:{
handClick(){
this.msg = "你好 世界"
}
}
})
</script>
生命週期鉤子
生命週期鉤子其實就是生命週期的回調函數.Vue實例從初始化,創建,顯示,更新以及銷燬的整個過程,而生命週期鉤子指的是每個過程都有一個回調函數,Vue中把回調函數稱爲鉤子。
- beforeCreate : 開始創建實例
- created : 實例創建出來了,vue的實例基本上被初始化
- beforeMount : 模版與數據相結合,頁面渲染之前,執行的函數
- mounted: 模版和數據結合完成,會將Vue實例掛載到dom樹上
- beforeDestroy : 實例要被回收的時候執行
- destroyed : 實例回收完成的時候調用
- beforeUpdate: 數據發生改變,還沒有渲染之前
- updated : 渲染完成
模板語法
<div id="app">
</div>
<script type="text/javascript">
let data = {
msg: "hello world"
}
let vue = new Vue({
el: "#app",
data: data,
template:'<div>\n' +
' <span>{{msg}}</span><br>\n' +
' <button @click="handClick">按鈕</button>\n' +
'</div>',
methods:{
handClick(){
this.msg = "你好 世界"
}
}
})
</script>
計算屬性
模板內的表達式非常便利,但是設計它們的初衷是用於簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護
-
普通實現
<div id="app"> <span>{{fullName()}}</span> </div> <script type="text/javascript"> let vue = new Vue({ el: "#app", data: { firstName:'bill', lastName:'gates' }, methods:{ fullName(){ console.log('執行了') return this.firstName+this.lastName } } }) </script>
-
計算屬性
<div id="app"> <span>{{fullName}}</span> </div> <script type="text/javascript"> let vue = new Vue({ el: "#app", data: { firstName:'bill', lastName:'gates', }, computed:{ fullName(){ console.log('執行了') return this.firstName+this.lastName } } }) </script>
-
計算屬性和普通實現的區別
頁面元素髮生變化時,普通方法會重新執行一遍,而計算屬性有緩存不會重新計算
計算屬性不需要寫函數()
偵聽屬性
觀察和相應vue上的數據變動
<div id="app">
<span>{{fullName}}</span>
<span>{{msg}}</span>
</div>
<script type="text/javascript">
let vue = new Vue({
el: "#app",
data: {
firstName:'bill',
lastName:'gates',
fullName:'bill gates',
msg:'哈哈'
},
watch:{
firstName(newVal,oldVal){
console.log('newVal='+newVal+'---oldVal='+oldVal)
},
lastName(newVal,oldVal){
console.log('newVal='+newVal+'---oldVal='+oldVal)
}
}
})
</script>
開發中儘量使用:計算屬性>偵聽器>普通屬性
class的動態綁定
<head>
<meta charset="UTF-8">
<title>class的動態綁定</title>
<script src="./lib/vue.js"></script>
<style>
.c1 {
background: red;
}
.c1-ac {
font-size: 40px;
}
</style>
</head>
<body>
<div id="app">
<!--<div :class="isActive ? cls : ''" @click="handClick">動態顯示樣式的條目</div>-->
<div class="c1" :class="{'c1-ac':isActive}" @click="handClick">動態顯示樣式的條目</div>
<div :class="cls">固定顯示樣式的條目</div>
</div>
</body>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
isActive: false,
cls: ['c1', 'c1-ac']
},
methods: {
handClick() {
console.log('點擊事件')
this.isActive = !this.isActive
console.log(this.isActived)
}
}
})
</script>
條件渲染
-
v-if
v-if顯示的文本 -
v-if v-else-if v-else
<div> <input type="number" v-model="age"> <div v-if="age>90">老年人</div> <div v-else-if="age>60">中年人</div> <div v-else>少年</div> </div>
-
v-if和v-show
<div v-show="show">v-show顯示的文本</div> <div v-if="show">v-if顯示的文本</div> <button @click="show = !show">顯示或隱藏</button>
v-if不顯示時就從DOM中移除,v-show還在DOM中
開發中儘量使用v-show
列表渲染
-
數組渲染
<body> <div id="app"> <!--數組不帶角標--> <div>數組不帶角標:</div> <ul> <li v-for="item in hobbies">{{item}}</li> </ul> <!--數組帶角標--> <div>數組帶角標:</div> <ul> <li v-for="item,index in hobbies">{{item}} {{index}}</li> </ul> </div> </body> <script type="text/javascript"> let vm = new Vue({ el: "#app", data: { hobbies:['抽菸','喝酒','燙頭'] }, methods: {} }) </script>
-
對象渲染
<div id="app"> <div>對象不帶屬性名:</div> <ul> <li v-for="ele in person">{{ele}}</li> </ul> <div>對象帶屬性名:</div> <ul> <li v-for="ele,name in person">{{ele}} {{name}}</li> </ul> <div>對象帶屬性名和角標:</div> <ul> <li v-for="ele,name,index in person">{{ele}} {{name}} {{index}}</li> </ul> </div> </body> <script type="text/javascript"> let vm = new Vue({ el: "#app", data: { person:{ 'name':'張三', age:20, phone:'13354234567' } }, methods: {} }) </script>
-
數組列表增加和刪除條目
<div id="app"> <input type="text" v-model="input"><button @click="add">添加</button><br> <ul> <li v-for="item,index in hobbies">{{item}} {{index}}</li> </ul> <input type="number" v-model="index"><button @click="deleteItem">刪除</button> </div> </body> <script type="text/javascript"> let vm = new Vue({ el: "#app", data: { hobbies:['抽菸','喝酒','燙頭'], input:'', index:0 }, methods: { add(){ //不會更新 // this.hobbies[this.hobbies.length] = this.input //用push方法 this.hobbies.push(this.input) }, deleteItem(){ this.hobbies.splice(this.index,1) } } }) </script>
-
注意:對象渲染列表如果增加一個屬性是不會刷新的需要通過set方法
<body> <div id="app"> <input type="text" v-model="input"><button @click="add">添加</button><br> <ul> <li v-for="item,index in person">{{item}}</li> </ul> <input type="number" v-model="index"><button @click="deleteItem">刪除</button> </div> </body> <script type="text/javascript"> let vm = new Vue({ el: "#app", data: { person:{ 'name':'bill', age:20, phone:'1234455' }, input:'', index:0 }, methods: { add(){ //這種方式不行 // this.person.email = this.input //通過set方法是響應式的 Vue.set(this.person,'email',this.input) }, deleteItem(){ // this.hobbies.splice(this.index,1) } } }) </script>
-
當我們去使用v-for的時候,最好去給它指定一個唯一的key值,這樣的會方便vue複用dom節點,從而提高性能
組件
組件是可複用的 Vue 實例,它與 new Vue
接收相同的選項,例如 data
、computed
、watch
、methods
以及生命週期鉤子等。僅有的例外是像 el
這樣根實例特有的選項。
全局組件
-
定義和使用全局組件
<div id="app"> <title-bar></title-bar> <div>內容</div> <bottom-bar></bottom-bar> </div> </body> <script type="text/javascript"> <!--全局組件--> Vue.component('title-bar',{ template:'<div>標題</div>' }) Vue.component('bottom-bar',{ template:'<div>底部菜單</div>' }) let vm = new Vue({ el: "#app", data: { }, methods: { } }) </script>
-
組件的data
一個組件的 data 選項必須是一個函數,因此每個實例可以維護一份被返回對象的獨立的拷貝
Vue.component('title-bar', { template: '<div>{{msg}}</div>', data() { return { msg: '我是標題' } } })
局部組件
<div id="app">
<title-bar></title-bar>
<div>內容</div>
<bottom-bar></bottom-bar>
</div>
</body>
<script type="text/javascript">
let TitleBar = {
name:'title-bar',
template:'<div>{{msg}}</div>',
data(){
return{
msg:'從data中獲取標題'
}
}
}
let BottomBar={
name:'bottom-bar',
template:'<div>底部欄目</div>'
}
let vm = new Vue({
el: "#app",
data: {
},
methods: {
},
components:{
TitleBar,
BottomBar
}
})
</script>
父子組件之間的通信
父組件傳遞數據給子組件
<body>
<div id="app">
<title-bar :mytitle="msg"></title-bar>
<div>內容</div>
<bottom-bar></bottom-bar>
</div>
</body>
<script type="text/javascript">
let TitleBar = {
name:'title-bar',
template:'<div>{{mytitle}}</div>',
props:['mytitle'],
data(){
return{
}
}
}
由於直接傳遞數據,子組件不能修改所以可以通過參數來接收父組件傳遞的數據
let TitleBar = {
name:'title-bar',
template:'<div>{{msg}}</div>',
props:['mytitle'],
data(){
return{
msg:this.mytitle
}
}
}
子組件傳遞數據給父組件
子控件需要先處理事件並把事件通過this.$emit
分發出去
<body>
<div id="app">
<title-bar :mytitle="msg" @child-click="handClick"></title-bar>
<div>內容</div>
<bottom-bar></bottom-bar>
</div>
</body>
<script type="text/javascript">
let TitleBar = {
name:'title-bar',
template:'<div>{{mytitle}} <button @click="handClick">返回</button></div>',
props:['mytitle'],
data(){
return{
translateMsg:'子組件傳遞給父組件'
}
},
methods:{
handClick(){
console.log('子控件點擊事件')
this.$emit('child-click',this.translateMsg)
}
}
}
let BottomBar={
name:'bottom-bar',
template:'<div>底部欄目</div>'
}
let vm = new Vue({
el: "#app",
data: {
msg:'父組件中傳遞的消息標題'
},
methods: {
handClick(msg){
console.log('點擊了子控件的button')
}
},
components:{
TitleBar,
BottomBar
}
})
</script>
或者直接將事件分發出去:$emit('enlarge-text', 0.1)
組件綁定原生事件
如果我們在自定義組件上綁定事件是沒有效果的,因爲組件上定義的事件都是自定義的,想要觸發需要我們在子組件內部調用$emit派發.但是這樣做又很麻煩,所以當我們想使用點擊事件,我們可以使用Vue提供的綁定原生事件方式,我們只需要使用
@click.native
<div id="app">
<title-bar :mytitle="msg" @click.native="handClick"></title-bar>
<div>內容</div>
<bottom-bar></bottom-bar>
</div>
組件插槽
首先看一個例子
<body>
<div id="app">
<child></child>
</div>
</body>
<script type="text/javascript">
let Child = {
name: 'child',
template: `<div>
<div>標題</div>
<div>內容</div>
<div>底部</div>
</div>`,
data() {
return {}
}
}
let vm = new Vue({
el: "#app",
data: {},
components: {
Child
}
})
</script>
一般頁面的標題和底部都是一樣的,但是內容是可變的,這樣寫的話就寫死了,所以需要用的時候傳內容
body>
<div id="app">
<child :content="content"></child>
</div>
</body>
<script type="text/javascript">
/*但是內容是可變的,怎麼辦?*/
let Child = {
name: 'child',
props:['content'],
template: `<div>
<div>標題</div>
<div v-html="content"></div>
<div>底部</div>
</div>`,
data() {
return {
}
}
}
let vm = new Vue({
el: "#app",
data: {
content:`<span>你好</span>`
},
components: {
Child
}
})
</script>
這樣的話就在vue實例裏面傳遞html元素給子控件,但是這樣寫的話也不直觀,我們希望的是能夠直接在html裏面添加自己的元素
但是能不能直接往自定義子控件裏面添加元素呢?
<div id="app">
<child>
<span>我是span內容</span>
</child>
</div>
這樣是不行的,不識別,這時就需要組件插槽了
<body>
<div id="app">
<child>
<span>我是span內容</span>
</child>
</div>
</body>
<script type="text/javascript">
/*但是內容是可變的,怎麼辦?*/
let Child = {
name: 'child',
props:['content'],
template: `<div>
<div>標題</div>
<slot></slot>
<div>底部</div>
</div>`,
data() {
return {
}
}
}
具名插槽
多個插槽可以給每一個插槽指定名稱
<body>
<div id="app">
<child>
<div slot="content">我是內容</div>
<div slot="foot">我是底部</div>
</child>
</div>
</body>
<script type="text/javascript">
/*但是內容是可變的,怎麼辦?*/
let Child = {
name: 'child',
props:['content'],
template: `<div>
<div>標題</div>
<slot name="content"></slot>
<slot name="foot"></slot>
</div>`,
data() {
return {
}
}
}
動態組件
組件切換
<body>
<div id="app">
<h1>標題欄</h1>
<component :is="curcom"></component>
<button @click="curcom='home'">首頁</button>
<br>
<button @click="curcom='my'">我的</button>
<br>
</div>
</body>
<script type="text/javascript">
let Home = {
name:'home',
template:`<div>首頁</div>`
}
let My = {
name:'my',
template:`<div>我的</div>`
}
let vm = new Vue({
el: "#app",
data: {
curcom:'home'
},
components: {
Home,
My
}
})
</script>