一、vue初步使用
1.渲染数据 {{ }}为插值表达式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">{{username}}</div>
<script>
const vm = new Vue({
el:'#app',
data:{
username:'iu'
}
})
</script>
</body>
</html>
2.指令(Directives)是 vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。
下列代码都要先导入vue.js
- 内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下 3 个:
v-text {{}} v-html
<body>
<div id="app">
<p v-text="username"></p>
<p>性别:{{gender}}</p>
<p v-html="info"></p>
</div>
<script>
// v-text指令的缺点:会覆盖元素原有的内容(了解即可) 这个问题用插值来解决{{ }}
// 渲染包含HTML标签的字符串使用v-html
// 用的最多的是{{}}
const vm = new Vue({
el:"#app", //接收的是一个选择器按规范填写
data:{
username:'iu',
gender:'女',
info:'<h4 style="color:red;font-weight:bold;">欢迎大家学习Vue</h4>'
}
})
</script>
</body>
- 属性绑定指令v-bind 简写:
<body>
<div id="app">
<!-- v-bind(简写 : )可以给属性动态添加值 -->
<input type="text" :placeholder="tips">
<hr>
<!-- <img :src="photo" alt=""> -->
<div>{{ tips }} 反转的结果是:{{ tips.split('').reverse().join('')}}</div>
<!--如果绑定的内容需要动态拼接,要在字符串的外面加上单引号-->
<div :title="'box'+index">这是一个div</div>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
tips: "请输入用户名",
index: 3
}
})
</script>
</body>
- 事件绑定v-on 简写@
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 -->
<div id="app">
<p>count 的值是:{{ count }}</p>
<!-- 在绑定事件处理函数的时候,可以使用 () 传递参数 -->
<!-- v-on: 指令可以被简写为 @ -->
<button @click="add(1)">+1</button>
<button @click="sub">-1</button>
</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<!-- <script src="./lib/vue-2.6.12.js"></script> -->
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
count: 0
},
// methods 的作用,就是定义事件的处理函数
methods: {
add(n) {
// 在 methods 处理函数中,this 就是 new 出来的 vm 实例对象
// console.log(vm === this)
// console.log(vm)
// vm.count += 1
this.count += n
},
sub() {
// console.log('触发了 sub 处理函数')
this.count -= 1
}
}
})
</script>
</body>
- 事件对象$event
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 -->
<div id="app">
<p>count 的值是:{{ count }}</p>
<!-- 如果 count 是偶数,则 按钮背景变成红色,否则,取消背景颜色 -->
<!-- <button @click="add">+N</button> -->
<!-- vue 提供了内置变量,名字叫做 $event,它就是原生 DOM 的事件对象 e -->
<button @click="add($event, 1)">+N</button>
</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<!-- <script src="./lib/vue-2.6.12.js"></script> -->
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
count: 0
},
methods: {
add(e, n) {
this.count += n
// console.log(e)
// 判断 this.count 的值是否为偶数
if (this.count % 2 === 0) {
// 偶数
e.target.style.backgroundColor = 'red'
} else {
// 奇数
e.target.style.backgroundColor = 'green'
}
}
},
})
</script>
</body>
- 事件修饰符
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 -->
<div id="app">
<p>count 的值是:{{ count }}</p>
<!-- 如果 count 是偶数,则 按钮背景变成红色,否则,取消背景颜色 -->
<!-- <button @click="add">+N</button> -->
<!-- vue 提供了内置变量,名字叫做 $event,它就是原生 DOM 的事件对象 e -->
<button @click="add($event, 1)">+N</button>
</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<!-- <script src="./lib/vue-2.6.12.js"></script> -->
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
count: 0
},
methods: {
add(e, n) {
this.count += n
// console.log(e)
// 判断 this.count 的值是否为偶数
if (this.count % 2 === 0) {
// 偶数
e.target.style.backgroundColor = 'red'
} else {
// 奇数
e.target.style.backgroundColor = 'green'
}
}
},
})
</script>
</body>
- 按键修饰符
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 -->
<!-- .esc表示按下esc键就可以清除了 .enter表示按下enter键就可以写入了-->
<div id="app">
<input type="text" @keyup.esc="clearInput" @keyup.enter="commitAjax">
</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<script src="./js/vue.js"></script>
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {},
methods: {
clearInput(e) {
console.log('触发了 clearInput 方法')
e.target.value = ''
},
commitAjax() {
console.log('触发了 commitAjax 方法')
}
},
})
</script>
</body>
- 双向绑定指令v-model
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 -->
<div id="app">
<p>用户的名字是:{{ username }}</p>
<input type="text" v-model="username">
<hr>
<input type="text" :value="username">
<hr>
<select v-model="city">
<option value="">请选择城市</option>
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">广州</option>
</select>
</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<script src="./js/vue.js"></script>
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
username: 'zhangsan',
city: '2'
}
})
</script>
</body>
- v-model的修饰符
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们把数据填充到 div 内部-->
<!-- v-model.number="n1" number输入字符串转为有效的数字 -->
<!-- v-model.trim trim自动去除首尾的空白字符 -->
<!-- v-model.trim lazy不会实时更新而是鼠标点击空白地方是更新数据 -->
<div id="app">
<input type="text" v-model.number="n1"> + <input type="text" v-model.number="n2"> = <span>{{ n1 + n2 }}</span>
<hr>
<input type="text" v-model.trim="username">
<button @click="showName">获取用户名</button>
<hr>
<input type="text" v-model.lazy="username">
</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<script src="./js/vue.js"></script>
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
username: 'zhangsan',
n1: 1,
n2: 2
},
methods: {
showName() {
console.log(`用户名是:"${this.username}"`)
}
},
})
</script>
</body>
- 条件渲染指令 v-if
v-if与v-show都可以控制显示与隐藏
v-if:是添加和删除元素
v-show:是控制元素的display属性
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们把数据填充到 div 内部 -->
<div id="app">
<p v-if="flag">这是被 v-if 控制的元素</p>
<p v-show="flag">这是被 v-show 控制的元素</p>
<hr>
<div v-if="type === 'A'">优秀</div>
<div v-else-if="type === 'B'">良好</div>
<div v-else-if="type === 'C'">一般</div>
<div v-else>差</div>
</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<script src="./js/vue.js"></script>
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
// 如果 flag 为 true,则显示被控制的元素;如果为 false 则隐藏被控制的元素
flag: true,
type: 'A'
}
})
</script>
</body>
- 循环渲染指令 v-for
<body>
<!-- 希望 Vue 能够控制下面的这个 div,帮我们把数据填充到 div 内部 -->
<div id="app">
<table class="table table-bordered table-hover table-striped">
<thead>
<th>索引</th>
<th>Id</th>
<th>姓名</th>
</thead>
<tbody>
<!-- 官方建议:只要用到了 v-for 指令,那么一定要绑定一个 :key 属性 -->
<!-- 而且,尽量把 id 作为 key 的值 -->
<!-- 官方对 key 的值类型,是有要求的:字符串或数字类型 -->
<!-- key 的值是千万不能重复的,否则会终端报错:Duplicate keys detected -->
<tr v-for="(item, index) in list" :key="item.id">
<td>{{ index }}</td>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
<!-- 1. 导入 Vue 的库文件,在 window 全局就有了 Vue 这个构造函数 -->
<script src="./js/vue.js"></script>
<!-- 2. 创建 Vue 的实例对象 -->
<script>
// 创建 Vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前 vm 实例要控制页面上的哪个区域,接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
list: [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
{ id: 3, name: '王五' },
{ id: 4, name: '张三' },
]
}
})
</script>
</body>
- v-for中的key
key的值最好是遍历数据的表示唯一的那个属性,一般都是id
<body>
<!-- 在页面中声明一个将要被 vue 所控制的 DOM 区域 -->
<div id="app">
<!-- 添加用户的区域 -->
<div>
<input type="text" v-model="name">
<button @click="addNewUser">添加</button>
</div>
<!-- 用户列表区域 -->
<ul>
<li v-for="(user, index) in userlist" :key="user.id">
<input type="checkbox" />
姓名:{{user.name}}
</li>
</ul>
</div>
<script src="./js/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
// 用户列表
userlist: [
{ id: 1, name: 'zs' },
{ id: 2, name: 'ls' }
],
// 输入的用户名
name: '',
// 下一个可用的 id 值
nextId: 3
},
methods: {
// 点击了添加按钮
addNewUser() {
this.userlist.unshift({ id: this.nextId, name: this.name })
this.name = ''
this.nextId++
}
},
})
</script>
</body>
- label的for的属性
<body>
<input type="checkbox" id="cb1">
<label for="cb1">男</label>
<hr>
<input type="checkbox" id="cb2">
<label for="cb2">女</label>
</body>
- 过滤器(filter)的使用
管道符为 |
<body>
<div id="app">
<p>message的值是:{{ message | capi}}</p>
</div>
<script src="./js/vue.js"></script>
<script>
// | 叫管道符 调用过滤器
const vm = new Vue({
el: "#app",
data: {
message: "hello vue.js"
},
// 过滤器函数,必须定义到filters节点之下
// 过滤器本质上是函数
filters: {
// 过滤器函数形参中的val,永远都是“管道符”前面的那个值
capi(val) {
// 字符串有charAt方法,这个方法接收索引值,表示从字符串中把索引对应的字符,获取出来
const first = val.charAt(0).toUpperCase();
const other = val.slice(1);
//强调 过滤器中,一定要有返回值
return first + other
}
}
})
</script>
</body>
- 私有过滤器和全局过滤器
<body>
<div id="app">
<!-- 可以调用多个过滤器 -->
<!-- <p>message 的值是:{{ message | capi | xxx | yyy }}</p> -->
<p>message 的值是:{{ message | capi }}</p>
</div>
<div id="app2">
<!-- 过滤器本质是JS函数,可以接收采参数 -->
<!-- <p>message 的值是:{{ message | capi(a,b) }}</p> -->
<p>message 的值是:{{ message | capi}}</p>
</div>
<script src="./js/vue.js"></script>
<script>
// 使用 Vue.filter() 定义全局过滤器
// 注意:如果全局过滤器和私有过滤器名字一致,此时按照"就近原则",调用的是“私有过滤器”
Vue.filter('capi', function (str,a,b) {
const first = str.charAt(0).toUpperCase()
const other = str.slice(1)
return first + other + '~~~'
})
const vm = new Vue({
el: '#app',
data: {
message: 'hello vue.js'
},
// 过滤器函数,必须被定义到 filters 节点之下
// 过滤器本质上是函数
filters: {
// 注意:过滤器函数形参中的 val,永远都是“管道符”前面的那个值
capi(val) {
// 字符串有 charAt 方法,这个方法接收索引值,表示从字符串中把索引对应的字符,获取出来
// val.charAt(0)
const first = val.charAt(0).toUpperCase()
// 字符串的 slice 方法,可以截取字符串,从指定索引往后截取
const other = val.slice(1)
// 强调:过滤器中,一定要有一个返回值
return first + other
}
}
})
const vm2 = new Vue({
el: '#app2',
data: {
message: 'heima'
}
})
</script>
</body>
- 侦听器Watch
<body>
<div id="app">
<h2>
<span>姓:</span>
<input type="text" v-model="firstName">
<span>名:</span>
<input type="text" v-model="lastName">
</h2>
<h2>
<span>姓名:</span>
<span>{{fullName}}</span>
</h2>
<hr>
<h2>
<h2>员工信息:</h2>
姓名:<input type="text" v-model="emp.name">
<br>
年龄:<input type="text" v-model="emp.age">
<h2>员工的车辆信息:</h2>
汽车:<input type="text" v-model="emp.car.name">
<br>
价格:<input type="text" v-model="emp.car.price">
</h2>
</div>
<script>
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: "#app",
data() {
return {
firstName: '秦',
lastName: '嬴政',
emp: {
name: '哈哈哈',
age: '20',
car: {
name: '奔驰',
price: '100万'
}
}
}
},
// 计算属性
computed: {
fullName(){
// 计算属性的方法,会在它里面的用到的属性的值发生变化时重新执行
// 所以计算属性本身就具备了监听数据的能力
return this.firstName + '.' + this.lastName
}
},
// 数据侦听器 watch
watch: {
// 侦听谁就以那个属性作为方法
// 该方法可以接收两个参数,分别是侦听的那个属性的最新值和之前的旧值.一般旧值不需要
// 侦听器主要应用在登录时的验证
firstName(newValue, oldValue) {
// console.log(newValue);
},
// 如果要深度监听某个属性,就要采用完整的形式,定义侦听器
emp:{
//deep深度监听
deep: true,
// immediate:true,//让侦听器,一上来就立刻执行一次
// handler()方法,侦听数据的变化
handler(newValue, oldValue) {
console.log(newValue);
}
}
}
})
</script>
</body>
- 对象格式的侦听器
<body>
<div id="app">
<input type="text" v-model="username">
</div>
<script src="./js/vue-2.6.12.js"></script>
<script src="./js/jquery-v3.6.0.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: 'admin'
},
// 所有的侦听器,都应该被定义到 watch 节点下
watch: {
// 定义对象格式的侦听器
username: {
// 侦听器的处理函数
handler(newVal, oldVal) {
console.log(newVal, oldVal)
},
// immediate 选项的默认值是 false
// immediate 的作用是:控制侦听器是否自动触发一次!
immediate: true
}
}
})
</script>
</body>
- 计算属性(computed)—例子RGB颜色
计算属性写法上是一个函数,返回的值就是计算属性最终的值
<body>
<div id="app">
<div>
<span>R:</span>
<input type="text" v-model.number="r">
</div>
<div>
<span>G:</span>
<input type="text" v-model.number="g">
</div>
<div>
<span>B:</span>
<input type="text" v-model.number="b">
</div>
<hr>
<!-- 专门用户呈现颜色的 div 盒子 -->
<!-- 在属性身上,: 代表 v-bind: 属性绑定 -->
<!-- :style 代表动态绑定一个样式对象,它的值是一个 { } 样式对象 -->
<!-- 当前的样式对象中,只包含 backgroundColor 背景颜色 -->
<div class="box" :style="{ backgroundColor: rgb }">
{{ rgb }}
</div>
<button @click="show">按钮</button>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
// 红色
r: 0,
// 绿色
g: 0,
// 蓝色
b: 0
},
methods: {
// 点击按钮,在终端显示最新的颜色
show() {
console.log(this.rgb)
}
},
// 所有的计算属性,都要定义到 computed 节点之下
// 计算属性在定义的时候,要定义成“方法格式”
computed: {
// rgb 作为一个计算属性,被定义成了方法格式,
// 最终,在这个方法中,要返回一个生成好的 rgb(x,x,x) 的字符串
rgb() {
return `rgb(${this.r}, ${this.g}, ${this.b})`
}
}
});
console.log(vm)
</script>
</body>
- 使用axios
要使用axios.js文件,在html引用
<body>
<!-- <button @click="btnPost">发起POST请求</button> -->
<button id="btnPost">发起POST请求</button>
<button id="btnGet">发起GET请求</button>
<script>
document.querySelector("#btnPost").addEventListener('click', async function () {
// 如果调用某个方法的返回值是Promise实例,则前面可以添加await
// await只能用在被async修饰的方法中
// {}解构赋值
const {
data
} = await axios.post("http://www.liulongbin.top:3006/api/post",{
name: 'zs',
age: 20
})
console.log(data);
})
document.querySelector("#btnGet").addEventListener('click', async function () {
// 如果调用某个方法的返回值是Promise实例,则前面可以添加await
// await只能用在被async修饰的方法中
// {}解构赋值 {xx:{}}双层解构赋值
// 把解构出来的data属性,使用冒号进行重命名,一般都名字为{data:res}
const {
data:{data} //第一种
// data:res
} = await axios.get("http://www.liulongbin.top:3006/api/getbooks",{
params:{id:1}
})
// console.log(res.data);
console.log(data);
})
</script>
<!-- <script>
//http://www.liulongthbin.top:3006/api/getbooks
// 调用axios方法得到的返回值是Promise对象
axios({
methods: "GET",
url: 'http://www.liulongbin.top:3006/api/getbooks',
// URL中的查询参数
params:{
id:1
},
// 请求体参数
data:{}
}).then(r => {
console.log(r.data.data);
})
</script> -->
</body>
- $mount方法
<body>
<div id="app">{{username}}</div>
<script src="./js/vue-2.6.12.js"></script>
<script>
const vm = new Vue({
data: {
username: 'admin'
}
})
// $mount作用相当于el:''
vm.$mount('#app')
</script>
</body>