什么是Vue?
-
一套用于构建用户界面的渐进式框架
-
采用自下向上增量开发的设计
-
核心库只关注视图层,易于上手
-
可驱动采用单文件组件和Vue生态系统支持的库开发复杂单页面应用
为什么使用Vue?
1,声明式渲染
vue.js核心就是一个允许采用简洁的模块语法来声明式的将数据渲染进DOM系统。
2.响应式数据绑定
MVVM
M:Model层
V:View 层
VM: ViewModel层,数据绑定,数据监听
3.组件化开发
它是一种抽象,允许我们使用小型,独立和通常可复用的组件构建大型,独立和通常可复用的组件构建大型应用。
4.虚拟DOM
浏览器处理dom性能是会有瓶颈的,而使用虚拟dom可以减少dom操作,提升渲染性能。
Vue实例
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">{{message}}</div>
<script src="vue.js"></script>
<script>
const data = {
message:"一个vue程序",
str:null //数据必须提前声明,才能在vue中使用
}
//Object.freeze(data) 数据冻结read only
/**
不要在选项 property 或回调上使用箭头函数,比如
created: () => console.log(this.a) 或
vm.$watch('a', newValue => this.myMethod())。
因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,
经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught
TypeError: this.myMethod is not a function 之类的错误。
**/
const app = new Vue({
el:"#app",
data:data,
beforeCreate:function(){
console.log(this)
console.group("beforeCreate实例创建前")
console.log("el===>",this.$el)
console.log("data====>",this.$data)
console.log("message=====>",this.message)
},
created:function(){
console.group("created实例创建完毕")
console.log("el===>",this.$el)
console.log("data====>",this.$data)
console.log("message=====>",this.message)
},
beforeMount:function(){
console.group("beforeMount实例挂载到dom前")
console.log("el===>",this.$el)
console.log("data====>",this.$data)
console.log("message=====>",this.message)
},
mounted:function(){
console.group("mounted实例挂载到dom完毕")
console.log("el===>",this.$el)
console.log("data====>",this.$data)
console.log("message=====>",this.message)
},
beforeUpdate:function(){
console.group("beforeUpdate数据更新前")
console.log("el===>",this.$el)
console.log("data====>",this.$data)
console.log("message=====>",this.message)
},
updated:function(){
console.group("updated数据更新完毕")
console.log("el===>",this.$el)
console.log("data====>",this.$data)
console.log("message=====>",this.message)
},
beforeDestroy:function(){
console.group("beforeDestroy销毁前")
console.log("el===>",this.$el)
console.log("data====>",this.$data)
console.log("message=====>",this.message)
},
destroyed:function(){
console.group("destroyed销毁完毕")
console.log("el===>",this.$el)
console.log("data====>",this.$data)
console.log("message=====>",this.message)
}
})
//app.$el 获取app实例 dom元素
//app.$data 获取实例数据
app.$watch("message",(newval,oldval)=>{console.log(newval,oldval)})//监听数据变化
</script>
</body>
</html>
数据绑定
<style>
.div-class{
color:red
}
.div-class_none{
display: none
}
</style>
<body>
<div id="app">
<!--只能用表达式的写法,不能用语句的写法-->
{{ message + "-" + hoverTitle}}
<!--动态绑定-->
<div v-html=html v-bind:id="myId" v-bind:title="hoverTitle" v-if="isShow"></div>
<h1>{{count}}</h1>
<button v-on:click="handleClick">点击+1</button>
<input type="text" placeholder="请输入内容" v-on:focus="onFoucus" v-on:blur="onBlur"/>
<div>
<!-- 样式绑定 -->
<!-- 字符串的写法 -->
<!-- <div :class="strClass" >Class</div>
<button @click="handleChangeClick">改变class</button>
</div> -->
<!-- 对象的写法 -->
<!-- <div :class="{'div-class':true,'div-class_none':flag}" >Class</div>
<button @click="handleChangeClick">控制class显示</button>
</div> -->
<!-- 数组的写法 -->
<!-- <div :class="[strClass,hiddenClass]" >Class</div>
<button @click="handleChangeClick">控制class显示</button>
</div> -->
<!-- 对象方式 -->
<!-- <div :style="{color:'blue',backgroundColor:'yellow'}" >Class</div>
<button @click="handleChangeClick">控制class显示</button>
</div> -->
<!-- 数组方式 -->
<div :style="[baseStyle,otherStyle]" >Class</div>
<button @click="handleChangeClick">控制class显示</button>
</div>
</div>
<script src="vue.js"></script>
<script>
/*
1.文本绑定:{{}},html -> v-html
2.html属性的一个绑定:v-bind v-bind:id="myId" ->:id="myId"
3.方法的绑定:v-on v-on:click -> @click
4.样式绑定:class style ->v-bind:
class 字符串 对象,数组
style 对象 数组 (是对象方式的集合)
*/
const app = new Vue({
el:"#app",
data:{
message:"数据绑定",
html:"<p>html文本</p>",
myId:"myId",
hoverTitle:"title",
isShow:false,
count:0,
strClass:'div-class',
hiddenClass:"div-class_none",
flag:true,
baseStyle:{
color:'red',
backgroundColor:"yellow"
},
otherStyle:{
backgroundColor:'green',
border:"1px solid orange",
transition:'all 1s'
}
},
methods:{
handleClick(){
this.count++;
},
onFoucus(){
console.log("获取焦点")
},
onBlur(){
console.log("失去焦点")
},
handleChangeClick(){
// this.strClass = 'div-class_none'
// this.flag = !this.flag
this.hiddenClass = ""
}
}
})
</script>
</body>
计算属性与监听属性
<div id="app">
<!-- {{endName}} {{msg}} -->
<!-- {{computedName()}} {{msg}} -->
{{fullName}}
</div>
<script src="vue.js" ></script>
<script>
/**
实现方式:
1.插值表达式
2.computed
3.使用methods里面的方法
4.watch
a.计算属性与监听属性都可以缓存,方法不能实现缓存,
b.一个功能既可以通过计算属性实现,也可以通过watch实现,优先推荐计算属性实现
一对多 -> computed
多对一 ->watch
c.如果不希望有缓存,则使用方法来代替
**/
const app = new Vue({
el:"#app",
data:{
firstName:'王 -',
lastName:'小 哇',
msg:"改变的值",
fullName:"-------"
},
methods:{
//不会缓存,其他变量改变也会触发其改变。
computedName(){
console.log("方法实现")
return this.firstName+ "." + this.lastName
}
},
//响应式缓存,改变其他值不会改变其,其性能更高
computed:{
endName:function(){
console.log("计算属性实现")
return this.firstName+ "." + this.lastName
}
},
//有缓存,多对一适合watch方法,监听一个的值,对多个值进行操作
watch:{
firstName(){
console.log("watch属性firstName一次")
this.fullName = this.firstName+ "." + this.lastName
this.firstName = this.firstName.split(" ").reverse()
this.lastName = this.lastName.split(" ").reverse()
},
lastName(){
console.log("watch属性lastName一次")
this.fullName = this.firstName+ "." + this.lastName
}
}
})
</script>
条件渲染
<div id="app">
<!-- v-if 和v-else必须紧邻 -->
<!-- <p v-if="count===0">{{showMsg}}</p>
<p v-else-if="count===1">其他数据</p>
<p v-else>中间内容</p> -->
<!-- v-show 只是显示隐藏,用于数据量大的情况 -->
<!-- <p v-show="flag">{{showMsg}}</p> -->
<!-- v-show 不能作用于template这种模版标签上 -->
<!-- <template v-if="flag">
<p>1==if</p>
<p>2==if</p>
<p>3==if</p>
<p>4==if</p>
</template> -->
<div v-show="flag">
<div>1==show</div>
<div>2==show</div>
<div>3==show</div>
<div>4==show</div>
</div>
<button @click="handleClick">控制显示隐藏</button>
</div>
<script src="vue.js"></script>
<script>
/**
v-if:正真的条件渲染,惰性,带来更高的切换开销,初始渲染开销减少
v-show:不管条件是什么都会渲染,基于display:none/block,缺点:初始开销大,优点切换开销小
**/
const app = new Vue({
el:"#app",
data:{
showMsg:"显示数据",
flag:true,
count:0
},
methods:{
handleClick(){
this.flag = !this.flag
// this.count++
}
}
})
</script>
列表渲染
<div id="app">
<template v-if="dataArr.length>2">
<!--:key 列表有更新删除,为了提高性能,给个标示,当数据有变化时是数据的移动而不会重新渲染 -->
<ul>
<li v-for="(item,index) in dataArrFilter" :key="index" @click="handleDelete(index)">{{item.name}}---------{{item.id}}-------{{index}}</li>
</ul>
<button @click="change">改变列表项的值</button>
<ul>
<li v-for="(value,key,index) in dataObj">{{value}}======={{key}}========={{index}}</li>
</ul>
<button @click="changeObj">改变列表项的值</button>
</template>
</div>
<script src="vue.js"></script>
<script>
/*
1.数据遍历
v-for="(item,index) in list"
item:遍历数组元素的别名
index:数据元素的索引
list:数据
2.对象的遍历
v-for="(value,key,index) in obj""
3.注意:
1.推荐使用v-for时,带上:key属性
2.数组数据更新,不能通过数组下标进行修改,
变异方法改变列表值可以被检测到
$set
push
pop
shift
unshift
splice
sort
reverse
3.对象数据更新
object.assgin() 可以增加多个数据
v-for 计算属性computed,当循环数据进行判断时,不推荐同时使用v-for,v-if,可以使用v-for,computed
*/
const app = new Vue({
el:"#app",
data:{
dataArr:[
{id:1,name:'🐘'},
{id:2,name:"🐯"}
],
dataObj:{
age:10,
name:"张三"
}
},
methods:{
handleDelete(index){
this.dataArr.splice(index,1)
},
change(){
this.$set(this.dataArr,0,{id:1,name:"🍌"})
this.dataArr.push({id:3,name:"🦊"})
this.dataArr.pop()
},
changeObj(){
this.dataObj.age = 20
this.$set(this.dataObj,"pyhone","11111111")
this.dataObj = Object.assign({},this.dataObj,{address:"xxxxxx",hobby:'学习'})
}
},
computed:{
dataArrFilter:function(){
return this.data.filter(item=>{
return item.id !== 1
})
}
}
})
</script>
事件处理
<div id="app">
<p>{{count}}</p>
<div @click="handleClick">
<button @click.stop.self="handleAdd($event)">点击+1</button>
</div>
<input type="text" placeholder="请输入内容" @keyup.vup="onSumbit"/>
</div>
<script src="vue.js"></script>
<script>
/*
事件修饰符: .stop .self .once .prevent
@ === v-on:click.prevent
按键修饰符
.enter .tab .esc .up
*/
//v -> 86
Vue.config.keyCodes.vup = 86
const app = new Vue({
el:"#app",
data:{
count:0
},
methods:{
handleAdd(){
//尽量纯粹的数据逻辑处理,不处理dom细节
// event.stopPropagation()
this.count++
},
handleClick(event){
console.log("父级")
},
onSumbit(){
console.log("数据提交")
}
}
})
</script>
表单输入绑定
<div id="app">
<p>input输入的值:{{inputValue}}</p>
<!-- 如果input使用了数据绑定,就会忽略input本身的value值 -->
<input type='text' placeholder="请输入" value="value初始值" v-model.number="inputValue"/>
<p>input输入的值:{{textareaValue}}</p>
<!-- uuuuuuu不会生效 -->
<textarea name="" id="" cols="30" rows="30" v-model="textareaValue">uuuuuuu</textarea>
<!-- 单项绑定 -->
<!-- <input type="checkbox" id="boy" v-model="checkboxVaue"/> -->
<label for="boy">{{checkboxVaue}}</label>
<!-- 多项绑定 -->
<input type="checkbox" id="children" value="children" v-model="checkboxArr"/>
<label for="children">{{checkboxArr}}</label>
<input type="checkbox" id="sister" value="sister" v-model="checkboxArr"/>
<label for="sister">{{checkboxArr}}</label>
<input type="checkbox" id="brother" value="brother" v-model="checkboxArr"/>
<label for="brother">{{checkboxArr}}</label>
<input type="radio" id="girl" value="girl" v-model="sex"/>
<label for="girl">{{sex}}</label>
<input type="radio" value="boy" v-model="sex"/>
<label for="boy">{{sex}}</label>
<p>{{userinfo}}</p>
<select v-model="userinfo" multiple>
<option value="" disabled>请选择</option>
<option value="age" >年龄</option>
<option value="name" >姓名</option>
</select>
</div>
<script src="vue.js"></script>
<script>
/*
input 单行文本 value属性,input事件
textarea 多行文本 value属性,input事件
select select属性,change事件
radio checked属性,change事件
checkbox checked属性,change事件
v-model 指令,语法糖
修饰符:.lazy 当失去焦点时才会被触发 .number .trim 过滤首尾的空白字符
*/
const app = new Vue({
el:"#app",
data:{
inputValue:"",
textareaValue:"",
checkboxVaue:true,
checkboxArr:[],
sex:"boy",
userinfo:'age'
},
methods:{
}
})
</script>