Vue的基本使用
创建Vue实例
创建Vue实例,初始化渲染
1.准备容器(Vue所管理的范围)
2.引包(开发版本包/生产版本包)官网
3.创建实例
4.添加配置项 => 完成渲染
<body>
<div id="app">
{{ msg }}
</div>
</body>
<!-- 引入的是开发版本包,包含完整的注释和警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
// 一旦引入VueJS核心包,在全局环境,就有了Vue构造函数
const app = new Vue({
// 通过el配置选择器,指定Vue管理的是哪个盒子
el: '#app',
// 通过data提供数据
data: {
msg: 'Hello Insight'
}
})
</script>
插值表达式 {{ }}
- Vue的一种模板语法,利用表达式进行插值渲染
- 使用的数据必须存在(data)
- 支持的是表达式,而非语句
- 不能在标签属性中使用{{ }}插值
<div id="app">
<p>{{ nickname }}</p>
<p>{{ nickname.toUpperCase() }}</p>
<p>{{ nickname + '你好' }}</p>
<p>{{ age >= 18 ? '成年' : '未成年' }}</p>
<p>{{ friend.name }}</p>
<p>{{ friend.desc }}</p>
</div>
...
<script>
// 一旦引入VueJS核心包,在全局环境,就有了Vue构造函数
const app = new Vue({
el: '#app',
data: {
nickname: 'tony',
age: 18,
friend: {
name: 'jackson',
desc: '热爱学习 Vue'
}
}
})
</script>
安装Vue开发者工具:安装插件调试Vue应用
1.访问网址,搜索vue插件
https://chrome.zzzmh.cn/index
2.下载插件并解压
3.打开浏览器拓展页面,将文件拖至拓展区域,确认添加拓展,同时点击拓展详情信息,打开
允许访问文件URL
4.重启浏览器,打开调试工具,便可在顶部菜单栏找到Vue板块
Vue指令
带有v-前缀
的特殊标签属性
v-html
动态设置当前元素的html,相当于innerHTML
<div v-html="link"></div>
...
data{
msg: '<a href="www.baidu.com">搜索一下,你就知道</a>'
}
v-show
语法:v-show="表达式"
控制元素显示隐藏(通过display:none隐藏,适用于频繁切换显示隐藏的场景)
v-if
语法:v-if="表达式"
控制元素显示隐藏(通过条件判断,控制元素的创建或移除,适用于不频繁切换显示隐藏的场景)
- v-if 、v-else 、v-else-if
<p v-if="gender === 1">性别:男</p>
<p v-else>性别:女</p>
<hr>
<p v-if="score >= 90">优秀<p>
<p v-else-if="score >= 80">良好<p>
<p v-else-if="score >= 70">一般<p>
<p v-else>不及格<p>
...
data{
gender: 2,
score: 80
}
v-on
注册事件 = 添加监听 + 提供处理逻辑
语法:
v-on:事件名 = “内联语句”
v-on:事件名 = “methods中的函数名”
<!-- v-on:事件名 = “内联语句” -->
<button v-on:click="count++">{{ count }}</button>
...
data{
count: 100
}
<!-- v-on:事件名 = “methods中的函数名” -->
<button @click="changeShow">切换显示隐藏</button>
<h1 v-show="isShow">Insight</h1>
...
data: {
isShow: true
},
methods: {
changeShow() {
this.isShow = !this.isShow
}
}
v-on:click 可以简写为 @click
v-on需要传递参数时:
@click="add(8, 9)
"
v-bind
动态设置属性值
<img v-bind:src="imgUrl" v-bind:title="msg">
v-bind:src 可以简写为:
:src
案例:图片的点击切换
<div id="app">
<button v-show="index > 0" @click="index--">上一页</button>
<div>
<img :src="list[0]" alt="">
</div>
<button v-show="index < list.length - 1" @click="index++">下一页</button>
</div>
...
<script>
const app = new Vue({
el: "#app",
data: {
index: 0,
list: [
'./1.png',
'./2.png',
'./3.png'
]
}
})
</script>
v-bind对于样式控制的增强
操作class
- 对象:键值对,值为true添加类,否则不添加
<div class="box" :class="{ 类名1: 布尔值, 类名2: 布尔值}"></div>
- 数组:将数组中所有类添加
<div class="box" :class="[ 类名1, 类名2 ]"></div>
操作style
<div class="box" :style="{ CSS属性名: CSS属性值, CSS属性名: CSS属性值}"></div>
不支持
-
,例如background-color,可以改为backgroundColor
案例:京东秒杀tab
<style>
* {
margin: 0;
padding: 0;
}
ul {
display: flex;
border-bottom: 2px solid #e01222;
padding: 0 10px;
}
li {
width: 100px;
height: 50px;
line-height: 50px;
list-style: none;
text-align: center;
}
li a {
display: block;
text-decoration: none;
font-weight: bold;
color: #333333;
}
li a.active {
background-color: #e01222;
color: #fff;
}
</style>
<body>
<div id="app">
<ul>
<li v-for="(item, index) in list" :key="item.id" @click="activeIndex = index">
<a :class="{ active: index === activeIndex }" href="#">{{ item.name }}</a>
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
activeIndex: 1,
list: [
{ id: 1, name: '京东秒杀' },
{ id: 2, name: '每日特价' },
{ id: 3, name: '品类秒杀' },
]
}
})
</script>
</body>
v-for
基于数据循环,多次渲染整个元素
语法:v-for="(item, index) in 数组"
<ul>
<li v-for="(item, index) in list">{{ item }}-{{ index }}</li>
</ul>
...
data: {
list: ['苹果', '香蕉', '西瓜']
}
v-for中的key
语法:key属性=“唯一标识”
给元素添加唯一标识,便于Vue进行列表项的正确排序复用
案例:书架
<div id="app">
<h2> 书架</h2>
<ul>
<li v-for="item in booksList" :key="item.id">
<span>{{ item.name }}</span>
<span>{{ item.author }}</span>
<button @click="del(item.id)">删除</button>
</li>
</ul>
</div>
...
<script>
const app = new Vue({
el: "#app",
data: {
booksList: [
{ id: 1, name: '《红楼梦》', author: '曹雪芹' },
{ id: 2, name: '《西游记》', author: '吴承恩' },
{ id: 3, name: '《水浒传》', author: '施耐庵' },
{ id: 4, name: '《三国演义》', author: '罗贯中' }
]
},
methods: {
del(id) {
// filter不会改变原数组,根据条件,保留满足条件的对应项,得到一个新数组
this.booksList = this.booksList.filter(item => item.id !== id)
}
}
})
</script>
v-model
语法:v-model="变量"
为表单元素使用,双向数据绑定,可以快速获取和设置
姓名:<input type="text" v-model="username">
是否单身:<input type="checkbox" v-model="isSingle">
性别:
<input v-model="gender" type="radio" name="gender" value="1">男
<input v-model="gender" type="radio" name="gender" value="2">女
所在城市:
<select v-model="cityId">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">成都</option>
<option value="104">南京</option>
</select>
自我描述:<textarea v-model="desc"></textarea>
...
data: {
username: '',
isSingle: false,
gender: "2",
cityId: '102',
desc: ""
}
案例:记事本
<body>
<!-- 主体区域 -->
<section id="app">
<!-- 输入框 -->
<header class="header">
<h1>Insight记事本</h1>
<input @keyup.enter="add" v-model="todoName" placeholder="请输入任务" class="new-todo" />
<button @click="add" class="add">添加任务</button>
</header>
<!-- 列表区域 -->
<section class="main">
<ul class="todo-list">
<li class="todo" v-for="(item, index) in list" :key="item.id">
<div class="view">
<span class="index">{{ index + 1 }}.</span> <label>{{ item.name }}</label>
<button @click="del(item.id)" class="destroy"></button>
</div>
</li>
</ul>
</section>
<!-- 统计和清空 => 没有任务了,底部隐藏,v-show -->
<footer class="footer" v-show="list.length > 0">
<!-- 统计 -->
<span class="todo-count">合 计:<strong> {{ list.length }} </strong></span>
<!-- 清空 -->
<button class="clear-completed" @click="clear">
清空任务
</button>
</footer>
</section>
<!-- 底部 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
list: [
{ id: 1, name: "干一碗饭" },
{ id: 2, name: "喝一杯水" },
{ id: 3, name: "睡一觉" }
],
todoName: ""
},
methods: {
del(id) {
this.list = this.list.filter(item => item.id !== id)
},
add() {
if (this.todoName.trim() === '') {
alert('请输入任务!')
return
}
this.list.unshift({
id: +new Date(),
name: this.todoName
})
this.todoName = ''
},
clear() {
this.list = []
}
}
})
</script>
</body>
指令的修饰符
通过
.
指明指令后缀,封装来不同的处理操作=>简化代码
- 键盘修饰符
@keyup.enter
键盘回车监听
@keyup 监听所有的按键
<input @keyup.enter="add" v-model="todoName" placeholder="请输入任务"/>
- v-model修饰符
v-model.trim
去除首尾空格v-model.number
转数字
<input v-model.trim="username" type="text">
<input v-model.number="age" type="text">
- 事件修饰符
@事件名.stop
阻止冒泡@事件名.prevent
阻止默认行为
<div @click="fatherFn" class="father">
<div @click.stop="sonFn" class="son">儿子</div>
</div>
<a @click.prevent href="http://www.baidu.com">阻止默许行为</a>
计算属性
基于现有的数据,计算出来的新属性,声明在computed配置项中
<p>礼物总数:{{ totalCount }}</p>
...
<script>
data:{
list: [
{ id: 1, name: '篮球', num: 1 },
{ id: 1, name: '篮球', num: 1 },
{ id: 1, name: '篮球', num: 1 }
]
},
computed: {
totalCount(){
let total = this.list.reduce((sum, item) => sum + item.num, 0)
return total
}
}
</script>
计算属性完整写法(配置设置的逻辑)
<div id="app">
姓:<input type="text" v-model="firstName"> +
名:<input type="text" v-model="lastName"> =
<span>{{ fullName }}</span><br><br>
<button @click="changeName">改名卡</button>
</div>
...
<script>
const app = new Vue({
el: '#app',
data: {
firstName: '刘',
lastName: '备',
},
methods: {
changeName () {
this.fullName = '黄忠'
}
},
computed: {
// 简写 → 获取,没有配置设置的逻辑
// fullName () {
// return this.firstName + this.lastName
// }
// 完整写法 → 获取 + 设置
fullName: {
// (1) 当fullName计算属性,被获取求值时,执行get(有缓存,优先读缓存)
// 会将返回值作为,求值的结果
get () {
return this.firstName + this.lastName
},
// (2) 当fullName计算属性,被修改赋值时,执行set
// 修改的值,传递给set方法的形参
set (value) {
this.firstName = value.slice(0, 1)
this.lastName = value.slice(1)
}
}
}
})
</script>
watch侦听器
监听数据变化,执行业务逻辑或异步操作
<script>
data: {
words:
user: {
age: ''
}
},
watch: {
words(newValue, oldValue){
console.log(newValue)
},
'user.age'(newValue){
console.log(newValue)
}
}
</script>