一. 概述:
Vue是一款由中国人(尤玉溪)开发的,基于js的渐进式框架,它的功能覆盖了大部分常见的需求,vue基础非常简单,容易上手.
Vue是基于mvvm模型进行数据渲染
- m model 模型 后台接口响应回来的数据
- v view 视图 html的标签部分
- mv modelview 模型视图:将m和v进行结合的机制.比如插值表达式、v-text、v-html等渲染语法。
官网:
Vue.js - 渐进式 JavaScript 框架 | Vue.js
使用场景:
- 完整的项目
- 可以在单个模块中使用vue
- 可以在html中使用vue项目
二、入门案例
1-下载vue的库(js文件)
下载地址:https://unpkg.com/vue@2.7.15/dist/vue.js
2-创建一个html文件,将vue的库引入
//通过链接的方式引入vue的库
<script src="https://unpkg.com/vue@2.7.15/dist/vue.js"></script>
//通过引入内部文件的方式引入vue的库
<script src="./JS/vue.js"></script>
3-创建一个vue实例,挂在页面的标签(往往用块级元素:常选用div)
4-将data中的数据渲染到页面部分,使用插值表达式{{ }}
实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue入门案例</title>
<!-- 用引用链接的引入vue的库 -->
<script src="https://unpkg.com/vue@2.7.15/dist/vue.js"></script>
</head>
<body>
<div id="demo">
<font color="red">{{name}}</font>
</div>
<font color="blue">{{name}}</font>
<script>
new Vue({
el:'#demo' ,
data:{
name:'zs'
}
});
</script>
</body>
</html>
运行结果:
三、页面渲染:v-text 和 v-html
v-text和插值表达式的效果相同
v-html 可以将内容中的标签进行解析,渲染到页面上
注意:
v-text和v-html都可以将内容直接当成文本进行渲染,但是当内容存在标签的时候 v-text 是不能将标签进行解析的
实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue@2.7.15/dist/vue.js"></script>
<style>
font{
margin-left: 10px;
}
</style>
</head>
<body>
<div id="demo">
用v-text引入名字: <font v-text="name"></font><br>
用v-text引入标签: <font v-text="content"></font><br>
用v-html引入名字: <font>{{name}}</font><br>
用v-html引入标签: <font v-html="content"></font><br>
</div>
<script>
new Vue({
el:'#demo',
data:{
// 名字:
'name':'张三',
// 标签
'content':'<a href="https://www.baidu.com/">点击跳转百度<a/>'
}
});
</script>
</body>
</html>
运行结果:
四、属性渲染:v-bind
格式:
<标签 v-bind :属性名 = “data中定义的key” ></标签>
实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>属性渲染</title>
<script src="https://unpkg.com/vue@2.7.15/dist/vue.js"></script>
</head>
<body>
<div id="demo">
<font v-bind:color="color" v-bind:size="size" v-bind:face="face">{{content}}</font>
</div>
<script>
new Vue({
el:'#demo',
data:{
content:'我是一个标签!!',
color:'red',
size:6,
face:'楷体'
}
})
</script>
</body>
</html>
运行结果:
五、绑定事件:v-on
格式:
<标签 v-on:事件名字 = “函数名字”></标签>
实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue@2.7.15/dist/vue.js"></script>
</head>
<body>
<div id="demo">
<font v-bind:color="color" v-bind:size="size" v-bind:face="face">{{content}}</font>
<!-- 绑定事件 -->
<button v-on:click="test1">点击变红</button>
<button v-on:click="test2">点击变蓝</button>
</div>
<script>
new Vue({
el:'#demo',
data:{
content:'我是一个标签!!',
color:'black',
size:6,
face:'楷体'
},
methods:{
test1(){
this.color='red'
},
test2(){
this.color='blue'
}
}
})
</script>
</body>
</html>
运行结果:
刚打开页面,不点击
点击“点击变红”
点击“点击变蓝”
六、v-on和v-bind的简写
v-bind的简写
原来样式:
<font v-bind:color="color" v-bind:size="size" v-bind:face="face">{{content}}</font>
简写样式:
<font :color="color" :size="size" :face="face">{{content}}</font>
v-on的简写
原来样式:
<button v-on:@click="test1">点击变红</button>
简写样式:
<button @click="test1">点击变红</button>
七、条件渲染:v-show、v-if
格式:(true:显示 false:隐藏)
<标签 v-show = "true \ false" ></标签>
<标签 v-if = "true \ false" ></标签>
取值来源于vue实例中的data即可
v-show和v-if之间的区别:
- v-show:通过控制display样式实现显隐
- v-if:通过控制标签的删除、插入实现显隐
实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./JS/vue.js"></script>
<style>
.a{
width: 100px;
height: 100px;
background: #000;
}
</style>
</head>
<body>
<div id="xx">
<h2>通过v-if控制显隐</h2>
<button @click="test" >点击显示或隐藏</button>
<font v-if="ok">{{name}}</font>
<hr>
<h2>通过v-show控制显隐</h2>
<button @click="test1" >点击显示或隐藏</button>
<div class="a" v-show="show"></div>
</div>
<script>
new Vue({
el:'#xx',
data:{
name:"张三疯",
ok:'true',
show:'true'
},
methods:{
test(){
//如果ok为true就将false赋值ok,如果ok为false,就将true赋值给ok
this.ok = !this.ok
},
test1(){
//如果show为true就将false赋值show,如果show为false,就将true赋值给show
this.show = !this.show
}
}
})
</script>
</body>
</html>
运行结果:
点击前:
点击后:
八、列表渲染:v-for
格式:
<标签名 v-for = "变量名 in 数组名"></标签名>
列表渲染就是将列表的数据渲染到页面上
实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="xx">
<h1>实现无序列表(数组)</h1>
<ul v-for="a in arr">
<li>{{a}}</li>
</ul>
<hr>
<h1>实现表格的插入(对象)</h1>
<table border="1px" >
<tr>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
<td>地址</td>
</tr>
<tr v-for="a in tab">
<td>{{a.name}}</td>
<td>{{a.age}}</td>
<td>{{a.sex}}</td>
<td>{{a.address}}</td>
</tr>
</table>
</div>
<script>
new Vue({
el:'#xx',
data:{
arr:["葡萄","香蕉","苹果","草莓","山竹"],
tab:[{
name:'张三',
age:12,
sex:'M',
address:"山东省潍坊市"
},{
name:'李四',
age:18,
sex:'M',
address:"山东省烟台市"
},{
name:'王五',
age:12,
sex:'F',
address:"山东省青岛市"
}]
}
})
</script>
</body>
</html>
运行结果:
九、绑定输入框:v-model
v-model指令可以在表单<input>、<textarea>及<select>元素上创建双向数据绑定。他会通过控件的类型自动选取正确的方法来更新元素
作用:负责监听用户的输入时间以更新数据,并对一些极端的场景进行特殊处理
格式:
<form @submit.prevent="函数"> // 表单提交会触发的函数 .prevent 的效果是阻止form表单的默认提交行为
<input type="text" v-model="user.username" >
</form>
<script>
new Vue({
el:'xxx',
data:{
user:{
username:''
}
}
})
</script>
实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="xx">
<form action="" @submit.prevent="test">
姓名:<input type="text" name="username" v-model="user.name"><br>
年龄:<input type="text" name="age" v-model="user.age"><br>
性别:<input type="radio" name="sex" value="M" v-model="user.sex">男<input type="radio" name="sex" value="F" v-model="user.sex">女<br>
地址:<input type="text" name="address" v-model="user.address"><br>
<button>点击提交</button>
</form>
<font>{{user}}</font>
</div>
<script>
new Vue({
el:'#xx',
data:{
user:{
name:"",
age:"",
sex:"",
address:""
}
},
methods:{
test(){
console.log(this.user)
}
}
})
</script>
</body>
</html>
运行结果:
输入前
输入后:
十、计算属性:computed
1) computed 是data、methods同级的参数
2) 计算属性 语法上将 就是函数
3) 计算属性 必须有返回值
4) 计算属性可以 通过插值表达式、v-text、v-html...渲染到页面上
真正渲染到页面上的是 它的返回值
5) 计算属性的返回值往往和 data 中的参数 关联
data中的参数发生改变 计算属性会自动执行 重新生成一个结果。
格式:
new Vue({
el:'' ,
data: {
priceA:'' ,
priceB:''
},
methods:{
},
computed:{
名字(){
return this.priceA+this.priceB;
}
}
})
案例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>计算属性--computed</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="xx">
商品1:<input type="text" placeholder="请输入商品的价格" v-model.number="price1"><br>
商品2:<input type="text" placeholder="请输入商品的价格" v-model.number="price2"><br>
<hr>
总价格:<font>{{test}}</font>
</div>
<script>
new Vue({
el:'#xx',
data:{
price1:'',
price2:''
},
computed:{
test(){
return this.price1+this.price2
}
}
})
</script>
</body>
</html>
运行结果:
十一、侦听器 :watch
1-和 data 、el、methods 同级
2-语法上也是函数 函数名必须是data中定义好的属性名字
3-侦听器 和 哪个属性 一样 就侦听哪个属性的变化
4-存在两个参数 第一个表示改变之后的值 第二表示改变之前的值
5-调用:插值表达式{{ }}渲染到页面上
格式:
new Vue({
el:'' ,
data: {
priceA:'' ,
priceB:''
},
methods:{
},
computed:{
名字(){
return this.priceA+this.priceB;
}
},
watch:{
priceA(a,b){
}
}
})
案例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>侦听器 watch</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="xx">
商品1:<input type="text" placeholder="请输入商品的价格" v-model.number="price1"><br>
商品2:<input type="text" placeholder="请输入商品的价格" v-model.number="price2"><br>
<hr>
总价格(computed处理):<font>{{test}}</font><br>
总价格(watch处理):<font>{{sum}}</font>
</div>
<script>
new Vue({
el:'#xx',
data:{
price1:'',
price2:'',
sum:''
},
computed:{
test(){
return this.price1+this.price2
}
},
watch:{
price1(newPrice,oldPrice){
this.sum = newPrice + this.price2
},
price2(newPrice,oldPrice){
this.sum = newPrice + this.price1
}
}
})
</script>
</body>
</html>
运行结果:
十二、vue的生命周期钩子
1) vue实例 从创建 到销毁 一共经历八个阶段
就是vue的生命周期。
2) 在vue的每一个生命周期阶段 都存在 自动执行的函数 一个8个
这8个函数就是生命周期钩子。
3) 八个声明周期钩子分别是
- beforeCreate vue实例创建之前
- created vue实例创建之后
- beforeMount 挂载之前
- mounted 挂载之后
- beforeUpdate 更新之前
- updated 更新之后
- beforeDestry 销毁之前
- destryed 销毁之后
这八个钩子 就是八个函数 位置和data、el、methods、computed、watch....都是并列的
4)刷新浏览器页面 会执行的钩子
- beforeCreate vue实例创建之前
- created vue实例创建之后
- beforeMount 挂载之前
- mounted 挂载之后
data从哪个钩子开始存在
created vue实例创建之后
从哪个构造开始 渲染了页面
mounted 挂载之后
实例代码:
<!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="./JS/vue.js"></script>
</head>
<body>
<div id="xx">
<font :size="size">{{content}}</font><br><hr>
<button @click="test1">修改内容</button>
<button @click="test2">销毁实例</button>
</div>
<script>
new Vue({
el:'#xx',
data:{
content:"一个标签!!",
size:6
},
methods:{
test1(){
this.content += "A"
},
test2(){
this.$destory()
}
},
// 哪个钩子开始 data开始存在 created
// 哪个钩子开始 页面上渲染了数据 mounted
beforeCreate() {
console.log('-- beforeCreate ~~ Vue实例创建之前--');
console.log( this.$data );
console.log( this.$el );
},
created() {
console.log('-- created ~~Vue实例创建之后--');
console.log( this.$data );
console.log( this.$el );
},
beforeMount() {
console.log('-- beforeMount ~~Vue实例挂载之前--');
console.log( this.$data );
console.log( this.$el );
},
mounted() {
console.log('-- mounted ~~Vue实例挂载之后--');
console.log( this.$data );
console.log( this.$el );
},
beforeUpdate() {
console.log('-- beforeUpdate ~~Vue实例更新之前--');
console.log( this.$data );
console.log( this.$el );
},
updated() {
console.log('-- updated ~~Vue实例更新之后--');
console.log( this.$data );
console.log( this.$el );
},
beforeDestroy() {
console.log('-- beforeDestroy ~~Vue实例销毁之前--');
console.log( this.$data );
console.log( this.$el );
},
destroyed() {
console.log('-- destroyed ~~Vue实例销毁之后--');
console.log( this.$data );
console.log( this.$el );
}
})
</script>
</body>
</html>
运行结果:
十三、axios(哎克谁哦)插件
vue项目中发送请求的一款插件,和ajax作用相同。
官网
axios中文文档|axios中文网 | axios (axios-js.com)
get、post请求
get请求 (then是成功会走,catch是失败会走)
// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 上面的请求也可以这样做
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
post请求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
实践
1-创建一个Controller,查看所有信息(idea)
@RestControllerpublic
class CategoryController {
@Autowired private FindCategoryService findCategoryService;
@RequestMapping("/queryNav")
public List<Category> queryNav(){
return findCategoryService.findCategory();
}
}
2-在Visual Studio Code 中访问这个接口
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
//引入axios
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="xx">
</div>
<script>
new Vue({
el:'#xx',
data:{},
created(){
axios.get("http://localhost/queryNav")
.then(function(res){
console.log(res.data)
})
}
})
</script>
</body>
</html>
3-结果报错
4-分析原因
违背了同源策略,协议,ip都相同,但是端口号不同
- 用Visual Studio Code 访问,地址为:http://127.0.0.1:5500/aa.html ,端口号为:5500
- 用 idea 访问,地址为:localhost/queryNav,端口号为:80
5-解决办法:
在Controller上添加注释:@CrossOrigin
就可以正常访问了: