一、官网
https://cn.vuejs.org/
二、介绍描述
1、渐进式 javascript 框架
渐进式的意思就是在核心库中逐渐添加相应的插件库
2、作者:尤雨溪
3、动态构建用户界面
三、与其他JS框架的关联
1、借鉴auglar的模板和数据绑定技术
2、借鉴react的组件化和虚拟DOM技术
四、vue的特点
1、遵循MVVM模式
2、编码简洁、体积小,运行效率高
3、只关注UI,可以轻松引入vue插件(依赖vue)和第三方库(不依赖vue)
一、代码
<body>
//MVVM中的V(view)
<div id="app">
//双向数据绑定——v-model
<input type="text" v-model="username">
<p>Hello{
{
username}}</p>
</div>
//第一步:引入vue文件
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
//第二步:创建vue对象(实例);MVVM中的vm
const vm=new vue({
//配置对象
el:"#app", //element 元素选择器
data:{
//data 指初始化数据,其值为对象;MVVM中的M(model)
username:'Hello VUE!'
}
})
</script>
</body>
二、理解VUE中的MVVM
M(model)——模型:数据对象(data)
V(view)——视图:模板页面(DOM页面)
VM(view model)——视图模型:vue的实例,VM中有DOM监听和数据绑定(数据能够从内存中自动显示到页面上)的功能
模板的理解:动态的html页面,包含了一些JS语法代码——双大括号表达式、指令(以v-开头的自定义标签属性)
<body>
<div id="app">
//双大括号表达式
<p>{
{
msg}}</p>
<p>{
{
msg.toUpperCase()}}</p>
<p v-text="msg"></p>
<p v-html="msg"></p>
//指令一:强制数据绑定v-bind:
<img src="imgUrl"> //此写法不能将图片加载上来
<img v-bind:src="imgUrl">
<img :src="imgUrl"> //v-bind: 的简写
//指令二:绑定事件监听v-on:
<button v-on:click="test">test1</button>
<button @click="test2(msg)">test2</button> //v-on: 的简写
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#app",
data:{
msg:'Welcome Back!',
imgUrl:'https://cn.vuejs.org/images/logo.png'
},
methods:{
test(){
alert("你好")
},
test2(a){
alert(a)
}
}
})
</script>
</body>
一、计算属性
在computed属性对象中定义计算属性的方法
<body>
<div id="demo">
姓:<input type="text" placeholder="First Name" v-model="firstname"><br>
名:<input type="text" placeholder="First Name" v-model="lastname"><br>
姓名1(单向):<input type="text" placeholder="Full Name1" v-model="fullname1"><br>
姓名2(单向):<input type="text" placeholder="Full Name2"><br>
姓名3(双向):<input type="text" placeholder="Full Name3"><br>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data:{
firstname:"A",
lastname:"B"
},
computed:{
fullname1(){
//计算属性的方法,方法的返回值作为属性值,会在初始显示时以及相关data属性数据改变时执行
return this.firstname+' '+this.lastname
}
}
})
</script>
</body>
二、监视属性
上述功能还可以用监视属性来实现。
通过vm对象的$watch()方法或 watch配置来监视指定的属性,当属性变化时,回调函数自动调用,在函数内部进行计算
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data:{
firstname:"A",
lastname:"B",
fullname2:"A B"
},
//第一种:配置监视
watch:{
firstname:function(value){
this.fullname2=value+' '+this.lastname
},
lastname:function(value){
this.fullname2=this.firstname+' '+value
}
}
})
//第二种:方法监视
vm.$watch('firstname',function(value){
this.fullname2=value+' '+this.lastname
})
vm.$watch('lastname',function(value){
this.fullname2=this.firstname+' '+value
})
</script>
三、计算属性高级
通过getter和setter实现对属性数据的显示和监听
计算属性存在缓存,多次读取只执行一次getter计算
computed:{
fullname3:{
get(){
return this.firstname+' '+this.lastname
}
set(value){
const names=value.split(' ')
this.firstname=names[0]
this.lastname=names[1]
}
}
}
是专门用来实现动态样式效果的技术
<style>
.aClass{
color:red;}
.bClass{
color:blue;}
.cClass{
font-size:30px;}
</style>
<body>
<div id="demo">
//class绑定
<p class="cClass" :class="a">你好</p> //字符串
<p :class="{aClass:isA,bClass:isB}">你好</p> //对象
//style绑定
<p :style="{color:activeColor,fontSize:fontSize+'px'}">你好</p>
<button @click="update">更新</button>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data:{
a:'aClass',
isA:true,
isB:false,
activeColor:'green',
fontSize:20
},
methods:{
update(){
this.a='bClass'
this.isA=false
this.isB=true
this.activeColor='pink'
this.fontSize=30
}
}
})
</script>
</body>
v-if、v-else:增添和移除元素
v-show:改变display的值
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好
<body>
<div id="demo">
<p v-if="ok">成功</p>
<p v-else>失败</p>
<p v-show="ok">失败</p>
<p v-show="!ok">成功</p>
<button @click="ok=!ok">转换</button>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data:{
ok:true
}
})
</script>
</body>
vue要调用变异方法来更新界面,变异方法包含:push() pop() shift() unshift() splice() sort() reverse()
<body>
<div id="demo">
//v-for遍历数组
<ul>
<li v-for="(p,index) in persons" :key="index">
{
{
index}}---{
{
p.name}}---{
{
p.age}}
---<button @click="deleteP(index)">删除</button>
---<button @click="updateP(index,{name:'jane',age:21})">更新</button>
</li>
</ul>
//v-for遍历对象
<ul>
<li v-for="(value,key) in persons[1]" :key="key">
{
{
value}}---{
{
key}}
</li>
</ul>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data:{
persons:[
{
name:'Tom',age:18},
{
name:'Jack',age:17},
{
name:'Bob',age:19},
{
name:'Marry',age:16}
]
},
methods:{
deleteP(index){
this.persons.splice(index,1)
},
updateP(index,newP){
this.persons.splice(index,1,newP)
}
}
})
</script>
</body>
<body>
<div id="demo">
<input type="text" v-model="searchName">
<ul>
<li v-for="(p,index) in filterPersons" :key="index">
{
{
index}}---{
{
p.name}}---{
{
p.age}}
</li>
</ul>
<button @click="setOrderType(1)">年龄升序</button>
<button @click="setOrderType(2)">年龄降序</button>
<button @click="setOrderType(0)">原本顺序</button>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data:{
searchName:'',
orderType:0, //0是原本顺序,1是升序,2是降序
persons:[
{
name:'Tom',age:18},
{
name:'Jack',age:17},
{
name:'Bob',age:19},
{
name:'Marry',age:16},
]
},
computed:{
filterPersons(){
const{
searchName,persons,orderType}=this
let fPersons
fPersons=persons.filter(p => p.name.indexOf(searchName)!==-1)
//排序
if(orderType!==0){
fPersons.sort(function(p1,p2){
if(orderType===2){
return p2.age-p1.age //升序
}else{
return p1.age-p2.age //降序
}
})
}
return fPersons
}
},
methods:{
setOrderType(orderType){
this.orderType=orderType
}
}
})
</script>
</body>
停止事件冒泡 .stop
阻止事件的默认行为 .prevent
@keyup.
<body>
<div id="demo">
//1、绑定监听
<button @click="test1">test1</button>
<button @click="test2('hello')">test2</button>
<button @click="test3">test3</button> //默认存在event
<button @click="test4('Hi',$event)">test4</button>
//2、事件修饰符
<div style="width:200px;height:200px;background:red" @click="test5">test5
<div style="width:100px;height:100px;background:blue" @click.stop="test6">test6</div>//停止事件冒泡 .stop
</div>
<a href="https://www.baidu.com" @click.prevent="test7">去百度</a> //阻止事件的默认行为 .prevent
//3、按键修饰符
<input type="text" @keyup.13="test9">
<input type="text" @keyup.enter="test9">
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data:{
test1(){
alert('你好')
},
test2(msg){
alert(msg)
},
test3(event){
alert(event.target.innerHTML)
},
test4(msg,event){
alert(msg+"---"+event.target.innerHTML)
},
test5(){
alert("outter")
},
test6(){
alert("inner")
},
test7(){
//event.preventDefault() 阻止事件的默认行为
alert("已点击")
},
test8(event){
if(event.keyCode===13){
alert(event.target.value +' '+event.keyCode)
}
},
test9(event){
alert(event.target.value +' '+event.keyCode)
}
}
})
</script>
</body>
<body>
<div id="demo" @submit.prevent="handleSubmit">
<form>
<span>用户名:</span>
<input type="text" v-model="username"><br><br>
<span>密码:</span>
<input type="password" v-model="pwd"><br><br>
<span>性别:</span>
<input type="radio" id="female" value="女" v-model="sex">
<label for="female">女</label>
<input type="radio" id="male" value="男" v-model="sex">
<label for="male">男</label><br><br>
<span>爱好:</span>
<input type="checkbox" id="basket" value="篮球" v-model="likes">
<label for="basket">篮球</label>
<input type="checkbox" id="football" value="足球" v-model="likes">
<label for="football">足球</label>
<input type="checkbox" id="ping-pang" value="乒乓球" v-model="likes">
<label for="ping-pang">乒乓球</label><br><br>
<span>城市:</span>
<select v-model="cityId">
<option value="">未选择</option>
<option :value="city.id" v-for="(city, index) in allCities" :key="index">
{
{
city.name}}</option>
</select><br><br>
<span>介绍:</span>
<textarea rows="10" v-model="desc"></textarea><br><br><br>
<input type="submit" value="注册">
</form>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data: {
username: '',
pwd: '',
sex: '女', //设置的值为value的值
likes: [],
cityId: '',
desc: '',
allCities: [{
id: 1, name: 'BJ'}, {
id: 2, name: 'SZ'},{
id: 4, name: 'SH'}],
},
methods: {
handleSubmit(){
console.log(this.username)
}
}
})
</script>
</body>
一、分析
1、 初始化显示 --执行1次
beforeCreate() 、 created() 、beforeMount() 、mounted()
2、更新状态–执行n次:this.xxx = value
beforeUpdate() 、updated()
3、 销毁 vue 实例–执行1次:vm.$destory()
beforeDestory() 、destoryed()
二、常用的生命周期方法
1、 mounted(): 发送 ajax 请求, 启动定时器等异步任务
2、 beforeDestory(): 做收尾工作, 如: 清除定时器
<body>
<div id="demo" >
<button @click="destoryVue">destory vue</button>
<p v-show="isShow">你好</p>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
const vm=new Vue({
el:"#demo",
data:{
isShow:true
},
mounted(){
//挂载,初始化显示后立即调用-1次
this.timer=setInterval(() => {
console.log('======')
this.isShow=!this.isShow
}, 1000)
},
beforeDestroy () {
//死亡之前调用-1次
//清除定时器
clearInterval(this.timer)
},
methods: {
//清除VM
destoryVue(){
this.$destroy()
}
}
})
</script>
</body>
<style>
.toggleFade-enter-active, .toggleFade-leave-active {
transition: opacity .5s }
.toggleFade-enter, .toggleFade-leave-to {
opacity: 0 }/* 可以设置不同的进入和离开动画 */
.move-enter-active {
transition: all .3s ease; }
.move-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0); }
.move-enter, .move-leave-to {
transform: translateX(10px); opacity: 0; } </style>
<body>
<div id="demo1" >
<button @click="isShow=!isShow">
toggle-fade
</button>
<transition name="toggleFade">
<p v-show="isShow">hello</p>
</transition>
</div>
<div id="demo2" >
<button @click="isShow=!isShow">
toggle-move
</button>
<transition name="move">
<p v-show="isShow">hello</p>
</transition>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#demo1",
data:{
isShow:true
}
})
new Vue({
el:"#demo2",
data:{
isShow:true
}
})
</script>
</body>
Moment.js:JavaScript 日期处理类库
<body>
<div id="demo" >
<p>{
{
currentDate}}</p>
<p>{
{
currentDate | dataString}}</p>
<p>{
{
currentDate | dataString("YYYY-MM-DD")}}</p>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript" src="https://cdn.bootcss.com/moment.js/2.24.0/moment.js"></script>
<script type="text/javascript">
//自定义过滤器
Vue.filter('dataString',function(value,format){
return moment(value).format(format || 'YYYY-MM-DD HH:mm:ss');
})
new Vue({
el:"#demo",
data:{
currentDate:new Date()
}
})
</script>
</body>
一、常用的内置指令
v-text : 更新元素的 textContent
v-html : 更新元素的 innerHTML
v-if : 如果为 true, 当前标签才会输出到页面
v-else: 如果为 false, 当前标签才会输出到页面
v-show : 通过控制 display 样式来控制显示/隐藏
v-for : 遍历数组/对象
v-on : 绑定事件监听, 一般简写为@
v-bind : 强制绑定解析表达式, 可以省略 v-bind
v-model : 双向数据绑定
ref : 指定唯一标识, vue 对象通过 $refs 属性访问这个元素对象
v-cloak : 防止闪现, 与 css 配合: [v-cloak] { display: none }
<style>
[v-cloak]{
display:none}
</style>
<body>
<div id="demo" >
<p ref="content">hello</p>
<button @click="hint">提示</button>
<p v-cloak>{
{
msg}}</p>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#demo",
data:{
currentDate:new Date(),
msg:"你好"
},
methods:{
hint(){
alert(this.$refs.content.textContent)
}
}
})
</script>
</body>
二、自定义指令
1、全局指令
Vue.directive(‘xxx’, function(el, binding){
el.innerHTML = binding.value.toupperCase()
})
2、局部指令
directives : {
‘xxx’ : {
bind (el, binding) {
el.innerHTML = binding.value.toupperCase()
} } }
<body>
<div id="demo1" >
<p v-upper-text="msg1"></p>
<p v-lower-text="msg2"></p>
</div>
<div id="demo2" >
<p v-upper-text="msg1"></p>
<p v-lower-text="msg2"></p>
</div>
<script type="text/javascript" src="../dist/vue.js"></script>
<script type="text/javascript">
//全局指令
Vue.directive("upper-text",function(el,binding){
el.innerHTML=binding.value.toUpperCase()
})
new Vue({
el:"#demo1",
data:{
msg1:"Good Good Study!",
msg2:"Day Day Up!"
}
})
new Vue({
el:"#demo2",
data:{
msg1:"Good Good Study!",
msg2:"Day Day Up!"
},
//局部指令
directives: {
"lower-text":{
bind(el,binding){
el.innerHTML=binding.value.toLowerCase()
}
}
}
})
</script>
</body>