基础知识
基础环境
- vscode
- 所需的插件:
jshint:JS代码检查
Beautify:代码美化(选中代码–>format doc)
Vetur: Vue插件
JavaScript (ES6) code snippets: ES6语法
Auto Rename Tag: 自动重命名标签
Vue-helper:Vue提示
vscode-icons: 文件夹图标
open in browser
vscode快捷键
ctrl+k
以及ctrl+s
打开快捷键窗口,以便查看快捷键
Vue 介绍
是一套构建前后端分离的架构
Vue的安装和使用
三种方式:
- script标签引用
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- production version, optimized for size and speed -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
- npm安装
- vue-cli安装
Vue体验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="../lib/vue.js"></script>
<title>01VueStudy</title>
</head>
<body>
<div id="app">
<p>{{ greet() }}</p>
<p>{{ username }}</p>
<button @click="username='隔壁老王'">更改值</button>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
username: "Hello"
},
methods: {
greet() {
return "你好啊"
}
}
})
</script>
</html>
Vue的模板语法
- v-bind: 属性绑定
- v-once: 在模板中只读取一次变量,后续变量更改了,不会跟着变化
- v-html: 解析html标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="../lib/vue.js"></script>
<title>vue v-bind</title>
</head>
<body>
<div id="app">
<p v-once>{{ username }}</p>
<p v-html='code'>{{ code }}</p>
<button @click="username='隔壁老王'">改变</button>
<img v-bind:src="logo" alt="">
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
username: "Alex",
code: "<a href='https://www.baidu.com'>BAT</a>",
logo: "https://vuejs.org/images/logo.png"
}
})
</script>
</html>
Vscode添加自定义代码片段
ctrl+shift+p
- 搜索
Snippets
关键字,选择Preferance - 选择html.json,修改成如下的样子
{
"my vue html code": {
"prefix": "html",
"body": [
"<!DOCTYPE html>",
"<html lang='en'>",
"<head>",
" <meta charset='UTF-8'>",
" <meta name='viewport' content='width=device-width, initial-scale=1.0'>",
" <meta http-equiv='X-UA-Compatible' content='ie=edge'>",
" <script src='../lib/vue.js'></script>",
" <title>$1</title>",
"</head>",
"<body>",
" <div id='app'>",
" </div>",
"</body>",
" <script>",
" new Vue({",
" el: '#app',",
" data: {",
" $2",
" }",
" })",
" </script>",
"</html>",
],
"description": "my vue html code"
}
}
属性绑定
- 绑定class的两种形式
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title></title>
<style>
.title{
font-size: 20px;
color: red
}
.main-title{
font-weight: 1800;
}
</style>
</head>
<body>
<div id='app'>
<!-- 数组方式 -->
<p v-bind:class="[pclass1,pclass2]">I like Vue</p>
<!-- 对象方式 -->
<p :class="{'title':true,'main-title':strong}">我是隔壁老王</p>
<button @click="strong=true">文字加粗</button>
<!-- 对象方式 -->
<p :style="{backgroundColor:backgroundColor}">属性绑定样例</p>
<!-- 数组方式 -->
<p :style="[Pstyle1,Pstyle2]">属性绑定样例2</p>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
pclass1: "title",
pclass2: "main-title",
strong: false,
backgroundColor: "red",
Pstyle1: {
'background-color':'blue',
'font-size': '30px'
},
Pstyle2: {
"border-bottom":"2px solid #000"
}
}
})
</script>
</html>
使用JS表达式
在属性绑定和变量读取中,可以使用表达式。常见的表达式有: 变量读取,变量运算,三目运算符,函数调用,取反等
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title></title>
</head>
<body>
<div id='app'>
<div :style="{color: danger?'red':'black'}">{{ message.split(" ").reverse().join(" ") }}</div>
<div>{{ greet() }}</div>
<div>{{ !is_adult }}</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
// 条件?条件成立的值:条件不成立的值
// danger: true
danger: false,
message: "Hello World Hello China",
is_adult: true
},
methods: {
greet() {
return "Good Morning!!"
}
}
})
</script>
</html>
条件判断
if系列
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title>Vue 判断</title>
</head>
<body>
<div id='app'>
<p v-if="weather=='sun'">GoPark</p>
<p v-else-if="weather='rain'">WatchMovie</p>
<p v-else>StayHome</p>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
weather: "rain"
}
})
</script>
</html>
多重条件使用template
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title>IF</title>
</head>
<body>
<div id='app'>
<template v-if="age < 18">
<p>AAA</p>
</template>
<template v-else-if="age >=18 && age <= 20">
<p>BBB</p>
</template>
<template v-else>
<p>CCC</p>
</template>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
age: 24
}
})
</script>
</html>
method小例子
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<script src='../lib/vue.js'></script>
<title>V-if</title>
</head>
<body>
<div id='app'>
<template v-if="loginType=='username'">
<label>用户名</label>
<input type="text" name="username" placeholder="用户名">
</template>
<template v-else-if="loginType=='email'">
<label>邮箱</label>
<input type="text" name="email" placeholder="email">
</template>
<button @click="changeLoginType">更换登录类型</button>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
loginType: "username"
},
methods: {
changeLoginType() {
//三目运算符
this.loginType = this.loginType =='username'?"email":"username"
}
}
})
</script>
</html>
小结:
-
v-if
,v-else-if
,v-else
- 如果想要某个调间下渲染多个元素,那么就要使用
template
标签 - Vue默认会重用相同的标签来提高性能,如果不要重用的话,那就在对应的元素上加一个
key
属性即可
v-show和v-if的区别
v-show: 是通过简单的切换display来渲染信息,会一次性加载所有的元素,在频繁切换的状态下推荐使用,不能在template标签上使用
v-if: 真正的条件渲染,如果条件更改了,会重新加载
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title></title>
</head>
<body>
<div id='app'>
<div v-show="loginType=='username'">
<label>用户名</label>
<input type="text" name="username" placeholder="username" key="username">
</div>
<div v-show="loginType=='email'">
<label>邮箱</label>
<input type="text" name="email" placeholder="email" key="email">
</div>
<button @click='changeLoginType'>切换登录方式</button>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
loginType: "username"
},
methods: {
changeLoginType() {
this.loginType = this.loginType=='username'?'email':'username'
}
}
})
</script>
</html>
循环语法
- 循环数组
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title>loop</title>
</head>
<body>
<div id='app'>
<table>
<thead>
<tr>
<th>Index</th>
<th>bookName</th>
<th>Author</th>
</tr>
</thead>
<tbody>
<tr v-for="book,index in books">
<td>{{index+1}}</td>
<td>{{ book.title }}</td>
<td>{{book.author}}</td>
</tr>
</tbody>
</table>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
books: [
{
'title':'Book1',
'author':'1'
},
{
'title': 'book2',
'author': '2'
},
{
'title':'book3',
'author':'3'
},
{
'title': 'book4',
'author': '4'
}
]
}
})
</script>
</html>
- 循环对象
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title>vue for</title>
</head>
<body>
<div id='app'>
<div v-for="(value,key) in person">
{{ key }} : {{ value }}
</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
person: {
username: "alex",
age: 18,
homepage: "http://www.baidu.com"
}
}
})
</script>
</html>
- 状态保持
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title>vue-for</title>
</head>
<body>
<div id='app'>
<div v-for="book in books" :key="book.title">
<label>标题:</label>
<input type="text" :placeholder="book.title">
</div>
<button @click="changeBookSort">更改图书顺序</button>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
books: [
{
'title':'Book1',
'author':'1'
},
{
'title': 'book2',
'author': '2'
},
{
'title':'book3',
'author':'3'
},
{
'title': 'book4',
'author': '4'
}
]
},
methods: {
changeBookSort() {
this.books.sort(function (a,b) {
return Math.random(0,1) - 0.5
})
}
}
})
</script>
</html>
小结:
- 默认情况下,如果数组中的顺序发生变化,或者个数比发生变化导致重新渲染,那么vue就会重新利用之前的元素,而不会重新排序,这样需要添加
key
属性,key
只能支持number和string类型 - 在vue2.2+ ,key是必须的
视图更新
针对数组中使用函数进行更新,有一下的方法直接触发更新push/pop/sort/splice/concat/reverse/shift/unshift
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title>View Update</title>
</head>
<body>
<div id='app'>
<ul>
<li v-for="role in roles" :key="role">
{{role}}
</li>
</ul>
<button @click="update">更新</button>
<button @click="update2">更新2</button>
<button @click="popRole">删除最后一个元素</button>
<button @click='shiftRole'>删除第一个元素</button>
<button @click='unshiftRole'>在第一个位置添加元素</button>
<button @click='spliceTwo'>删除前两个元素</button>
<button @click="spliceChange">替换前三个元素中的aaa为XXXX</button>
<button @click="spliceAdd">在第一个之前添加元素</button>
<button @click=concatRole>合并数组</button>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
roles: ['aaa','bbb','ccc']
},
methods: {
// 直接赋值更新
//通过函数更新
update() {
this.roles = ['ddd']
},
update2() {
this.roles.push("eee")
},
popRole() {
this.roles.pop()
},
shiftRole() {
this.roles.shift()
},
unshiftRole() {
this.roles.unshift("AAA")
},
spliceTwo() {
this.roles.splice(0,2)
},
spliceChange() {
this.roles.splice(0,4,'aaa','XXXX')
},
spliceAdd() {
this.roles.splice(0,0,"dsadsadsa")
},
concatRole() {
this.roles = this.roles.concat(['ssss','assfa'])
}
}
})
</script>
</html>
视图更新
如果想要通过下标来更新数组中的某个值,这样是不会触发视图更新的,需要通过Vue.set
来实现
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<script src='../lib/vue.js'></script>
<title>updateArray</title>
</head>
<body>
<div id='app'>
<ul>
<li v-for="role in roles" :key="role">
{{role}}
</li>
</ul>
<div v-for="(value,key) in users">
{{key}}:{{value}}
</div>
<button @click='updateArray'>更新Array</button>
<button @click='updateObj'>更新对象</button>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
roles:["aa","bb","cc"],
users: {"username":"BBB"}
},
methods: {
updateArray() {
// this.roles[0] = "dsadsadsd" 不能更新
Vue.set(this.roles,0,'dadsffdafa')
},
updateObj() {
this.users.username = "asdsfasfof",
Vue.set(this.users,'age',19)
}
}
})
</script>
</html>