一、模板语法
1.1 内容
Vue中的元素内容使用mustache模板引擎进行解析。https://github.com/janl/mustache.js
1.2 指令
指令会影响元素的渲染行为,指令始终以v-开头。
1.2.1 基础指令
v-for:循环渲染元素
<ul>
<!-- v-for 指令-->
<li v-for="(item,i) in products">
名称:{{item.name}}
<button @click="remove(i)">删除</button>
</li>
</ul>
v-html:设置元素的innerHTML,该指令会导致元素的模板内容失效
<body>
<div id ="app" v-html="htmlTitle">
</div>
<script src="./vue.min.js" ></script>
<script>
// vm:Vue实例
var vm = new Vue({
el:"#app",
data:{
htmlTitle:`<p style="color:red">库存管理系统</p>`,
},
});
</script>
</body>
v-on:注册事件。该指令由于十分常用,因此提供了简写@
;事件支持一些指令修饰符,如prevent
,阻止元素的默认行为。stop
,阻止事件冒泡;事件参数会自动传递。
<body>
<div id ="app">
<button v-on:click="hello()">Hello方式一</button>
<button @click="hello()">Hello方式二</button>
<a href="https://www.jianshu.com" @click.prevent="hello()">阻止元素的默认行为</a>
<div @click="hello">
<button @click.stop="world">阻止事件冒泡</button>
</div>
<button @click="test($event)">事件参数一</button>
<button @click="test">事件参数二</button>
</div>
<script src="./vue.min.js" ></script>
<script>
// vm:Vue实例
var vm = new Vue({
el:"#app",
methods:{
hello(){
console.log("Hello");
},
world(){
console.log("World");
},
test(e){
console.log("Test",e);
}
}
});
</script>
</body>
v-bind:绑定动态属性。该指令由于十分常用,因此提供了简写:
<body>
<div id ="app">
<img v-bind:src="imgUrl">
<img :src="imgUrl">
</div>
<script src="./vue.min.js" ></script>
<script>
// vm:Vue实例
var vm = new Vue({
el:"#app",
data:{
imgUrl:"https://upload.jianshu.io/users/upload_avatars/9571610/9dc14649-4d1b-415c-9a07-23b59d116d31.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/300/h/300/format/webp",
},
});
</script>
</body>
v-show:控制元素可见度
<body>
<div id ="app">
<img v-show="isShow" :src="imgUrl">
<button @click="isShow=!isShow">切换显示</button>
</div>
<script src="./vue.min.js" ></script>
<script>
// vm:Vue实例
var vm = new Vue({
el:"#app",
data:{
isShow: false,
imgUrl: "https://upload.jianshu.io/users/upload_avatars/9571610/9dc14649-4d1b-415c-9a07-23b59d116d31.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/300/h/300/format/webp",
},
});
</script>
</body>
v-show
v-show只是控制元素是否显示,即使元素不显示,元素也会生成,这样虚拟DOM的结构改动会小。
v-if、v-else-if、v-else:控制元素生成
<ul>
<!-- v-for 指令-->
<li v-for="(item,i) in products">
名称:{{item.name}}
<button @click="changeStock(item,item.stock-1)">-</button>
<span v-if="item.stock>0">{{item.stock}}</span>
<span v-else>无货</span>
<button @click="changeStock(item,item.stock+1)">+</button>
</li>
</ul>
如果元素不显示,则不生成元素。
v-model:双向数据绑定,常用于表单元素。该指令是v-on和v-bind的复合版
<body>
<div id ="app">
<h1>{{text}}</h1>
<!-- 单向绑定-->
<input type="text" :value="text" />
<!-- 双向绑定 v-on和v-bind-->
<input type="text" :value="text" @input="text=$event.target.value" />
<!-- 双向绑定-->
<input type="text" v-model="text" />
</div>
<script src="./vue.min.js" ></script>
<script>
// vm:Vue实例
var vm = new Vue({
el:"#app",
data:{
text:"AlanChen",
},
});
</script>
</body>
1.2.2 进阶指令
- v-slot:插槽
- v-test
- v-pre
- v-cloak
- v-once
- 自定义指令
1.3 特殊属性
最重要的特殊属性:key,该属性可以干预diff算法,在同一层级,key值相同的节点会进行比对,key值不同的节点则不会。
<body>
<div id ="app">
<div v-if="loginType==='mobile'">
<label>手机号:</label>
<input type="text" />
</div>
<div v-else>
<label>邮箱:</label>
<input type="text" />
</div>
<div>
<button @click="loginType = loginType==='mobile' ? 'email':'mobile'">切换登录方式</button>
</div>
</div>
<script src="./vue.min.js" ></script>
<script>
// vm:Vue实例
var vm = new Vue({
el:"#app",
data:{
loginType:"mobile",
},
});
</script>
</body>
手机登录
切换到邮箱登录
从手机登录方式切换到邮箱登录方式,输入的手机号码也带过来了。用diff算法演示如下:
input没设置key时我们要给两个input
标签分别设置key
值
<div v-if="loginType==='mobile'">
<label>手机号:</label>
<input type="text" key="1"/>
</div>
<div v-else>
<label>邮箱:</label>
<input type="text" key="2"/>
</div>
input设置key后
在循环生成的节点中,Vue强烈建议给予每个节点唯一且稳定的key值(一般用数据的ID)
<body>
<div id ="app">
<!-- 界面模板 -->
<!-- mustache -->
<h1>系统名称:{{title}}</h1>
<ul>
<!-- v-for 指令-->
<li :key="item.id" v-for="(item,i) in products">
名称:{{item.name}}
<button @click="changeStock(item,item.stock-1)">-</button>
<span v-if="item.stock>0">{{item.stock}}</span>
<span v-else>无货</span>
<button @click="changeStock(item,item.stock+1)">+</button>
<button @click="remove(i)">删除</button>
</li>
</ul>
</div>
<script src="./vue.min.js" ></script>
<script>
// vm:Vue实例
var vm = new Vue({ //配置对象
el:"#app", // css选择器
data:{ //和界面相关的数据
title:"库存管理系统",
products:[
{id:"1",name:"iphone",stock:10},
{id:"2",name:"xiaomi",stock:5},
{id:"3",name:"huawei",stock:6},
],
},
methods:{
remove(i){
this.products.splice(i,1);
},
changeStock(product,newStock){
if(newStock<0){
newStock = 0;
}
product.stock = newStock;
}
},
});
</script>
</body>
DOM树
二、计算属性
计算属性和方法的区别:
1、计算属性可以赋值,而方法不行
2、计算属性会进行缓存,如果依赖不变,则直接使用缓存结果,不会重新计算
3、凡是根据已有数据计算得到新数据的无参函数,都应该尽量写成计算属性,而不是方法
<body>
<div id ="app">
<p>姓:{{lastName}}</p>
<p>名:{{firstName}}</p>
<p>全名(拼装):{{firstName+lastName}}</p>
<p>全名(计算属性):{{fullName}}</p>
<p>全名(方法):{{getFullName()}}</p>
<input type="text" v-model="fullName"/>
<h1>{{count}}</h1>
<button @click="count++">自增</button>
</div>
<script src="./vue.min.js" ></script>
<script>
// vm:Vue实例
var vm = new Vue({
el:"#app",
data:{
firstName:"Alan",
lastName:"Chen",
count:0,
},
// 计算属性
computed:{
// fullName(){
// console.log("computed fullName");
// return this.firstName+this.lastName;
// }
// 计算属性可以赋值
fullName:{
get(){
console.log("computed fullName");
return this.firstName+this.lastName;
},
set(val){
console.log(val);
this.lastName=val[0];
this.lastName=val.substr(1);
}
}
},
methods:{
getFullName(){
console.log("methods getFullName");
return this.firstName+this.lastName;
}
}
});
</script>
</body>
默认效果
计算属性和methods的区别?
源码
源码 002
网友评论