认识vue
链接
<scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
Vue.js 是一套构建用户界面的渐进式框架
为什么要使用vue?
- 虚拟DOM :性能高
-
- 数据驱动试图
- 组件化:
- 数据与视图分离
基本语法
<div id="app">
{{ message }}//双大括号插值表达式
</div>
<script>
var app = new Vue({
el: '#app',//挂载点
data: {//集中存放所有的vue数据,数据统一存放在data中
message: 'Hello Vue!'
}
})
</script>
双大括号插值表达式:双大括号其实提供了一个js执行环境,可以写任意js表达式,(只能识别表达式和值)不识别html结构
一个元素中可以有多个插值表达式
指令
v-html
把一段html结构渲染到它所绑定的元素中
如果元素本身内部有内容,会被指令中的内容覆盖掉
<div id="app" v-html="inner"></div>
<script>
new Vue({
el:"#app",
data:{
inner:"<h1>你好</h1>"
}
})
</script>
v-text
把一段文本内容渲染到它所绑定的元素中
v-bind
动态绑定属性
v-bind:属性名="数据"
:属性名="数据"
v-bind的特殊情况
- class
- 可以绑定一个字符串,字符串名就是class名
- 可以绑定一个对象,对象的属性名就是class名,对象的属性值是布尔,代表是否有这个class
- 可以绑定一个数组,数组里是变量名,变量值就是class名字
- style
- 绑定到一个对象,对象就是样式对象
- 绑定到一个数组,就是绑定到多个样式对象
<div id="app">
<h1 v-bind:id="a" v-bind:class="b">{{msg}}</h1>
//可以简写成<h1 :id="a" :class="b">{{msg}}</h1>
</div>
<script>
let myVue = new Vue({
el:"#app",
data:{
a:"box",
b:"title",
msg:"hello"
}
})
</script>
v-on
//v-on:事件名="函数名" 缩写为 @事件名=“函数”
<div id="app">
//函数如果有参数,在指令里面直接加括号就行了,没有参数就不需要加括号
<button @click="fn(5)">按钮</button>
<input type="text" @focus="change">
</div>
<script>
new Vue({
el:"#app",
methods:{
fn(m){
console.log(m);
},
change(){
alert(456);
}
}
})
</script>
关于事件对象:
v-on:事件名="(e)=>{fn(e,arg)}"
<div id="app">
<button @click="fn(e,5)">按钮</button>
</div>
<script>
new Vue({
el:"#app",
methods:{
fn(m,n){
console.log(m,n);
}
}
})
</script>
按键修饰符:
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键
<input v-on:keyup.enter="submit">
<input v-on:keyup.page-down="onPageDown">
为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
.enter(常用)
.tab
.delete(捕获“删除”和“退格”键)
.esc(退出键)
.space(空格键)
.up
.down
.left
.right
v-if v-else
控制整个元素是否渲染,不是基于样式的, 是真正的条件渲染
<h1 v-if=" grades=='A' ">优秀</h1>
<h1 v-else-if="grades=='B'">良好</h1>
<h1 v-else-if="grades=='C'">及格</h1>
<h1 v-else>不及格</h1>
注意,使用v-if的时候
- v-if的元素是和v-else必须是同级
- v-if的元素和v-else的元素必须紧挨着,中间不允许夹杂其他元素
v-show+true/false
是基于样式的切换,并不是真正的条件渲染
<div id="app">
<div class="box" v-show="show"></div>
<button @click="toggle">按钮</button>
</div>
<script>
new Vue({
el:"#app",
data:{
show:true
},
methods:{
toggle(){
this.show=!this.show
}
}
})
</script>
v-if 与 v-show的性能对比
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
v-for
基本用法
<div id="app">
<select>
<option v-for="item in provinces">
{{item}}
</option>
</select>
</div>
<script>
new Vue({
el:"#app",
data:{
provinces:["山东省","浙江省","江苏省","广东省"]
},
})
</script>
用途:
- 可以循环数组 value index
- 可以循环对象 value key index
- 可以循环整数 item
注意:v-if和v-for尽量避免同时使用:因为v-for的优先级比v-if更高,可能会优先执行v-for
template的用法:
先来看一个需求:下图div用v-for做了列表循环,现在想要span也一起循环,应该怎么做?
有3种方法可以实现
①:直接用v-for对span也循环一次** (该方法虽然可以使用,但不要用这种方式,因为以后你会哭)
****
②:在div和span外面包裹一个div,给这个div加循环(该方法会额外增加一个多余的div标签)
③:若你不想额外增加一个div,此时应该使用template来实现 (推荐)
template的作用是模板占位符,可帮助我们包裹元素,但在循环过程当中,template不会被渲染到页面上
key的作用
为什么需要key?
当你不希望你的程序复用某个标签就可以加key
案例:
<div id="app">
<input type="text" v-if="see" key="a"/>
<input type="password" v-else key="b"/>
//当你不希望你的程序复用某个标签就可以加key
<button @click="change">更改</button>
</div>
<script>
new Vue({
el: '#app',
data: {
see:true
},
methods:{
change(){
this.see=false
}
}
})
</script>
响应式原理
由于 JavaScript 的限制,Vue 不能检测数组和对象的变化
对于对象来说:
property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的
对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property
//可以使用如下方法嵌套对象添加响应式 property
Vue.set(object, propertyName, value)
例如:
Vue.set(this.obj, "salary", 3500)
意思是将想修改的对象的salary属性改为3500
对于数组来说:
直接通过角标赋值是无法设置为响应式的
直接修改长度也是无法设置为响应式的
//可以使用如下方法为数组添加响应式 property
Vue.set(vm.items, indexOfItem, newValue)
例如:
Vue.set(this.search, 1, 8)
意思是将想修改的数组的角标为1的值改为8
数组更新方法
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
v-model
基本使用
表单的双向绑定
v-model默认绑定到表单的value属性
- 多选框: 单个多选框,绑定到布尔值,多个复选框,绑定的是数组
//多选框: 单个多选框,绑定到布尔值,多个复选框,绑定的是数组
<div id="app">
<input type="checkbox" v-model="search" value="篮球">
<input type="checkbox" v-model="search" value="足球">
<h1>{{search}}</h1>
</div>
<script>
new Vue({
el:"#app",
data:{
search:[]
}
})
</script>
- 单选框:值直接绑定到值
//单选框:值直接绑定到值
<div id="app">
<input type="text" v-model="search">
<h1>{{search}}</h1>
<button @click="change">获取</button>
</div>
<script>
new Vue({
el:"#app",
data:{
search:""
},
methods:{
change(){
console.log(this.search);
}
}
})
</script>
- 下拉选择框:直接绑定到值
//下拉选择框:直接绑定到值
<div id="app">
<select v-model="search">
<option value="1">男</option>
<option value="2">女</option>
</select>
<h2>{{search}}</h2>
</div>
<script>
new Vue({
el:"#app",
data:{
search:[]
}
})
</script>
双向绑定也可以绑定到数组的某一项或者对象的某一项
双向绑定案例:
<div id="app">
<input type="text" value="item" v-model="todo">
<button @click="add">添加</button>
<div>
<ul>
<li v-for="(item,index) in list" :key="index" @click="remove">{{item}}</li>
</ul>
</div>
</div>
<script>
new Vue({
el:"#app",
data:{
todo:"",
list:[]
},
methods:{
add(){
this.list.push(this.todo);
this.todo=""
},
remove(){
this.list.splice("index",1)
}
}
})
</script>
修饰符
在“change”时而非“input”时更新
<input v-model.lazy="msg">
如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符
<input v-model.number="num">
如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符
<input v-model.trim="msg">
methods
方法(函数)的集合,鼓励使用ES6的形式
computed(配置项:计算属性)
methods方法的弊端是:因为vue是数据驱动视图,所以每更改一次数据都要调用一次函数,所以有些时候的有些数据不需要更改就可以使用计算属性,使他不用每一次的更改其他数据时也被调用
计算属性的特点:
- 计算属性是个函数,要求一定有返回值
- 不能和data中的数据重名
- 计算属性是基于缓存的,只有在他计算依赖的项有变化的时候他才会重新运算,否则不运算
依赖:函数中用到的数据有变化,那么计算属性才会重新运行。
- 计算属性最终的结果是个属性,不能加括号,使用的时候直接写计算属性的名字,不加括号
- 计算属性也是可以传参的,只需要让返回值是个函数即可
计算属性跟函数的区别?
1.计算属性一定要返回值,函数不一定
2.函数需要主动调用,计算属性依赖的项变化的时候才执行
3.计算属性比函数性能高,因为是基于缓存的
案例:
<div id="example">
<p>原始数据: "{{ message }}"</p>
<p>使用计算属性(Computed)反转 message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
watch
定义:
监听某个数据,只要该数据变了,就会执行函数
1.函数名必须是一个已存在的数据名,函数名即是你所监听的数据名
2.首次加载不执行,只有在后续数据变化的时候才会运行
3.检测的数据可以是data中的,也可以是computed
<div id="app">
<h1>{{gender}}</h1>
<h1>{{b}}</h1>
<h1>{{msg}}</h1>
<button @click="change">更改</button>
</div>
<script>
new Vue({
el:"#app",
data:{
msg:"hello",
a:1,
b:2
},
methods:{
change(){
this.a=2;
}
},
computed:{
gender(){
return this.a==1?"男":"女"
}
},
watch:{
gender(){
console.log("gender变了");
//输出了,证明watch随着事件的改变而执行
}
}
})
</script>
computed和watch的异同点?
区别:
1.计算属性是返回一个值,watch是监听一个值做某件事情的。
2.计算属性是值变化的时候重新运算,watch值变化的时候执行函数
3.watch是干事的,computed是给值的
共同点:
都不需要主动调用