vue2基础
一、介绍
本文是以前学习 vue2
时整理的,对于目前的 vue3
有些过时。
专注后端,前端只作为使用学习。
二、 基础
1)数据绑定
代码语言:javascript复制<!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">
<!-- 插值表达式 -->
<!-- 将data中的数据渲染至页面 -->
<h1>{{ msg }}</h1>
</div>
<script>
new Vue({
// element,绑定页面的原始
el: "#app",
// data,保存一个对象数据
data: {
msg: "数据绑定"
}
});
</script>
</body>
</html>
2)指令
2.1、v-html
- 设置标签的内容,同数据绑定一致
- 设置标签内的html代码片段
<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代码片段
<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
- 绑定事件:如鼠标点击事件(v-on:click)等
- 简写@:如鼠标点击事件(@click)等
- 基本绑定
<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:方法集合对象
methods: {
submit: function(){
alert("模拟登录");
},
reset: function(){
alert("模拟重置");
}
}
})
</script>
- 访问Vue中data变量
- 通过this指向当前vue,访问data内数据不需要加data(this.data.msg是错误的)
<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
- 解决插值闪烁的问题
代码语言:javascript复制插值闪烁:页面在刷新加载的时候,会有一瞬间看到插值表达式的现象
<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
- 控制元素的显示和隐藏
<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>
小案例:通过点击按钮控制元素的显示和隐藏 <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
- 控制元素的显示和销毁状态
代码语言:javascript复制v-if和v-show的区别 v-if:元素是创建和销毁两个状态,对性能要求比较大 v-show:元素是通过css样式来控制元素的显示的隐藏,适用于频繁的切换场景
<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
- 绑定属性:如绑定img的src属性(v-bind:src)等
- 简写使用冒号(英文):如绑定img的src属性(:src)等
<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=https://img.yuanmabao.com/zijie/pic/2023/10/18/1mlvozd1qav.jpeg",
title: "半月喜欢的美女"
},
})
</script>
- 动态设置行内样式
<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类名
<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">
<!-- 通过data数据绑定,来给定类名 -->
<div v-bind:class="className">我是半月</div>
<hr>
<!-- 使用对象,给定类名,true/false表示是否启用类名 -->
<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>
小案例:点击按钮改变样式 <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
- 循环输出对象或数组
<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和元素之间有一一对应的关系,来完成这些状态的正常 <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
- 实现双向数据绑定
<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>
- 使用v-model获取表单的值
<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、自定义指令
- 全局指令
<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>
- 私有指令
<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、按键修饰符
- 键盘按键的限制修饰符
回车:.enter
Tab键:.tab
Esc键:.esc
空格键:.space
↑键:.up
↓键:.down
←键:.left
→键:.right
删除(退格)键:.delete
代码语言:javascript复制<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、事件修饰符
代码语言:javascript复制.stop:阻止事件冒泡
.prevent:阻止默认行为
.once:限定事件只执行一次
使用方法:@事件名:修饰符,例如点击事件(@click.stop)
.stop修饰符
代码语言:javascript复制<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修饰符
代码语言:javascript复制<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修饰符
代码语言:javascript复制<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)过滤器
- 作用:在数据渲染之前,进行一些函数操作,从而达到数据的控制效果(常用于日期的格式化)
- 语法支持:插值表达式和v-bind指令
- 插值:
{{ data | filter }}
- v-bind:
<div v-bind:id=" data | filter "></div>
- 插值:
- 分类:作用域可分为全局过滤器和局部过滤器,通过参数可分为有参无参过滤器
- 有参:
{{ data | filter(str01, str02) }}
- 无参:
{{ data | filter }}
- 有参:
- 注意事项:
- 过滤器必须要有返回值
- 全局过滤器必须写在vue实例的前边
- 多参传递时,自定义参数直接从第二个开始传递(参考4.2私有过滤器)
- 当全局和局部的过滤器命名冲突时,会默认使用局部过滤器
4.1、全局过滤器
代码语言:javascript复制<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实例之前
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、局部过滤器
代码语言:javascript复制<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)计算属性
- 作用:通过vue实例中已存在的属性来计算出一个不存在的属性
- 注意事项:
- 计算属性同data中定义的属性一致,可以在插值表达式或v-model中使用
- data定义的属性可读可写,而计算属性不能直接修改,仅作读取展示
- 计算属性定义时为函数方法,且必须有返回值
<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监听器
- 作用:监听data中定义的属性,当属性发生变化的时候,可以自动做一些处理
- 注意事项:
- 在watch中定义函数方法,注意函数名与data中要监听的属性名要一致
<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、匿名插槽
代码语言:javascript复制<div id="app">
<h1>{{ title }}</h1>
<hr>
<!-- 使用组件时,将html元素或文本内容写入组件 -->
<coma>
<img src="https://img.yuanmabao.com/zijie/pic/2023/10/18/perrckedhst.html"/><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、具名插槽
- 区别:不同于匿名插槽,具名插槽允许有多个
slot
标签
<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、作用域插槽
- 作用:当子组件有数据要交给父组件进行渲染时,可以使用作用域插槽
<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>
三、最后
我是半月,你我一同共勉!