1.vue简介
vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动.
vue:基于mvvm(modal-view-viewmodel)设计模式的前端设计框架,其中的vm可以理解为mvc当中的controller,把数据渲染到页面的桥梁。采用的组件化思想去构建页面,把一个页面分成多个组件,组件可以重复使用,每个组件包含数据、样式和模板,把每个组件合并起来就可以完成一个完整的项目。
vue特点:响应式数据,组件化思想,组件复用,虚拟dom使用
2.vue的基本使用
创建一个组件对象,如果组件对象有el配置,这个组件是根组件,一个项目只有一个根组件,根组件的数据是通过data配置,是一个对象类型
var app = new Vue({
el:"#app",//vue对象和模板进行关联
data:{
// data里面都具有响应式的效果
name:"张三",
age:10,
第:20
},
// create(){} 组件的生命周期函数
})
插值语法和属性赋值
<div id="app">
<!-- 组件里面的data数据可以使用插值语法 {{}} -->
<p>{{name}}</p>
<!-- title=name title的属性值为name这个字符串 -->
<p title="name">{{name}}</p>
<!-- 设置属性和属性值,属性值为data里面的某个数据,添加title属性的时候不能直接添加,需要是vue语法 -->
<!-- 绑定属性时候是通过 :属性 进行绑定 -->
<p :title='name'>{{第}}</p>
<p :id='age'>{{age}}</p>
<!-- 插值语法一般是用在标签内容区间,添加vue属性时候,一般不使用插值语法 -->
<input type="text" value="name">
<input type="text" :value="name" >
<!-- v-model双向绑定指令:用户进行修改,所有绑定的数据name也跟着修改了,数据修改了页面也会变化 -->
<input type="text" v-model="name">
</div>
3.v-model的使用
v-model是双向响应,也就是说用户也可以进行修改从而改变页面数据,一般用在input标签
先创建一个组件对象
var app = new Vue({
el:"#app",
data:{
v1:"edg"
,v2:true
,arr:['basketball','code','handsomebeautiful']
,v3:"男"
,v4:"李白"
}
})
在body里使用v-model
<div id="app">
<!-- 1.如果输入框是text,v-model可以绑定一个字符串类型,绑定数据就是value属性值,等同于给input设置了value属性 -->
<input type="text" v-model="v1">
<!-- 验证用户手动输入数据的时候,p标签可以看到效果 -->
<p>{{v1}}</p>
<!-- 2 如果input标签只有一个多选框时候,v-model可以绑定一个布尔值-->
<input type="checkbox" v-model='v2' >
<p>{{v2}}</p>
<!-- 3 input标签如果是checkbox,并且绑定的是数组,数组里面的元素和该元素的value值一致,这时候checkbox就处于选中状态 -->
<label>爱好:</label>
<br>
<input type="checkbox" name="hobby" v-model="arr" value="basketball">篮球
<input type="checkbox" name="hobby" v-model="arr" value="code">代码
<input type="checkbox" name="hobby" v-model="arr" value="handsomebeautiful">美女帅哥
<p>{{arr}}</p>
<!-- 4 input如果是radio,v-model可以绑定一个字符串变量,如果字符串变量和value值一致,radio就处于选中状态 -->
<label for="">性别</label>
<input type="radio" name="sex" v-model="v3" value="男">男
<input type="radio" name="sex" v-model="v3" value="女" >女
<p>{{v3}}</p>
<!-- 5 option的value属性的默认值就是option的内容 selected默认选中。
v-model可以绑定一个字符串变量,选择一个option的时候,双向绑定的变量就是选中option的value值-->
<select v-model="v4">
<option>李白</option>
<option>亚索</option>
<option>螳螂</option>
</select>
<p>{{v4}}</p>
</div>
4.属性的绑定
先创建一个组件对象
var app = new Vue({
el: "#app",
data: {
msg:"你好"
,c1:"color"
,arr:['color','border','font']
,obj:{
color:true
,border:false
,font:false
}
,obj2:{
color:"blue"
,fontSize:"30px"
,backgroundColor:"green"
}
}
})
设置的样式
<style>
.color{
color: red;
}
.border{
border: 1px solid #000;
}
.font{
font-size: 20px;
}
</style>
在body里对属性进行绑定
<div id="app">
<p v-bind:id='msg'>通过v-bind进行属性绑定 原始写法</p>
<p :id='msg'>v-bind简化后的写法</p>
<p :class='c1'>如果说绑定的是字符串,字符串就是类名</p>
<p :class='arr'>给class属性绑定一个数组,数组元素可以是类名的集合</p>
<input type="checkbox" name="style" v-model='arr' value="color">
<input type="checkbox" name="style" v-model='arr' value="border">
<input type="checkbox" name="style" v-model='arr' value="font">
<p>{{arr}}</p>
<p :class="obj">class绑定对象,对象属性是类名,对象的属性值是bool值,true代表存在,false代表不存在</p>
<p :style='obj2'>style属性可以绑定对象,对象的属性是样式,属性值就是样式值</p>
</div>
5.事件绑定
绑定事件通过@符号进行书写
样式
<style>
.color{
color: red;
}
.border{
border: 1px solid #000;
}
.font{
font-size: 20px;
}
</style>
在body里进行事件绑定
<div id="app">
<!-- 1绑定的时候不带(),默认把事件对象传递事件函数里面,第一个参数是事件对象 -->
<button v-on:click='f1'>通过v-on进行事件绑定</button>
<!-- 2绑定方法的时候如果想把事件对象传递进行,可以把通过$event,把事件对象传递过去 -->
<button @click='f1($event)'>可以简写成@click</button>
<!-- 3把事件对象作为事件函数的第一个参数 -->
<button @click='f2($event,10)'>绑定的时候既传递事件对象也传递其他的数据</button>
<p>字符串拼接{{name+age}}不建议这样写 </p>
<p>字符串拼接{{name}}{{age}}建议这样写 </p>
<!-- 4箭头函数 -->
<button @keydown='f4'>事件函数是一个箭头函数</button>
<!-- 5获取焦点和失去焦点 -->
<input type="text" @focus='f5' @blur='f6'>获取焦点</input>
</div>
创建一个组件对象
var app = new Vue({
el: "#app",
data: {
name:"zz",
age:100000
},
methods:{
//添加模板里面使用的函数
f1(e){
console.log(e);//
console.log(event);//内置的事件对象
console.log(this);//app组件对象
},
f2(e,a){
console.log(e);
console.log(a);
console.log(this._data.name);//zz 不建议采用这种方式进行访问,带下划线的属性都是隐藏属性
console.log(this.name);//zz 建议这样访问
this.age = this.age+1
},
f4:()=>{
console.log(this);//window
},
f5(e){
e.target.style = "outline:1px solid red"
},
f6(e){
e.target.style = ''
}
}
})
6.v-if的使用
v-if是条件渲染的指令,如果v-if为true,该标签显示. 通过v-if进行元素的显示和隐藏,显示的时候是元素创建,隐藏的时候是元素删除,一般的一些切换比较频繁的组件不建议使用v-if,重复的创建和删除导致性能降低。vue里面对v-if进行处理,如果删除一个组件,会把这个组件进行缓存一份,如果再次通过v-if显示/创建该组件的时候,这个时候从缓存取出组件,再进行显示,通过从缓存里面找到删除的组件的方式从而提升v-if的效率
<div id="app">
<p v-if='show'>v-if</p>
<p v-else>v-else和v-if条件相反的,v-else成立了该标签就显示</p>
<input type="text" v-model='score'>
<p v-if='score>=90&&score<=100'>very good</p>
<p v-else-if='score>=80&&score<90'>good</p>
<p v-else-if='score>=70&&score<80'>low good</p>
<p v-else>bad</p>
<p>{{show?"男":"女"}}</p>
<p v-if='show?10:0'>看看</p>
<p v-show='show'>v-show显示和隐藏组件的指令,通过css样式display=none/block进行元素的显示和隐藏</p>
<button @click='changeShow'>点击切换显示</button>
</div>
创建组件对象
var app = new Vue({
el: "#app",
data: {
show:false
,score:99
}
,methods:{
changeShow:function(){
this.show=!this.show
}
}
})
7.v-for的使用
循环指令 可以对数字进行循环
注意:不可以在根元素中使用v-for
<div id="app">
<p v-for='n in 3'>{{n}}</p>
<!-- b数组元素 i数组元素索引 :key属性是元素的唯一标识,在循环渲染的时候一般需要把key属性进行设置,属性不能一样,在更新组件可以根据key值找到要更新的组件,从而提升页面渲染的速率-->
<div v-for="(b,i) in books" :key='i'>
<p>{{i}}</p>
<p>{{b.name}}</p>
<p>{{b.price}}</p>
<p>{{b.count}}</p>
</div>
<div v-for="(b,i) in books" :key='i+10'>
<p>{{i}}</p>
<p>{{b.name}}</p>
<p>{{b.price}}</p>
<p>{{b.count}}</p>
</div>
</div>
创建组件对象
var app = new Vue({
el:"#app" ,// vue对象和模板进行关联
data:{
books:[
{
id:1,
name:"vue从入门到放弃",
price:1000,
count:1000
},
{
id:2,
name:"PHP基础",
price:10,
count:10
},
{
id:3,
name:"java",
price:1000,
count:1000
},
]
},
methods:{
}
})
8.过滤器的使用
过滤器在vue2中可以使用,在vue3中被删掉了,选择用计算结果取代了过滤器,这里简单介绍下过滤器,想要了解更多的小伙伴可以参考vue官网
过滤器:data里面的数据在渲染之前可以通过过滤函数对数据进行加工和处理之后再进行渲染,分为全局过滤器和局部过滤器,本质就是一个函数,通过函数调用的方式使用过滤器,一个数据可以连着使用多个过滤器,过滤器之间需要|进行分割。vue3里面把过滤器配置移除了,vue3中建议使用computed计算结果替代过滤器。
全局过滤器:参数1 过滤器的名字,参数2 回调函数(回调函数里有2个参数,第一个是过滤之前的数据,第二个是调用过滤函数传递过来的参数)。过滤器分为全局过滤器和局部过滤器。全局过滤器可以在任何一个组件去使用,在框架开发的时候,一般把过滤器写成一个单独的js文件,在需要使用的组件里进行导入。
Vue.filter("dataFormat",function(pre,e){
console.log(pre,e);
return Math.floor(pre/10000).toFixed("2")+e
})
局部过滤器:在组件对象里面配置的就是局部的组件,只能使用在该组件里面。
var app = new Vue({
el:"#app",
data:{
count:983434
},
// 计算结果
computed:{
},
// 在组件对象里面配置的就是局部的组件,只能使用在该组件里面
filters:{
// 过滤器名字
dataF(pre,e){
console.log(pre,e);
return e+pre
}
}
})
过滤器的使用方法
<div id="app">
<!-- 过滤的数据|过滤器() -->
<p>{{count|dataFormat("万")|dataF("♥")}}</p>
</div>
9.组件注册
全局注册组件:可以在其他组件中使用。
在组件里面使用template:后面直接跟模板字符串
// 全局注册组件,参数1组件名字,参数2组件配置的属性
Vue.component("inputBox", {
// 组件的模板配置:1有且仅有一个根节点 2标签必须要有闭合标签(单标签加斜杠)
template: `<div>
<img src='stm.jpg' />
{{age}}
</div>`,
// 非根组件data值是一个函数,在函数里面return一个对象
data() {
return {
age: 10
}
},
methods:{
},
filters:{
}
})
使用组件:1必须用横线分割法使用 2命名的时候可以使用横线分割法,大驼峰命名、小驼峰命名法则都可以。定义组件名字按照大驼峰方式进行命名,使用的时候按照横线分割法使用。
<input-box></input-box>
局部注册组件:只能在该组件里使用
// 根组件
var app = new Vue({
el: "#app",
data: {
count: "983434",
},
// 本组件里面需要使用其他的组件,定义一些局部的组件
components:{
com1:{
template:`<p>你好啊</p>`
}
}
})
在该组件使用局部组件
<div id="app">
<com1></com1>
<!-- 局部注册组件:只能在该组件里使用 -->
</div>
运用script标签创建模板进行注册组件
在组件里面使用template:后面跟的是script的id,需要设置script的type字段=text/html
<script type="text/html" id="s1">
<div>
<p>{{age}}</p>
</div>
</script>
<script type="text/html" id="s2">
<div>
<p>局部组件的模板</p>
</div>
</script>
注册组件
// 全局注册组件,参数1组件名字,参数2组件配置的属性
Vue.component("InputBox",{
template:`#s1`,
data(){
return{
age:10
}
},
components:{
}
})
// 根组件
var app = new Vue({
el: "#app",
data: {
count: "983434",
},
// 本组件里面需要使用其他的组件,定义一些局部的组件
components:{
com1:{
template:`<p>你好啊</p>`
},
com:{
template:"#s2"
}
}
})
10.计算结果
计算结果和函数和过滤器的区别
1计算结果使用的是缓存,如果计算结果所依赖的data数据没有发生变化,计算结果不会再次执行,计算结果使用上次计算的缓存,不会重新执行,函数每次调用都会去执行一次
2.计算结果定义在computed里面,函数和过滤器分别定义在methods和filters
3.计算结果使用的时候像data里面数据一样使用,函数和过滤器使用的时候像函数调用的方式使用。
// 根组件
var app = new Vue({
el: "#app",
data: {
msg:"hello"
},
methods:{
order(){
console.log("函数调用了几次");//每用组件一次就调用一次函数
return this.msg.split("").reverse().join('-')
}
},
// 计算结果的配置
computed:{
sum:function(){
console.log("计算调用了几次");//数据相同使用缓存里的,不再调用
return this.msg.split("").reverse().join('-')
}
}
})
使用组件检验
<div id="app">
<!-- 调用函数 2次 -->
<p>{{order()}}</p>
<p>{{order()}}</p>
<!-- 使用计算结果 1次 -->
<p>{{sum}}</p>
<p>{{sum}}</p>
</div>
11.nextTick的使用
数据在更新之后,dom是不会立马进行更新渲染,vue会把多个数据要更新的操作放在一个事件循环里面,在一个事件循环结束之后统一进行更新操作,进而提升页面渲染的效率。第一种使用方法,在created函数里进行使用nextTick
created() {
this.msg = "ss" // 更新数据
console.log(document.getElementById("p1").textContent);//{{msg}}
// 如果想在created通过操作获取更新之后值,怎么获取?
Vue.nextTick(function(){ //组件的异步更新,在回调函数里面通过操作dom获取更新之后的值.nextTick对应的是mounted这个钩子函数
console.log(document.getElementById("p1").textContent);//ss
})
},
第二种使用方法,在组件外部进行数据更新,操作如下
app.msg = "你好" //可以直接通过app对象.data里面的字段进行更新
console.log(app.$el.textContent);//hello 未更新之前
Vue.nextTick(function(){
console.log(app.$el.textContent);//你好 更新后的数据
})
12.ref的用法
Ref主要的功能有:
1获取页面的dom元素,和子组件中的标签
<div id="app">
<!-- this.refs:对象包含了具有ref属性的节点的集合 -->
<p ref="title">{{msg}}</p>
<p ref="text">{{msg}}</p>
<com1 ref="r1"></com1>
</div>
<script>
Vue.component("com1",{
template:`<div>
<p ref='p1'>你好</p>
</div>`
})
var app = new Vue({
el:"#app"
,data:{
msg:"11"
}
created() {
console.log(this.msg); // 11 data数据已经加载
console.log(this.$el); // undefined dom还没加载
console.log(this.$refs); // object 包含title这个dom节点
console.log(this.$refs.title); // undefined 因为在这还没生成虚拟dom,数据没挂载
},
mounted() {
console.log(this.$refs.title);// <p> p标签
console.log(this.$refs.r1.$refs.p1);// <p> 子组件内的标签
},
})
</script>
2获取子组件的data或者方法,
<template>
<div id="app">
<HelloWorld ref="hello"/> //子组件
<button @click="getHello">获取helloworld子组件中的值</button>
</div>
</template>
<script>
export default {
components: {
HelloWorld //子组件
},
data() {
return {}
},
methods: {
getHello() {
}
//获取子组件中data的msg
console.log(this.$refs.hello.msg)
//获取子组件中methods中的open方法
console.log(this.$refs.hello.open())
}
};
</script>