vue2基础
一、介绍
本文是以前学习 vue2
时整理的,对于目前的 vue3
有些过时。
专注后端,前端只作为使用学习。
二、 基础
1)数据绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>VUE数据绑定</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>{{ msg }}</h1> </div> <script> new Vue({ el: "#app", data: { msg: "数据绑定" } }); </script> </body> </html>
|
2)指令
2.1、v-html
-
设置标签的内容,同数据绑定一致
-
设置标签内的html代码片段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <div id="app"> <h1 v-html="title"></h1> <hr> <div v-html="msg"></div> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { title: "v-html的作用", msg: "<h3>html代码片段</h3>" } }) </script>
|
2.2、v-text
-
设置标签的内容,同数据绑定一致
-
会原样渲染data,不会解析html代码片段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <div id="app"> <h1 v-text="title"></h1> <hr> <div v-text="msg"></div> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { title: "v-text标题", msg: "<h3>html代码片段</h3>" } }) </script>
|
2.3、v-on
-
基本绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <div id="app"> <button v-on:click="submit()">{{ submitData }}</button> <button @click="reset()">{{ resetData }}</button> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { submitData: "登录", resetData: "重置" }, methods: { submit: function(){ alert("模拟登录"); }, reset: function(){ alert("模拟重置"); } } }) </script>
|
-
访问Vue中data变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <div id="app"> <button v-on:click="comeOn()">点击</button> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: "我叫半月" }, methods: { comeOn: function(){ alert(this.msg); } } }) </script>
|
2.4、v-cloak
插值闪烁:页面在刷新加载的时候,会有一瞬间看到插值表达式的现象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <style> [v-cloak]{ display: none; } </style>
<div id="app"> <h1 v-cloak>{{ msg }}</h1> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: "我叫半月" } }) </script>
|
2.5、v-show
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <div id="app"> <h1 v-show="isShow">{{ msg }}</h1> <hr> <h1 v-show="false">{{ msg }}</h1> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: "我叫半月", isShow: true } }) </script>
|
小案例:通过点击按钮控制元素的显示和隐藏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <div id="app"> <button @click="showChange()">{{ text }}</button> <hr> <h1 v-show="isShow">{{ msg }}</h1> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: "我叫半月", isShow: true, text: "隐藏" }, methods: { showChange() { this.isShow = !this.isShow if (this.isShow) { this.text = "隐藏" } else { this.text = "显示" } } } }) </script>
|
2.6、v-if
v-if和v-show的区别
v-if:元素是创建和销毁两个状态,对性能要求比较大
v-show:元素是通过css样式来控制元素的显示的隐藏,适用于频繁的切换场景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <div id="app"> <button @click="showChange()">{{ text }}</button> <hr> <h1 v-if="isShow">{{ msg }}</h1> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: "我叫半月", isShow: true, text: "隐藏" }, methods: { showChange() { this.isShow = !this.isShow if (this.isShow) { this.text = "隐藏" } else { this.text = "显示" } } } }) </script>
|
2.7、v-bind
1 2 3 4 5 6 7 8 9 10 11 12 13
| <div id="app"> <img v-bind:src="url" :title="title"> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { url: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1593073021353&di=f4a4c47914b1cda5ab582304fb7642c3&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20180424%2F7b8ae3018fd641bc8a61b3ac76f536c4.jpeg", title: "半月喜欢的美女" }, }) </script>
|
-
动态设置行内样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div id="app"> <div :style="styleObj"></div> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { styleObj: { border: "1px solid red", width: "100px", height: "100px", } }, }) </script>
|
-
设置class类名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <style> .div{ width: 200px; height: 200px; border: 1px red solid; } .font{ color: red; text-align: center; line-height: 200px; } .back{ background-color: rosybrown; } </style> <div id="app"> <div v-bind:class="className">我是半月</div> <hr> <div :class="{ div: true, font: isFont, back: false }">我是半月</div> <hr> <div :class="['div', isFont==true? 'font': '', 'back']"> 我是半月 </div> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { className: "div", isFont: false }, }) </script>
|
小案例:点击按钮改变样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <style> .div{ width: 200px; height: 200px; border: 1px red solid; } .font{ color: red; text-align: center; line-height: 200px; } .back{ background-color: rosybrown; } </style> <div id="app"> <button @click="change01()">设置盒子边框</button> <button @click="change02()">设置字体样式</button> <button @click="change03()">设置背景颜色</button> <hr> <div v-bind:class="{div: isDiv, font: isFont, back: isBack }">我是半月</div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { isDiv: false, isFont: false, isBack: false, }, methods: { change01(){ this.isDiv = !this.isDiv; }, change02(){ this.isFont = !this.isFont; }, change03(){ this.isBack = !this.isBack; } } }) </script>
|
2.8、v-for
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <div id="app"> <ul> <li v-for="item in msg"> {{item}} </li> </ul> <hr> <ul> <li v-for=" (item, index) in msg"> {{index}}:{{item}} </li> </ul> <hr> <h4 v-for="(value, key) in person"> {{key}}:{{value}} </h4> <hr> <span v-for=" num in 5 ">{{num}},</span> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: ["香蕉", "苹果", "柚子", "雪梨"], person: { name: "banmoon", age: 18, sex: "男" } }, }) </script>
|
说明v-for中key的作用说明
不加key的问题:某些遍历的元素有自己的状态,在修改数组对象时,这些状态可能会出现混乱的情况
给定唯一key值:将保证key和元素之间有一一对应的关系,来完成这些状态的正常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <div id="app"> <input type="text" name="" id="" placeholder="请输入" ref="text"> <input type="button" value="添加" @click="add"> <hr> <ul> <li v-for="item in msg" v-bind:key="item.id"> <label for=""> <input type="checkbox" name="" id=""> {{item.name}} </label> </li> </ul> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: [ {id: 1, name: "香蕉"}, {id: 2, name: "苹果"}, {id: 3, name: "柚子"}, {id: 4, name: "雪梨"}, ] }, methods: { add(){ let value = this.$refs.text.value; this.msg.unshift({ id: this.msg.length+1, name: value }); } }, }) </script>
|
2.9、v-model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <div id="app"> <h1>{{ value }}</h1> <hr> <input type="text" name="" id="" v-model="value"> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { value: "我是半月" }, }) </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <div id="app"> 账号:<input type="text" name="" id="" v-model="username"><br> 密码:<input type="password" name="" id="" v-model="password"><br> <input type="button" value="登录" @click="submit"> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { value: "我是半月", username: "", password: "" }, methods: { submit(){ alert("账号:"+this.username+",密码:"+this.password); } } }) </script>
|
2.10、自定义指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <div id="app" class="container"> <h1 v-color="color">{{ title }}</h1> <button @click="changeColor('red')">改变为红色</button> <button @click="changeColor('black')">改变为黑色</button> </div>
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script> Vue.directive("color", (el, binding) => { console.log(el, binding); el.style.color = binding.value; }) new Vue({ el: "#app", data: { title: "directive自定义组件", color: "black" }, methods: { changeColor(val){ this.color = val } } }) </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <div id="app" class="container"> <h1 v-color="color">{{ title }}</h1> <button @click="changeColor('red')">改变为红色</button> <button @click="changeColor('black')">改变为黑色</button> </div>
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { title: "directive自定义组件", color: "black" }, methods: { changeColor(val){ this.color = val } }, directives: { color(el, binding){ console.log(el, binding); el.style.color = binding.value; } } }) </script>
|
3)修饰符
3.1、按键修饰符
1 2 3 4 5 6 7 8 9
| 回车:.enter Tab键:.tab Esc键:.esc 空格键:.space ↑键:.up ↓键:.down ←键:.left →键:.right 删除(退格)键:.delete
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <div id="app"> <input type="text" name="" id="" @keydown.enter="keyDown"> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { value: "我是半月", username: "", password: "" }, methods: { keyDown(){ alert("已经点击"); } } }) </script>
|
3.2、事件修饰符
1 2 3 4 5
| .stop:阻止事件冒泡 .prevent:阻止默认行为 .once:限定事件只执行一次
使用方法:@事件名:修饰符,例如点击事件(@click.stop)
|
-
.stop修饰符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <style> .fa{ width: 200px; height: 200px; background: skyblue; } .sub{ width: 100px; height: 100px; background: greenyellow; } </style>
<div id="app"> <div class="fa" @click="click1"> <div class="sub" @click.stop="click2"></div> </div> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: {
}, methods: { click1(){ alert("已经点击1"); }, click2(){ alert("已经点击2"); } } }) </script>
|
-
.prevent修饰符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <div id="app"> <form action=""> <input type="text" name="" id=""> <button @click.prevent="submit">提交</button> </form> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: {
}, methods: { submit(){ alert("模拟提交") } } }) </script>
|
-
.once修饰符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <div id="app"> <button @click.once="cilck01">点击</button> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: {
}, methods: { cilck01(){ alert("点击") } } }) </script>
|
4)过滤器
4.1、全局过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <div id="app"> <h1>{{ datatime|dateFormat }}</h1> <hr> <button @click="clickMe">刷新</button> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> Vue.filter("dateFormat", (input) => { let year = input.getFullYear(); let month = input.getMonth()+1; let day = input.getDate(); let hour = input.getHours(); let min = input.getMinutes(); let ss = input.getSeconds(); return year+"-"+month+"-"+day+" "+hour+":"+min+":"+ss; });
new Vue({ el: "#app", data: { datatime: new Date() }, methods: { clickMe() { this.datatime = new Date() } } }) </script>
|
4.2、局部过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <div id="app"> <h1 :title="msg|strSub(21, '~~~')">{{ msg|strSub(10, '...') }}</h1> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: "大家好,我叫半月,来自浙江温州,目前在广州,从事IT行业,巴拉巴拉巴啦啦" }, methods: {
}, filters: { strSub(input, len, suffix){ return input.substr(0, len)+suffix; } } }) </script>
|
5)计算属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <div id="app"> {{ fullName }} <hr> 姓:<input type="text" name="" id="" v-model="firstName"><br> 名:<input type="text" name="" id="" v-model="lastName"> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { firstName: "半月", lastName: "无霜" }, computed: { fullName(){ return this.firstName+this.lastName; } } }) </script>
|
6)watch监听器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <div id="app"> {{ fullName }} <hr> 姓:<input type="text" name="" id="" v-model="firstName"><br> 名:<input type="text" name="" id="" v-model="lastName"> </div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { firstName: "半月", lastName: "无霜", fullName: "半月无霜" }, watch: { firstName(newVal, oldVal){ this.fullName = newVal+this.lastName;k }, lastName(newVal, oldVal){ this.fullName = this.firstName+newVal; } } }) </script>
|
7)插槽
7.1、匿名插槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <div id="app"> <h1>{{ title }}</h1> <hr> <coma> <img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2182074484,1483150801&fm=26&gp=0.jpg"/><br> <a href="#">跳转</a><br> <button>跳转</button> 文本也可以 </coma> </div>
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { title: "slot插槽", }, methods: { }, components: { coma: { // 定义插槽位置 template: ` <div> <h1>插槽</h1> <slot></slot> </div> ` } } }) </script>
|
7.2、具名插槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div id="app" class="container"> <h1>{{ title }}</h1> <hr> <coma> <template v-slot:header> <button class="btn btn-info">导航</button> </template> <template v-slot:footer> <button class="btn btn-success">跳转</button> </template> </coma> </div>
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { title: "slot插槽", }, methods: {
}, components: { coma: { // 定义插槽位置 template: ` <div class="panel panel-default"> <header class="panel-heading"> <slot name="header"></slot> </header> <div class="panel-body">内容</div> <footer class="panel-footer"> <slot name="footer"></slot> </footer> </div> ` } } }) </script>
|
7.3、作用域插槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div id="app" class="container"> <h1>{{ title }}</h1> <hr> <coma> <template v-slot:default="props"> <input name="test" type="checkbox" /> {{ props.item }} </template> </coma> <coma> <template v-slot:default="props"> <input name="test" type="radio" /> {{ props.item }} </template> </coma> </div>
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { title: "slot插槽", }, methods: {
}, components: { coma: { template: ` <ul class="list-group"> <li v-for="item in list" class="list-group-item"> <slot :item="item"></slot> </li> </ul> `, data(){ return{ list: ["洒", "苹果", "香蕉"] } } }, } }) </script>
|
三、最后
我是半月,你我一同共勉!