您现在的位置是:首页 >技术交流 >前端小记——Vue3网站首页技术交流
前端小记——Vue3
目录
Vue介绍
Vue是一套用于构建用户界面的渐进式JavaScript框架,本质就是一个JavaScript库,Vue 的核心
库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
渐进式框架:表示我们可以在项目中一点点来引入和使用Vue,而不一定需要全部使用Vue来开发
整个项目。
Vue安装使用
1.通过CDN方式引入
<script src="https://unpkg.com/vue@next"></script>
2.下载引入
下载vue的源码,另存为新的文件,如vue.js,通过script标签引入。
<script src="./js/vue.js"></script>
Vue入门案列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入vue-->
<script src="js/vue.js"></script>
</head>
<body>
<!-- vue 控制的区域-->
<div id="box">
<h1>{{msg}}</h1> //插值表达式
<h2>{{num}}</h2>
</div>
<script>
//创建vue实例
const app = Vue.createApp({
//vue管理的数据,data选项的值是一个函数
data:function() {
return {
msg:"Hello Vue",
num:0
}
}
})
//挂载模板
var vm=app.mount('#box');
</script>
</body>
</html>
插值表达式
插值表达式支持运算符,三元表达式,调用方法,但是不建议这么做
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
<!--插值表达式-->
<h1> {{msg}}</h1>
<!-- 插值表达式,支持运算符 -->
<h1> {{num + 10 * 2}}</h1>
<h1> {{num + 10 * 2 > 50}}</h1>
<!-- 支持三元表达式-->
<h1> {{num + 10 * 2 > 50 ? '大于' : '不大于'}}</h1>
<!--支持调用方法-->
<h1> {{msg.split('').reverse().join('')}}</h1>
<!-- 虽说,插值表达式,支持运算符,三元表达式,调用方法,但是我们不建议这么做,因为可读性太差 -->
<!--我们一般只是把vue管理的数据展示出来,不需要对数据再次做运算方面的处理-->
</div>
<script>
Vue.createApp({
data: function () {
return {
msg: "Hello World!",
num: 1
}
}
}).mount("#box")
</script>
</body>
</html>
我们一般只是把vue管理的数据展示出来,不建议进行运算和调用函数
Vue指令
vue提供的行间属性,能够完成一些功能操作
v-test
只输出文本
v-html
输出html,就是带标签属性的文本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.global.js"></script>
</head>
<body>
<div id="box">
{{msg}}
<h1 v-text="content"></h1>
<span v-html="content2"></span>
</div>
</body>
<script>
Vue.createApp({
data: function () {
return {
msg:"Hello Vue",
content:"为什么",
content2:"<b style='background: red;color: white'>为什么要这么对我</b>"
}
}
}).mount("#box")
</script>
</html>
v-bind
绑定html自带的属性
例如
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.global.js"></script>
</head>
<body>
<div id="box">
<!-- <a href="http://www.163.com">进入网易</a> //正常进入网站-->
<!-- <a href="url">进入网易</a> //若是这种情况,'url'只是字符串,进入不了网站-->
<a v-bind:href="url">进入网易</a> //在属性前加上v-bind: 简写 :
<a :href="url">进入网易</a>
</div>
</body>
<script>
Vue.createApp({
data: function () {
return {
url: 'http://www.163.com'
}
}
}).mount("#box")
</script>
</html>
v-bind 简写方式为 :
v-on
事件绑定
v-on: 简写 @
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
<!-- v-on 绑定事件 -->
<button v-on:click="show()">一个按钮</button> 函数括号可不写
<button v-on:click="show2(num,'hello')">一个按钮</button>
<!-- v-on 简写-->
<button @click="show3()">一个按钮</button>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
msg: 'Hello world!',
num: 100
}
},
//定义函数的选项
methods: {
show: function () {
//this 指向vue的组件实例
alert(this.msg);
},
show2(n, str) {
alert(this.num)
alert(n);
alert(str);
},
show3(n, str) {
alert(this.num)
}
}
})
app.mount('#box')
</script>
</body>
</html>
案例:计数器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.global.js"></script>
</head>
<body>
<div id="box">
当前计数 {{msg}}
<br>
<button @click="add">+1</button>
<button @click="jian">-1</button>
</div>
</body>
<script>
Vue.createApp({
data: function () {
return {
msg:0,
}
},
methods : {
add :function() {
this.msg++;
},
jian:function() {
this.msg--;
}
}
}).mount("#box")
</script>
</html>
v-model
双向绑定
视图和数据双向绑定,数据变化,视图就会变化;视图变化,数据变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
<input type="text" v-model="num">
<input type="text" :value="num">
{{num}}
<button @click="add()">改变数据</button>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
num:1,
}
},
//定义函数的选项
methods: {
add(){
this.num++;
}
}
})
app.mount('#box')
</script>
</body>
</html>
v-cloak
用于隐藏尚未完成的DOM模板
当使用直接在 DOM 中书写的模板时,可能会出现一种叫做“未编译模板闪现”的情况:用户可能先
看到的是还没编译完成的双大括号标签,直到挂载的组件将它们替换为实际渲染的内容。
v-cloak
会保留在所绑定的元素上,直到相关组件实例被挂载后才移除。配合像 [v-cloak] {
display: none }
这样的 CSS 规则,它可以在组件编译完毕前隐藏原始模板。
v-show
根据表达式的真假,来设置元素的可见性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
#d1 {
height: 200px;
width: 200px;
background-color: red;
}
</style>
</head>
<body>
<div id="box">
<!-- v-show true显示,false 隐藏 切换 display-->
<div id="d1" v-show="flag">
</div>
<button @click="flag=true">显示</button>
<button @click="flag=false">隐藏</button>
<button @click="flag=!flag">开关</button>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
msg: 'Hello world!',
flag:true
}
},
methods : {
}
})
app.mount('#box')
</script>
</body>
</html>
v-if
根据表达式的真假,来条件性地渲染模板元素
v-if元素被触发,其组件会被销毁和重建,如果初始条件为假,其内容不会被渲染,且组件不会被
创建,因此当需要频繁切换时,使用v-show,反之使用v-if。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
#d1 {
height: 200px;
width: 200px;
background-color: red;
}
</style>
</head>
<body>
<div id="box">
<!-- v-if true显示,false 隐藏 通过创建dom元素和销毁dom元素来实现的。-->
<div id="d1" v-if="flag">
</div>
<button @click="flag=true">显示</button>
<button @click="flag=false">隐藏</button>
<button @click="flag=!flag">开关</button>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
msg: 'Hello world!',
flag:true
}
},
methods : {
}
})
app.mount('#box')
</script>
<!-- v-if vs v-show
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。-->
</body>
</html>
v-else
v-if的另一种情况,可以从if--else语句理解
v-else-if
表示v-if的“else if 块”。可以进行链式调用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
<input placeholder="请输入成绩0-100" type="text" v-model="score">
<h1 v-if="score>=90&&score<=99">优秀</h1>
<h1 v-else-if="score>=80&&score<90">良好</h1>
<h1 v-else-if="score>=70&&score<80">中等</h1>
<h1 v-else-if="score>=60&&score<70">很差</h1>
<h1 v-else-if="score>=0&&score<60">不及格</h1>
<h1 v-else-if="score===100">满分</h1>
<h1 v-else>成绩不合法</h1>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
msg: 'Hello world!',
score: 0
}
}
})
app.mount('#box')
</script>
</body>
</html>
v-for
循环渲染,格式:(//键,值,索引) in 数组/集合
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为
每项提供一个唯一 key
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
<ul>
<li v-for="(element,index) in arr" :key="index">
参数1-数组中的元素{{element}}参数2-元素的索引{{index}}
</li>
</ul>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
msg: 'Hello world!',
arr:[10,20,30,40,50,60,70,80,90,100]
}
}
})
app.mount('#box')
</script>
</body>
</html>
计算属性
为了避免在模板中写太多逻辑,使用计算属性computed
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
<input type="text" v-model="msg">
<!--我们在插值表达式中,调用方法,完成了这个需求,但是不建议这么做-->
<h1>{{msg.split('').reverse().join('')}}</h1>
<!--所以,对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性。-->
<h1>{{newStr}}</h1>
<h1>{{reverseStr()}}</h1>
<hr>
<!-- 计算属性有缓存,-->
<h1>{{getTime}}</h1>
<h1>{{getTime}}</h1>
<h1>{{getTime}}</h1>
<hr>
<!-- 没有缓存,调用一次执行一次-->
<h1>{{getNowTime()}}</h1>
<h1>{{getNowTime()}}</h1>
<h1>{{getNowTime()}}</h1>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
msg: 'HelloWord',
}
},
//所以,对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性。
computed: {
newStr: function () {
console.log("计算属性的函数调用了")
//1.在第一次初始化的时候,会调用一次
//2.当你计算属性的这个函数中,使用的别的属性,一变化,这个计算属性的函数就会调用
return this.msg.split('').reverse().join('');
},
getTime() {
console.log("getTime计算属性调用了")
return Date.now();
}
},
methods: {
reverseStr() {
return this.msg.split('').reverse().join('');
},
getNowTime() {
console.log("getNowTime方法调用了")
return Date.now();
}
}
})
app.mount('#box')
</script>
</body>
</html>
计算属性完整写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
姓氏:
<input type="text" v-model="xing">
<br>
名字:
<input type="text" v-model="ming"/>
<br>
全名:
<input type="text" v-model="fullname"/>
<br>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
xing: '',
ming: '',
msg: 'HelloWord',
}
},
//所以,对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性。
computed: {
fullname:{
//返回计算属性的盒子
get: function () {
//1.第一次初始化会调用一次
//2.计算属性的函数中,依赖的其他属性一变化,这个计算属性的函数就会调用。
return this.xing.concat(' ').concat(this.ming);
},
//监听计算属性 fullname 的变化
//set方法,监听,这个fullName的变化,只要fullName的值变化了,这个set方法就会调用
//fullName变化之后的值,会作为参数传过来
set: function (newValue) {
console.log(newValue);
const names = newValue.split(' ')
this.xing = names[0]
this.ming = names[names.length - 1]
}
}
}
})
app.mount('#box')
</script>
</body>
</html>
属性侦听
属性侦听的是属性值,当定义的值发生变化时,会执行相应的函数
计算属性不能执行异步任务,异步任务用属性侦听做
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
姓氏:
<input type="text" v-model="xing">
<br>
名字:
<input type="text" v-model="ming"/>
<br>
全名:
<input type="text" v-model="fullname"/>
<br>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
xing:'',
ming:'',
fullname: '',
}
},
//属性的侦听
watch:{
//参1:新值 参数2:旧值
xing:function(newValue,oldValue) {
//Ajax
console.log("新的值:"+newValue+" 旧值:"+oldValue)
this.fullname = newValue;
},
ming:function (newValue,oldValue){
console.log("新的值:"+newValue+" 旧值:"+oldValue)
this.fullname = this.xing.concat(' ').concat(newValue);
}
}
})
app.mount('#box')
</script>
</body>
</html>
class属性的绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
.aa {
color: red;
}
.bb {
background-color: yellow;
}
</style>
</head>
<body>
<div id="box">
<h1 class="aa">ABCDEF</h1>
<h1 :class="'aa'">ABCDEF</h1>
<h1 :class="['aa','bb']">ABCDEF</h1>
<!-- 这种是常用的语法 false 这个class选择器不生效,true class选择器生效-->
<h1 :class="{'aa':false,'bb':true}">EEEEEEE</h1>
<!-- 这种是常用的语法-->
<h1 :class="{'aa':f1,'bb':f2}">EEEEEEE</h1>
</div>
<script>
var obj;
Vue.createApp({
data: function () {
return {
msg: 'hello',
f1:true,
f2:true,
}
}
}).mount('#box');
</script>
</body>
</html>
style属性的绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
.aa {
color: red;
background-color: yellow;
}
.bb {
color: green;
background-color: palevioletred;
}
</style>
</head>
<body>
<div id="box">
<h1 :style='{"color":mycolor,"background-color":bg}' @click="swithStyle()">ABCEFDFDFFFFF22222</h1>
</div>
<script>
var obj;
Vue.createApp({
data: function () {
return {
mycolor: 'red',
bg: 'yellow',
flag:true
}
},
methods: {
swithStyle() {
if (this.flag){
this.mycolor = 'green';
this.bg = 'pink';
}else{
this.mycolor = 'red';
this.bg = 'yellow';
}
this.flag = !this.flag;
}
}
}).mount('#box');
</script>
</body>
</html>
表单数据收集
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="box">
<form action="123.html" method="get" @submit.prevent="tijiao()">
用户名:
<input maxlength="10" minlength="3" name="username" placeholder="请输入用户名" required="required" type="text"
v-model.trim="username" value="">
<br>
密码:
<!-- oninput onblur -->
<input name="password" placeholder="请输入密码" type="password" v-model.lazy="password" value="">
{{password}}
<br>
<br>
性别:
<input id="nan" name="sex" type="radio" v-model="sex" value="1">
<label for="nan">男</label>
<input id="nv" name="sex" type="radio" v-model="sex" value="0">
<label for="nv">女</label>
<br>
爱好:
<input id="zq" name="hobby" type="checkbox" v-model="hobby" value="zq"/>
<label for="zq">足球</label>
<input name="hobby" type="checkbox" v-model="hobby" value="lq"/>
蓝球
<input name="hobby" type="checkbox" v-model="hobby" value="pq"/>
排球
<br>
学历:
<select name="xueli" v-model="xueli">
<option value="">请选择你的学历</option>
<option value="xx">小学</option>
<option value="zx">中学</option>
<option value="dx">大学</option>
</select>
<br>
生日:
<input name="birthday" type="date" v-model="birthday"/>
<br>
你有几个女朋友:
<input name="shuliang" type="text" v-model.number="shuliang" />
<br>
<br>
<input type="submit" value="提交">
<input type="reset" value="重置"/>
</form>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
username: '张三',
password: '',
sex: '0',
hobby: ['zq', 'lq'],
xueli: 'zx',
birthday: '2022-10-10',
shuliang: 10
}
},
methods: {
tijiao() {
var jsonObj = {
"username": this.username,
"password": this.password,
"sex": this.sex,
"hobby": this.hobby,
"xueli": this.xueli,
"birthday":this.birthday,
"shuliang":this.shuliang
}
var jsonString = JSON.stringify(jsonObj);
alert("异步提交:"+jsonString);
}
}
})
app.mount('#box')
</script>
</body>
</html>
事件绑定和修饰符
$event
例:@click="show($event)"
.prevent 阻止元素的默认行为
.stop 阻止冒泡
.once 事件只执行一次
@keypress/down.enter="show()" 键盘按下
@mousedown.left="show" 鼠标按下
鼠标按钮修饰符
.left
.right
.middle
按键别名:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
Vue之Axios发送Ajax请求
Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。
get方法
axios
.get('https://api.oioweb.cn/api/common/teladress',{
params: { //参数
mobile:this.phone
}
})
.then((res)=>{
//箭头函数,会找他上层作用域里面的this
this.textData =res.data.result.name;
})
.catch(function (error) { // 请求失败处理
console.log(error);
});
传递配置
axios({
method:'get',
url:'https://api.oioweb.cn/api/common/teladress',
params: {
mobile:'13259158562'
},
timeout:3000,
responseType: 'json'
}).then((res)=>{
//箭头函数,会找他上层作用域里面的this
this.textData =res.data.result.name;
}).catch(function (error) { // 请求失败处理
console.log(error);
});