一、初识Vue
1、读音
Vue:/vju:/。类似于View
2、定义
是一个构建用户界面的渐进式框架。
- 渐进式意味着你可以将Vue作为你应用的一部分(先画一个圈)嵌入其中,带来更丰富的交互体验。
- 当然也有全家桶:比如Core+Vue-router+Vuex,也可以满足你各种各样的需求。
3、安装
- 直接CDN引入
- 下载和引入
- NPM安装
二、Hello Vue
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./static/vue.min.js"></script> </head> <body> <div id="app">{{sayHi}}</div> <script> //数据模板引擎 new Vue({ el:"#app", data:{ sayHi:"Hello,Vue!" } }) </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title></title> <script src="js/vue.js" type="text/javascript"></script> </head> <body> <div id="app"> <h2>当前计数:{{counter}}</h2> <button v-on:click="add">+</button> <button v-on:click="sub">-</button> </div> <script> const app = new Vue({ el: "#app", data: { counter: 0 }, methods:{ add:function(){ this.counter=this.counter+1; }, sub:function(){ this.counter=this.counter-1; } } }) </script> </body> </html>
特点
- 编程范式:命令式和声明式。js属于命令式,Vue属于声明式。
- 响应式:Vue属于数据响应式视图。通过数据的变化从而影响页面视图的展示
- {{}},mustache语法
- new Vue 中的 options 属性。
- el:类型:string | HTMLElement;
- el:作用:决定之后Vue实例会管理哪一个DOM
- data:类型:object|Function;
- data:作用:Vue实例对应的数据对象
- methods:类型:{[key:string]:function}
- methods:作用:定义属于Vue的方法,可以在其他地方调用,也可以在指令中使用
MVVM
- View:视图层,DOM层,给用户展示各种信息。
- Model:数据层,固定数据、服务器、网络上请求下来。
- VueModel:视图模型,View和Model沟通的桥梁。
- 1:它实现了数据绑定(DataBinding), 将Model的改变实时的反映到View中
- 2:它实现了DOM监听(DOM Listener),当DOM发生一些事件(点击、滚动、touch等),可以监听,并在需要的情况下改变对应的Data
三、指令
1、插值指令
<body> <div id="app" v-once> {{once}} </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { once:"表示元素和组件只渲染一次!" }, }) </script> </body>
<body> <div id="app" v-text="sayHi"></div> <script> //数据模板引擎 new Vue({ el:"#app", data:{ sayHi:"Hello,Vue!" } }) </script> </body>
<body> <div id="app" v-html="sayHi"> </div> <script> new Vue({ el: "#app", data: { sayHi: "<h1>Hello, Vue</h1>" } } ) </script> </body>
<body> <div id="app" v-pre> {{pre}} </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { pre:"将代码原封不动的解析出来!" }, }) </script> </body>
<body> <style> [v-cloak]{ display: none; } </style> <div id="app" v-cloak> {{pre}} </div> <script src="js/vue.js" type="text/javascript"></script> <script> setTimeout(function() { let app = new Vue({ el: "#app", data: { pre: "斗篷函数!" }, }) }, 1000) </script> </body>
<div id="app3"> <ul> <li v-for="aihao in hobby">{{aihao}}</li> </ul> </div> <script> new Vue({ el: "#app3", data: { hobby: ["跑步", "游泳", "阅读" ], } } ) </script>
2、属性绑定指令 v-bind
<body> <div id="app"> <a :href="baidu">百度一下</a> <img :src="imgSrc"> </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { baidu: "https://www.baidu.com/", imgSrc: "https://imgsrc.baidu.com/baike/pic/item/0df3d7ca7bcb0a4661ab1f6c6463f6246a60afde.jpg" }, }) </script> </body>
<body> <div id="app"> <div :class="['class1','class2']">数组语法</div> <div :class="arryClass">数组语法2</div> <div :class="{'class5':true,'class6':false}">对象语法</div> <div :class="{'class7':isclass7,'class8':isclass8}">对象语法2</div> <div :class="getObjClass()">对象语法3</div> </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { arryClass: ['class3', 'class4'], isclass7: true, isclass8: false, }, methods: { getObjClass: function() { return {'class9':true,'class10':false} } } }) </script> </body>
<body> <div id="app"> <div :style="[redFont, bFont]">数组语法</div> <div :style="{color:'blue',fontSize:'10px'}">对象语法</div> <div :style="{fontSize:curSize}">对象语法2</div> <div :style="getObjStyle()">对象语法3</div> </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { redFont: { color: 'red' }, bFont: { fontSize: "20px" }, curSize:"15px" }, methods: { getObjStyle: function() { return { color: 'yellow', fontSize: '40px' } } } }) </script> </body>
<head> <meta charset="utf-8"> <title></title> <style type="text/css"> .active { color: red; } </style> </head> <body> <div id="app"> <ul> <li v-on:click="changeColor(index)" v-bind:class="{active:i==index}" v-for="(item,index) in movies">{{index}}--{{item}}</li> </ul> </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { movies: ["阿甘正传", "教父", "最后一课"], i: false }, methods: { changeColor(index) { this.i = index } } }) </script> </body>
3、计算属性 computed
<body> <div id="app"> {{fullName}}:{{TotalPrice}} </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { firstName: "张", lastName: "三", books: [{ id: "001", name: "深入理解Python", price: 100, count: 3 }, { id: "002", name: "深入理解Vue", price: 200, count: 2 } ] }, computed: { fullName: function() { return this.firstName + this.lastName }, TotalPrice: function() { return this.books.reduce((total, bo) => { return total + bo.price * bo.count }, 0) } } }) </script> </body>
<div id="app9"> <input v-model="num1" /> + <input v-model="num2" /> = {{sum}} </div> <script> new Vue({ el: "#app9", data: { num1: 0, num2: 0, }, computed: { sum:function() { return parseInt(this.num1) + parseInt(this.num2); } }, } ) </script>
<body> <div id="app"> {{fullName}} </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { firstName: "张", lastName: "三" }, computed: { fullName: { set(str) { const arryStr = str.split(" ") this.firstName = arryStr[0] this.lastName = arryStr[1] }, get() { return this.firstName + this.lastName } } } }) </script> </body>
<body> <div id="app"> {{fullName}} {{fullName}} {{fullName}} {{fullName}} {{getFullName()}} {{getFullName()}} {{getFullName()}} {{getFullName()}} </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { firstName: "张", lastName: "三" }, computed: { fullName() { console.log("computed,调用次数") return this.firstName + this.lastName } }, methods:{ getFullName(){ console.log("methods,调用次数") return this.firstName + this.lastName } } }) </script> </body>
computed与methods的区别
- computed是属性调用,而methods是函数调用
- computed带有缓存功能,而methods不是
- computed定义的方法我们是以属性访问的形式调用的,{{computedTest}}
- 但是methods定义的方法,我们必须要加上()来调用,如{{methodTest()}}
4、事件监听 v-on
<body> <div id="app" @click="divClick"> divClick <button type="button" v-on:click="sayHello">sayHello</button> <button type="button" @click="sayHi('张三')">sayHi</button> <button type="button" @click.stop="btnClick">防止冒泡</button> </div> <script src="js/vue.js" type="text/javascript"></script> <script> let app = new Vue({ el: "#app", data: { }, methods: { sayHello() { console.log("Hello,World!"); }, sayHi(strName) { console.log("Hello," + strName + "!"); }, divClick(){ console.log("hello,Div"); }, btnClick(){ console.log("hello,Btn"); } } }) </script> </body>
5、分支判断
<div id="app5"> <ul> <li v-if="score>80">优秀</li> <li v-else-if="score>60" >及格</li> <li v-else="score">补考</li> </ul> </div> <script> new Vue({ el: "#app5", data: { score:16, } } ) </script>
<body> <div id="app"> <ul> <li v-if="score>80">优秀</li> <li v-show="score>80">优秀</li> <li v-show="score<60">不及格</li> </ul> </div> <script src="js/vue.js" type="text/javascript"></script> <script> new Vue({ el: "#app", data: { score: 16, } } ) </script> </body>
6、循环
<div id="app"> <ul> <li v-for="item in movies">{{item}}</li> </ul> <ul> <li v-for="(item,index) in movies">{{index+1}}----{{item}}</li> </ul> <br> <!-- 循环obj对象 --> <ul> <li v-for="item in objMovies">{{item}}</li> </ul> <ul> <li v-for="(value,key) in objMovies">{{key}}---{{value}}</li> </ul> <ul> <li v-for="(value,key,index) in objMovies">{{index+1}}---{{key}}---{{value}}</li> </ul> <ul> <li v-for="(value) in objMovies" :key="value"> {{value}}</li> </ul> </div> <script src="js/vue.js" type="text/javascript"></script> <script> new Vue({ el: "#app", data: { movies: ["阿甘正传", "教父", "最后一课"], objMovies: { name: "狮子王", price: "200", addr: "国家大剧院" }, }, }) </script>
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 <link rel="stylesheet" href="style.css"> 8 </head> 9 10 <body> 11 <div id="app"> 12 <div v-if="books.length"> 13 <table> 14 <thead> 15 <tr> 16 <th>编号</th> 17 <th>名称</th> 18 <th>出版日期</th> 19 <th>价格</th> 20 <th>数量</th> 21 <th>操作</th> 22 </tr> 23 </thead> 24 <tbody> 25 <tr v-for="(item,index) in books"> 26 <td>{{item.id}}</td> 27 <td>{{item.name}}</td> 28 <td>{{item.date}}</td> 29 <td>{{item.price|showPrice}}</td> 30 <td><button @click="sub(item)" :disabled="item.count<=1">-</button>{{item.count}}<button @click="add(item)">+</button></td> 31 <td><button @click="removeHandle(index)">删除</button></td> 32 </tr> 33 </tbody> 34 </table> 35 <h2>总价格{{totalPrice|showPrice}}</h2> 36 </div> 37 <h2 v-else>购物车为空</h2> 38 </div> 39 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.13/dist/vue.js"></script> 40 <script src="main.js"></script> 41 </body> 42 43 </html>
const app = new Vue({ el: "#app", data: { books: [ { id: 1, name: "《算法导论》", date: "2020-01-01", price: 85.0, count: 1 }, { id: 2, name: "《流畅的python》", date: "2022-11-01", price: 105.0, count: 1 }, { id: 1, name: "《Java入门》", date: "2021-05-03", price: 95.0, count: 1 }, { id: 1, name: "《VUE》", date: "2022-11-01", price: 55.0, count: 1 } ], }, methods: { removeHandle(index) { this.books.splice(index, 1) }, add(item){ item.count ++ }, sub(item){ item.count -- } }, computed:{ totalPrice(){ let total_price =0 for (let book of this.books){ total_price += book.price * book.count } return total_price } }, filters: { showPrice(price) { return "¥" + price.toFixed(2) } } })
table { border: 1px solid #e9e9e9; border-collapse: collapse; border-spacing: 0; } th, td { padding: 8px 16px; border: 1px solid #e9e9e9; text-align: left; } th { background-color: #f7f7f7; color: #5c6b77; font-weight: 600; }
7、v-mode 双向绑定
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 <link rel="stylesheet" href="style.css"> 8 </head> 9 10 <body> 11 <div id="app"> 12 <h3>请选择您喜欢吃水果,如果下拉列表中不存在,可以手动输入</h3> 13 14 <select id="fu" v-model="fruit" @change="chooseCore"> 15 <option v-for="item in fruits">{{item}}</option> 16 </select> 17 </br> 18 <input v-model="fruit"> 19 </br> 20 您选择的水果是,{{fruit}} 21 </div> 22 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.13/dist/vue.js"></script> 23 <script> 24 const app = new Vue({ 25 el: "#app", 26 data: { 27 fruits: ["苹果", "香蕉", "榴莲", "葡萄"], 28 fruit: "苹果" 29 }, 30 methods: { 31 chooseCore() { 32 this.fruits = [] 33 } 34 } 35 }) 36 37 </script> 38 </body> 39 40 </html>
修饰符(延时请求、数字校验、去左右空格)
<div id="app9"> <input v-model.number.trim.lazy="num1" /> + <input v-model.number.trim.lazy="num2" /> = {{sum}} </div> <script> new Vue({ el: "#app9", data: { num1: 0, num2: 0, }, computed: { sum:function() { return this.num1 + this.num2 ; } }, } )
</div> <div id="app10"> <div ref="myRef">星</div>星 <button v-on:click="changeColor2">变色</button> </div> <script> new Vue({ el: "#app10", data: { isActive: true, }, methods: { changeColor2: function() { this.$refs.myRef.style.color = "red" } } } ) <script>