简介

官网:cn.vuejs.org
官方文档:https://v3.cn.vuejs.org/guide/installation.html
菜鸟:https://www.runoob.com/vue3/vue3-tutorial.html

可以联网导入,也可以下载下来本地导入。本文章全以本地导入为主
<script src="https://unpkg.com/vue@next"></script>

Hello Vue

熟悉以下语法

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- 第一步 引入vue.js文件 -->
<script src="./js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
<!-- 第二步 创建一个挂载节点 -->
<div id="app">
{{message}}
</div>

<!-- 第三步 创建Vue实例,并且绑定挂载节点 -->
<script type="text/javascript">

//声明一个常量
const app = {
data(){
return{
message:`Hello Vue`
}
}
}

//创建Vue实例,并且绑定挂载节点
Vue.createApp(app).mount("#app");

</script>
</body>
</html>

指令

指令是带有v-开头的特殊属性,其值限定为单个表达式。
指令的作用是,当表达式的值发生变化,将其产生的连带影响应用到DOM节点中。

v-html

用于更新元素的innerHTML,该根部内容会被当做HTML代码插入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
<div id="app">
<p v-html="message"></p>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return {
message: `<h1>Hello Vue.js</h1>`
}
}
}).mount("#app");
</script>
</body>

v-text

将字符串以普通文本的形式输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<p v-text="message"></p>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return {
message: `<h1>Hello Vue.js</h1>`
}
}
}).mount("#app");
</script>
</body>
</html>

v-bind

主要用于响应更新HTML元素属性,将一个或者多个属性动态绑定到表达式。
v-bind可省略,如v-bind:src可简写为:src

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<img v-bind:src="imgUrl" width="100" height="100"/>
<!--
v-bind指令可以省略
-->
<p :title="message">把鼠标放在这里停留几秒</p>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return {
imgUrl: `https://img2.baidu.com/it/u=281572882,1041305488&fm=26&fmt=auto`,
message:"这个是绑定了title属性的p元素"
}
}
}).mount("#app");
</script>
</body>
</html>

v-model

该指令用于在表单元素中的双向数据绑定。
v-model会忽略所有表单元素的value checked、selected特性的初始值。因为它会选择vue实例的数据来作为具体的值。

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h2>1.文本输入</h2>
<p>{{message}}</p>
<input v-model="message" type="text"/>

<h2>2.单选框</h2>
<p>{{gender}}</p>
性别:
男:<input type="radio" name="gender" value="male" v-model="gender"/>
女:<input type="radio" name="gender" value="female" v-model="gender" />


<h2>3.复选框</h2>
<p>{{hobby}}</p>
爱好:
健身<input type="checkbox" value="健身" v-model="hobby" />
踢球<input type="checkbox" value="踢球" v-model="hobby" />
游戏<input type="checkbox" value="游戏" v-model="hobby" />
游泳<input type="checkbox" value="游泳" v-model="hobby" />
拳击<input type="checkbox" value="拳击" v-model="hobby" />


<h2>4.下拉选框</h2>
<p>{{city}}</p>
<select v-model="city">
<option value ="0">--请选择--</option>
<option value="gz">广州</option>
<option value="nj">南京</option>
<option value="bj">北京</option>
<option value="sh">上海</option>
</select>


<hr/>
<button type="button" @click="show">点击</button>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return {
message:"zhangsan",
gender:"male",
hobby:['拳击'],
city:"0"
}
},
methods:{
show(){
//alert(this.message);
//alert(this.gender);
//alert(this.hobby);
alert(this.city);
}
}
}).mount("#app");
</script>
</body>
</html>

v-show 与 v-if

根据表达式的真假,来显示或者隐藏HTML元素。

区别:
v-show会生成节点然后使用dispaly属性进行显示和隐藏
v-if在值是false的时候不生成节点

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h1 v-show="yes">yes</h1>
<h1 v-show="no">no</h1>
<h1 v-show="age >= 26">{{age}}</h1>
<h1 v-show="name.indexOf('s') >= 0">{{name}}</h1>
</div>
<script type="text/javascript">
Vue.createApp({
data(){
return{
yes:true,
no:false,
age:26,
name:"smith"
}
}
}).mount("#app");
</script>
</body>
</html>
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h1 v-if="yes">yes</h1>
<h1 v-if="no">no</h1>
<h1 v-if="age >= 26">{{age}}</h1>
<h1 v-if="name.indexOf('s') >= 0">{{name}}</h1>
</div>
<script type="text/javascript">
Vue.createApp({
data(){
return{
yes:true,
no:false,
age:26,
name:"smith"
}
}
}).mount("#app");
</script>
</body>
</html>

v-else-if 与 v-else

互斥条件,当一个条件满足时,后续条件都不会再判断。

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<span v-if="score >= 95">优秀</span>
<span v-else-if="score >= 80">良好</span>
<span v-else-if="score >= 60">及格</span>
<span v-else>不及格</span>
</div>
<script type="text/javascript">
Vue.createApp({
data(){
return{
score:79
}
}
}).mount("#app");
</script>
</body>
</html>

v-for

通过循环的方式来渲染一个列表,循环对象可以是数组,也可以是JS对象。
遍历数组语法:item in items
遍历对象语法:value,key,index in Obj

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h1>1.迭代数组</h1>
<ul>
<li v-for="(city,index) in citys">{{index + 1}}--{{city}}</li>
</ul>
<h1>2.迭代对象</h1>
<ul>
<li v-for="(value,key,index) in book">{{index}}--{{key}}--{{value}}</li>
</ul>
</div>
<script type="text/javascript">
Vue.createApp({
data() {
return {
citys:['广州','南京','上海','北京'],
book:{
name:"《从入门到放弃》",
isbn:"1234567890",
author:"葫芦",
price:65.00
}
}
}
}).mount("#app");
</script>
</body>
</html>

v-on

事件绑定指令,而且JS的所有事件都可以用v-on绑定

全写形式:v-on-click
简写形式:@click

其他常用事件:https://pengyirui.gitee.io/posts/d3d6.html#%E4%BA%8B%E4%BB%B6

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h1>1.点击事件</h1>
{{message}}

<h1>2.焦点失去事件</h1>
<input type="text" @blur="print" />
<hr />
<button type="button" @click="changeMessage">点击改变message的值</button>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return {
message: "Hello Vue.js"
}
},
methods: {
changeMessage() {
this.message = "Hello World";
},
print() {
alert("焦点失去事件被触发...");
}
}
}).mount("#app");
</script>
</body>
</html>

绑定HTML 的class

class是每个HTML元素都有的属性。
用vue控制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
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
.active{
width: 100px;
height: 100px;
background-color: greenyellow;
}
.border-style{
border-radius: 10px;
cursor: pointer;
}
</style>

<script src="../js/v3.2.8/vue.global.prod.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
<div id="app">
<div :class="{'active':isActive,'border-style':isBorderStyle}"></div>
<div :style=""></div>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return {
isActive:true,
isBorderStyle:true
}
},
}).mount("#app");
</script>
</body>
</html>

组件

可以 扩展 HTML 元素 和 封装 可重用的代码。

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
<body>
<div id="app">
<!-- 4.可重复使用组件 -->
<first-component></first-component>
<first-component></first-component>
</div>

<script type="text/javascript">
//1.构建一个空的Vue实例
const app = Vue.createApp({});

//2.使用 vue实例构建一个组件
// first-component:自定义标签
// template:编写模板
app.component("first-component",{
template:`
<div>
<h1>Hello Component</h1>
<h2>这是我的第一个VUE组件...</h2>
</div>
`
});
//3.挂载
app.mount("#app");
</script>
</body>

局部组件注册

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
<body>
<div id="app">
{{message}}
<login></login>
</div>
<script type="text/javascript">

Vue.createApp({
data() {
return{
message:"这是Vue实例的message"
}
},
components:{
login:{
template:`
<h1>这是登录的局部组件--{{this.message}}</h1>
`,
data() {
return{
message:"这是局部组件的message"
}
}
}
}
}).mount("#app");
</script>
</body>

静态值传递 props

关键字props:用于设定组件中的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<div id="app">
<site-name title="Google"></site-name>
<site-name title="Runoob"></site-name>
<site-name title="Taobao"></site-name>
</div>

<script>
const app = Vue.createApp({})

app.component('site-name', {
props: ['title'],
template: `<h4>{{ title }}</h4>`
})

app.mount('#app')
</script>
</body>

动态值传递

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
<body>
<div id="app">
<login :post="obj"></login>
<button type="button" @click="changeData">点击</button>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return{
obj:{
id:1,
title:"《标题》",
content:"内容...."
}
}
},
methods:{
changeData(){
alert('点击触发事件执行');
this.obj = {'id':2,'title':'关于...','content':'疫情防御....'}
}
},
components:{
login:{
template:`
<div>
<h1>{{post.id}}</h1>
<h1>{{post.title}}</h1>
<h1>{{post.content}}</h1>
</div>
`,
props:['post']
}
}
}).mount("#app");
</script>
</body>

事件绑定

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
49
50
51
<body>
<div id="app">
<login v-bind:post="obj"></login>
<button type="button" @click="changeData">普通点击事件</button>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return{
obj:{
id:1,
title:"《标题》",
content:"内容...."
}
}
},
methods:{
changeData(){
alert('点击触发事件执行');
this.obj = {'id':2,'title':'关于...','content':'疫情防御....'}
}
},
components:{
login:{
data() {
return{
msg:"组件中数据.."
}
},
template:`
<div>
<h1>{{post.id}}</h1>
<h1>{{post.title}}</h1>
<h1>{{post.content}}</h1>
<h1>{{msg}}</h1>
<button type="button" @click="changeData">组件点击事件</button>
</div>
`,
props:['post'],
methods:{
changeData(){
alert(this.msg);
this.msg = "修改了组件中的数据"
}
}
}
}
}).mount("#app");
</script>
</body>

计算属性 computed

是用来简化vue页面中 文本插值的js表达式。

computed 与 methods区别:
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

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
<body>
<div id="app">
<p>未改变之前的数据:{{message}}</p>
<p>改变之后的数据:{{upperCase}}</p>
<p>{{msg}}</p>
<button type="button" @click="upperCase1">点击</button>
</div>

<script type="text/javascript">
Vue.createApp({
data() {
return{
message:"Hello World",
msg:""
}
},
computed:{
upperCase(){
return this.message.toUpperCase();
}
},
methods:{
upperCase1(){
this.msg = this.message.toUpperCase();
}
}
}).mount("#app");
</script>
</body>

路由

在vue的基础上,再导入路由文件
下载 或 在线导入路由:<script src="https://unpkg.com/vue-router@4"></script>

路由允许我们通过不同的url访问不同的内容
通过vue可以实现多视图的单页web应用

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
<body>
<div id="app">
<router-view></router-view>
<router-link to="/">首页</router-link>
<router-link to="/news">新闻</router-link>
<router-link to="/book">图书</router-link>
</div>

<script type="text/javascript">
//1.创建模板
const index = {
template: `<div>这是主页</div>`
}
const news = {
template: `<div>这是新闻</div>`
}
const book = {
template: `<div>这是图书</div>`
}

//2.设置路由地址,列表中的对象
const routes = [{
path: "/",
component: index
},
{
path: "/news",
component: news
},
{
path: "/book",
component: book
},
]

//3.创建路由
const router = VueRouter.createRouter({
//设置路由的模式
history: VueRouter.createWebHistory(),
routes
});

//4.创建vue实例并且使用路由及挂载
Vue.createApp({}).use(router).mount("#app")
</script>
</body>

axios

vue中的ajax技术。可以理解为vue封装的ajax技术。
axios是基于vue.js开发的的,所以要先导入vue.js
下载 或 在线导入:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

1
2
3
4
5
6
7
8
语法:
axios({method,url,params}then().catch();

get语法:
axios.get('',{params}).then(resp=>{}).catch(error=>{});

post语法(需要转换):
axios.post('',{});

具体实现:把name与time发送到后台,后台发送json对象到前台

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
// method:模式
// url:发送地址
// params:传送的数据
// .then(resp=>{成功后接收到的数据})
axios({
method:"post",
url:"http://localhost:8080/ums_web_war_exploded/axiosAjax",
params:{
name:this.name,
time:"2021-10-8 16:52"
}
}).then(resp=>{
this.info = resp.data;
})

// get
axios.get('http://localhost:8080/ums_web_war_exploded/axiosget',{
params:{
name:this.name,
time:"2021-10-8 16:52"
}
}).then(resp=>{
this.users = resp.data;
});

// post
// 注意!!!!
//处理需要发送的数据
let params = new URLSearchParams();
params.append("name",this.name);
params.append("time","2021-10-8 16:52");
//将传给服务器后台的数据封装成:name=xxx&time=2021-10-8 16:52
//然后将处理过的参数让浏览器打包发送给服务器
//使用axios发送ajax请求
axios.post('http://localhost:8080/ums_web_war_exploded/axiospost',params).then(resp => {
this.users = resp.data;
});

vue cli

Vue CLI 是一个基于 Vue.js进行快速开发的一个完整的系统。
Vue CLI安装需要使用npm命令,npm命令需要基于node.js,所以要先安装node.js

node.js官网:【http://nodejs.cn/】

搭建:npm install -g @vue/cli

选一个目录创建项目
vue create 项目名

进入项目目录,运行服务,用浏览器测试。
npm run serve

添加自定义组件

例子:在components 文件夹中添加一个 mycomponent.vue文件

  1. 创建组件文件
    .vue为后缀的文件,这个文件可以包含,HTML、CSS、JS
    HTML是写在<template></template>
    CSS是写在<style></style>
    JS是写在<script></script>

在APP.vue中导入 mycomponent.vue

  1. 如需要,在vue cli 中添加axios
    命令:npm导入:npm install --save axios
  2. 在MyComponent.vue文件中导入axios
    import axios from ‘axios’