Vue的核心特性是:响应式
而响应式,也就是数据变化,视图自动更新
- Vue是一个用于 构建用户界面 的渐进式框架
- 构建用户界面:基于数据渲染出用户看到的页面
第一个Vue程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 准备容器 -->
<div id="app">
<!-- 这里会写一些用于渲染的代码逻辑 -->
<!-- 这个双括号是插值表达式 -->
<h1>{{ msg }}</h1>
{{ count }}
</div>
<!-- 引包(开发版本,包含完整的注释和警告) -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
//一旦引入了VueJS核心包,在全局环境中,就有了Vue构造函数
const app=new Vue({
//通过el去配置选择器,指定Vue管理的是哪个盒子
el:'#app',
//通过data提供渲染数据
data:{
msg:'Hello Vue',
count:666
}
})
</script>
</body>
</html>
1. 插值表达式(双花括号)
- 一种Vue的模板语法
- 利用表达式来进行插值,渲染到页面中
- 注意:
-
1.使用的数据必须存在(data)
-
2.支持的是表达式,而非语句
-
3.不能在标签的属性中<>使用{{}}只插
-
4.插值表达式不具备解析标签的能力,所以如果有这方面的需求,需要指令来实现
-
2. Vue指令
Vue会根据不同的 指令,针对标签实现不同的 功能
- 指令:带有
v-前缀的特殊标签属性
<!-- Vue指令 -->
<div v-html="str"></div>
<!-- 普通标签属性 -->
<div class="box"></div>
<div title="click"></div>
v-html
v-html
动态设置元素的innerhtml
语法:
v-html="表达式"
< div>{{msg}}< /div>这个是无效的,因为插值表达式并不具备解析标签的能力
<div id="app">
<!-- <div>{{msg}}</div>这个是无效的 -->
<div v-html="msg"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
el:'#app',
data:{
msg:'<a href="http://www.itheima.com">百度</a>'
}
})
</script>
v-show 和 v-if
v-show (后是等于号=)
- 控制元素显示隐藏
- 语法
v-show="表达式",表达式为true显示,false隐藏它的本质是通过css的display:none来隐藏的,检查可以看到盒子依然存在,只是被隐藏
v-if(后是等于号=)
- 控制元素显示隐藏(条件渲染)
- 语法
v-if="表达式",,表达式为true显示,false隐藏它的本质是根据判断条件,来控制元素的创建和移除,所以隐藏就是移除,检查的时候就显示没有这个盒子
根据你的条件,要么显示,要么隐藏
v-else 和 v-else-if
v-else
- 辅助v-if进行判断渲染
- 语法:
v-else,后不跟表达式
v-else-if(后面是等于)
- 辅助v-if进行判断渲染
- 语法:
v-else-if="表达式"
v-on
v-on(后面是冒号)
- 用来 注册事件=添加监听+提供处理逻辑
- 语法:
v-on:事件名="内联语句"
- 内联语句(也就是一段可执行的代码)、
- 它更相当于一种行内写法
v-on:事件名="methods中的函数名"v-on:有一个简写的方式,就是把这一部分直接用@代替- v-on的调用传参 fn(参数)
v-on:事件名="内联语句"比如可以做一个购物车商品加减效果
<div id="app">
<button v-on:click="count--">-</button>
<span>{{count}}</span>
<button v-on:click="count++">+</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
el:'#app',
data:{
count:100
}
})
</script>
v-on:事件名="methods中的函数名"
- data上的数据是挂在你const的实例上的,所以在对data中数据的变动时,都需要加上它的实例名前缀
- 提供的所有methods中的函数,this都指向当前实例
- 也就是说你的
实例名=this
<div id="app">
<button @click="fn"> 显示隐藏</button>
<span v-show="flag">购物车页面</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
el:'#app',
data:{
flag:true
},
methods:{
fn(){
app.flag=!app.flag
}
}
})
</script>
v-bind
v-bind
- 动态设置html的标签属性(比如src、url、title)
- 语法:
v-bind:属性名="表达式"- 它的简写方式是省略v-band,直接写比如
:src冒号属性名
Vue指令案例:图片切换
<div id="app">
<button v-show="index>0" @click="index--">上一页</button>
<img :src="pic_list[index]" alt="" style="width: 200px;">
<button v-show="index<pic_list.length-1" @click="index++"> 下一页</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
el:'#app',
data:{
index:0,
pic_list:[
'./pic/1.jpg',
'./pic/2.jpg',
'./pic/3.jpg',
'./pic/4.jpg'
]
}
})
</script>
v-for
v-for
- 基于数据循环,多次渲染整个元素
- 它可以遍历:数组、对象、数字...
- 语法:
v-for="(item,index) in 数组"
<div id="app">
<h1>水果铺</h1>
<ul>
<li v-for="(item,index) in list">
{{item}} - {{index}}
</li>
</ul>
<!-- 如果只需要显示item,那么可简写成下面这样 -->
<h1>水果铺2</h1>
<ul>
<li v-for="item in list">
{{item}}
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
el:'#app',
data:{
list:['西瓜','草莓','哈密瓜','香蕉']
}
})
v-for中的key
<li v-for="item in book_list" :key="item.id">
- 语法:key属性="唯一标识"
- 作用:给列表项添加的唯一标识。便于vue进行列表项的正确排序复用
- v-for不写key,默认行为会尝试原地修改元素(就地复用),删除一个内容后,其它内容顺次往前移
- key的值只能是字符串或数字类型
- key的值必须具有唯一性
- 推荐使用id为key(唯一),不推荐使用index作为key(会变化,不对应)
图书管理案例——小黑的书架
- 页面渲染 v-for
- 删除列表中数据 v-on:click=""
这个跟之前写过的一个购物车显示隐藏的案例原理并不太相同。
- 这个由于你用了v-for循环渲染,所以如果再直接用之前显示隐藏中改变flag布尔值的方式的话,会一下把所有的数据都删掉
- 所以这里的思路是:由于vue是响应式布局,所以我们只需想办法通过删除列表中的数据则可同步实现页面响应删除
- 而我们 删除列表对应项 有两种思路
- 1.根据index下标删
- 2.根据id删(建议优先使用这个,id是唯一标识,更加稳定)
- 用filter(根据条件,保留满足条件的对应项,得到一个新数组,但是 并不会改变原数组)
- 所以就需要将得到的新数组再赋值回给原数组
- 所以综上就是这一句
this.book_list=this.book_list.filter(item => item.id!==id),并配合上面的@click="del(item.id)"
<div id="book">
<h1>小黑的书架</h1>
<ul>
<li v-for="item in book_list" :key="item.id">
<span>{{item.name}}</span>
<span>{{item.author}}</span>
<button @click="del(item.id)" >删除</button>
<!-- 必须是item.id,而不是直接写id -->
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const book=new Vue({
el:'#book',
data:{
book_list:[
{id:1,name:'《黑莲花攻略》',author:'小美'},
{id:2,name:'《莲花楼》',author:'小花'},
{id:3,name:'《沉香如屑》',author:'唐周'},
{id:4,name:'《一念关山》',author:'小帅'}
]
} ,
methods:{
del(id){
this.book_list=this.book_list.filter(item => item.id!==id)
}
}
})
</script>
v-model
v-model
- 给表单元素使用,双向数据绑定——>可以快速 获取 或 设置 表单元素内容
- 双向数据绑定:
- 数据变化——>视图自动更新
- 视图变化——>数据自动更新
- 语法:
v-model=‘变量’
v-model应用于表单元素
- 输入框 input
比如:用户登录界面的数据
<div id="app">
账户:<input type="text" v-model="username"><br><br>
密码: <input type="password" v-model="password"><br><br>
<button @click="log">登录</button>
<button @click="reset">重置</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
const app=new Vue({
el:'#app',
data:{
username:'',
password:''
} ,
methods:{
log(){
console.log(this.username,this.password)
},
reset(){
this.username=''
this.password=''
}
}
})
</script>
- 文本域 textarea
- 复选框 input:checkbox
- 单选框 input:radio
- 下拉菜单 select
小黑学习网
<div id="app">
<h3>小黑学习网</h3>
姓名:
<input type="text" v-model="username">
<br><br>
是否单身:
<input type="checkbox" v-model="isSingle">
<br><br>
<!--
前置理解:
1. name: 给单选框加上 name 属性 可以分组 → 同一组互相会互斥
2. value: 给单选框加上 value 属性,用于提交给后台的数据
文本是为了给用户看的,真正后台提交的数据是给value值
结合 Vue 使用 → v-model
-->
性别:
<input type="radio" v-model="gender" name="gender" value="1" >男
<input type="radio" v-model="gender" name="gender" value="2">女
<br><br>
<!--
前置理解:
1. option 需要设置 value 值,提交给后台
2. select 的 value 值,关联了选中的 option 的 value 值
结合 Vue 使用 → v-model
-->
所在城市:
<select v-model="cityId">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">成都</option>
<option value="104">南京</option>
</select>
<br><br>
自我描述:
<textarea v-model="own"></textarea>
<button>立即注册</button>
</div>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
username:'',
isSingle:false,
gender:'1',
cityId:'101',
own:''
}
})
</script>
小黑记事本
在vue中,trim是指在处理表单输入时自动去除输入字符串两端的空白字符
- 列表渲染
- 删除功能
- 添加功能
- 底部统计 和 清空
<!-- 主体区域 -->
<section id="app">
<!-- 输入框 -->
<header class="header">
<h1>番茄记事本</h1>
<input 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">
<div class="view">
<span class="index">{{index+1}}</span> <label>{{item.name}}</label>
<button class="destroy" @click="del(item.id)"></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 @click="cut" class="clear-completed">
清空任务
</button>
</footer>
</section>
<!-- 底部 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
todoName:'',
list:[
{id:1,name:'一天八杯水'},
{id:2,name:'期末周看完莲花楼'},
{id:3,name:'五天看完59集沉香如屑'}
]
},
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=''//添加完之后输入框内自动清空
},
cut(){
this.list=[]
}
}
})
</script>