Vue 指令
- 基本语法
<body>
<section id="app">
<div>{{msg}}</div>
<div>{{1+3+msg}}</div>
<div v-text='msg'></div>
</section>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '你好,世界!'
},
methods: {
}
})
</script>
Vue指令
- 概念
- 本质就是自定义属性
- Vue中指定都是以
v-
开头
v-cloat
指令
- 功能
- 防止页面加载时出现闪烁问题
<style type="text/css">
/*
1、通过属性选择器 选择到 带有属性 v-cloak的标签 让他隐藏
*/
[v-cloak]{
display: none; /* 元素隐藏 */
}
</style>
<body>
<section id="app">
<!-- 2、 让带有插值 语法的 添加 v-cloak 属性
在 数据渲染完场之后,v-cloak 属性会被自动去除,
v-cloak一旦移除也就是没有这个属性了 属性选择器就选择不到该标签
也就是对应的标签会变为可见
-->
<div v-cloak>{{msg}}</div>
</section>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
// el 指定元素 id 是 app 的元素
el: '#app',
// data 里面存储的是数据
data: {
msg: 'Hello Vue'
}
});
</script>
</body>
v-text
指令
- 功能
v-text
指令用于将数据填充到标签中,作用于插值表达式类似,但是没有闪动问题- 如果数据中有HTML标签会将html标签一并输出
- 注意:此处为单向绑定,数据对象上的值改变,插值会发生变化;但是当插值发生变化并不会影响数据对象的值
<section id="app">
<!--
注意:在指令中不要写插值语法 直接写对应的变量名称
在 v-text 中 赋值的时候不要在写 插值语法
一般属性中不加 {{}} 直接写 对应 的数据名
-->
<p v-text="msg"></p>
<p>
<!-- Vue 中只有在标签的 内容中 才用插值语法 -->
{{msg}}
</p>
</section>
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello Vue.js'
}
});
</script>
v-html
指令
- 功能
- 用法和
v-text
相似,但是他可以将HTML片段填充到标签中 - 可能有安全问题, 一般只在可信任内容上使用
v-html
,永不用在用户提交的内容上 - 它与v-text区别在于v-text输出的是纯文本,浏览器不会对其再进行html解析,但v-html会将其当html标签解析后输出。
- 用法和
<section id="app">
<p v-html="html"></p> <!-- 输出:html标签在渲染的时候被解析 -->
<p>{{message}}</p> <!-- 输出:<span>通过双括号绑定</span> -->
<p v-text="text"></p> <!-- 输出:<span>html标签在渲染的时候被源码输出</span> -->
</section>
<script>
let app = new Vue({
el: "#app",
data: {
message: "<span>通过双括号绑定</span>",
html: "<span>html标签在渲染的时候被解析</span>",
text: "<span>html标签在渲染的时候被源码输出</span>",
}
});
</script>
v-pre
指令
- 功能
- 显示原始信息跳过编译过程
- 跳过这个元素和它的子元素的编译过程。
- 一些静态的内容不需要编译加这个指令可以加快渲染
<span v-pre>{{ this will not be compiled }}</span>
<!-- 显示的是{{ this will not be compiled }} -->
<span v-pre>{{msg}}</span>
<!-- 即使data里面定义了msg这里仍然是显示的{{msg}} -->
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello Vue.js'
}
});
</script>
v-once
指令
- 功能
- 执行一次性的插值【当数据改变时,插值处的内容不会继续更新】
- 数据响应式
<!-- 即使data里面定义了msg 后期我们修改了 仍然显示的是第一次data里面存储的数据即 Hello Vue.js -->
<span v-once>{{msg}}</span>
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello Vue.js'
}
});
</script>
v-model
指令
- 功能
- 数据双向绑定
- 当数据发生变化的时候,视图也就发生变化
- 当视图发生变化的时候,数据也会跟着同步变化
- 限制在
<input>、<select>、<textarea>、components
中使用 - 当输入框中内容改变的时候,页面上的msg会自动更新
<div id="app">
<div>{{msg}}</div>
<div>
<input type="text" v-model='msg'>
</div>
</div>
MVVM
- MVC是后端的分层开发概念;MVVM是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端的视图层,分为了三部分 Model, View , VM ViewModel
- M-model:数据层Vue中数据层都放在data里面
- V-view:Vue中view,即我们的HTML页面
- VM-view-model:控制器,将数据和视图层建立联系,vm即Vue的实例
v-on
指令
-
功能
- 用来绑定事件的
- 形式如:
v-on:click
缩写为@click
;
-
v-on
事件函数中传入参数
<div id="app">
<div>{{num}}</div>
<div>
<!-- 如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数 -->
<button v-on:click='handle1'>点击1</button>
<!-- 2、如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,并且事件对象的名称必须是$event
-->
<button v-on:click='handle2(123, 456, $event)'>点击2</button>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
num: 0
},
methods: {
handle1: function(event) {
console.log(event.target.innerHTML);
},
handle2: function(p, p1, event) {
console.log(p, p1);
console.log(event.target.innerHTML);
this.num++;
}
}
});
</script>
事件修饰符
- 功能
- 在事件处理程序中调用
event.preventDefault()
或event.stopPropagation()
是非常常见的需求。 - Vue不推荐我们操作DOM,为了解决这个问题,Vue.js 为
v-on
提供了事件修饰符 - 修饰符是由点开头的指令后缀来表示的
- 使用修饰符时顺序很重要;相应的代码会以同样的顺序产生。
- 用
v-on:click.prevent.self
会阻止所有的点击 - 而用
v-on:click.self.prevent
会阻止对元素自身的点击。 .stop
阻止冒泡.prevent
阻止默认事件
- 在事件处理程序中调用
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 即阻止冒泡也阻止默认事件 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
按键修饰符
-
功能
- 在做项目中有时会用到键盘事件,在监听键盘事件时,我们经常需要检查详细的按键。
- Vue 允许为
v-on
在监听键盘事件时添加按键修饰符
-
常用的按键修饰符
.enter
=> enter键.tab
=> tab键.delete
=> 删除键(捕获“删除”和“退格”按键).esc
=> 取消键.space
=> 空格键.up
=> 上.down
=> 下.left
=> 左.right
=> 右
<section id="app">
<form action="">
<div>
<span>用户名:</span>
<input type="text" v-on:keyup.delete='clearContent' v-model='uname'>
</div>
<div>
<span>密码:</span>
<input type="text" v-on:keyup.f1='handleSubmit' v-model='pwd'>
</div>
<div>
<input type="button" v-on:click='handleSubmit' value="提交">
</div>
</form>
</section>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/* 事件绑定-按键修饰符 */
Vue.config.keyCodes.f1 = 113
var vm = new Vue({
el: '#app',
data: {
uname: '',
pwd: '',
age: 0
},
methods: {
clearContent:function(){
// 按delete键的时候,清空用户名
this.uname = '';
},
handleSubmit: function(){
console.log(this.uname,this.pwd);
}
}
});
</script>
自定义按键修饰符别名
- 功能
- 在Vue中可以通过
config.keyCodes
自定义按键修饰符别名
- 在Vue中可以通过
<div id="app">
<span>预先定义了keycode 116(即F5)的别名为f5,因此在文字输入框中按下F5,会触发prompt方法</span>
<input type="text" v-on:keydown.f5="prompt()">
</div>
<script>
Vue.config.keyCodes.f5 = 116;
let app = new Vue({
el: '#app',
methods: {
prompt: function() {
alert('我是 F5!');
}
}
});
</script>
案例:简易累加器
<body>
<section id="add">
<h1>简易累加器</h1>
<div>
<span>数值A</span>
<input type="text" v-model='a'>
</div>
<div>
<span>数值B</span>
<input type="text" v-model='b'>
</div>
<div>
<span>计算结果:</span>
<span v-text='res'>0</span>
</div>
<div>
<br>
<button v-on:click = 'add'>累加喽</button>
</div>
</section>
</body>
<script>
var add = new Vue({
el: '#add',
data: {
a: 0,
b: 0,
res: 0
},
methods: {
add: function(){
this.res = parseInt(this.a) + (this.b*1);
}
}
});
</script>
v-bind
指令
- 功能
v-bind
指令被用来响应地更新 HTML 属性v-bind:href
可以缩写为:href
;
<body>
<section id="app">
<a v-bind:href="url" v-text='text'></a>
<button v-on:click='change'>切换</button>
</section>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
url: 'https://www.baidu.com',
text: '百度点我',
flag: true
},
methods: {
change: function(){
if(this.flag){
this.url = 'https://www.cnblogs.com/';
this.text = '博客园点我';
}else{
this.url = 'https://www.baidu.com/';
this.text = '百度点我';
}
this.flag = !this.flag;
}
}
});
</script>
- 绑定对象
- 我们可以给
v-bind:class
一个对象,以动态地切换class。 - 注意:
v-bind:class
指令可以与普通的class特性共存 v-bind
中支持绑定一个对象:如果绑定的是一个对象,则键为对应的类名, 值为对应data中的数据
- 我们可以给
<!--
HTML最终渲染为 <ul class="box textColor textSize"></ul>
注意:
textColor,textSize 对应的渲染到页面上的CSS类名
isColor,isSize 对应vue data中的数据 如果为true 则对应的类名 渲染到页面上
当 isColor 和 isSize 变化时,class列表将相应的更新,
例如,将isSize改成false,
class列表将变为 <ul class="box textColor"></ul>
-->
<ul class="box" v-bind:class="{textColor:isColor, textSize:isSize}">
<li>学习Vue</li>
<li>学习Node</li>
<li>学习React</li>
</ul>
<div v-bind:style="{color:activeColor,fontSize:activeSize}">对象语法</div>
<sript>
var vm= new Vue({
el:'.box',
data:{
isColor:true,
isSize:true,
activeColor:"red",
activeSize:"25px",
}
})
</sript>
<style>
.box{
border:1px dashed #f0f;
}
.textColor{
color:#f00;
background-color:#eef;
}
.textSize{
font-size:30px;
font-weight:bold;
}
</style>
- 绑定class
v-bind
中支持绑定一个数组,数组中classA和classB对应为data中的数据
<!--这里的classA 对用data 中的 classA
这里的classB 对用data 中的 classB-->
<ul class="box" :class="[classA, classB]">
<li>学习Vue</li>
<li>学习Node</li>
<li>学习React</li>
</ul>
<script>
var vm= new Vue({
el:'.box',
data:{
classA:‘textColor‘,
classB:‘textSize‘
}
})
</script>
<style>
.box{
border:1px dashed #f0f;
}
.textColor{
color:#f00;
background-color:#eef;
}
.textSize{
font-size:30px;
font-weight:bold;
}
</style>
- 绑定对象和绑定数组的区别
- 绑定对象的时候 对象的属性 即要渲染的类名 对象的属性值对应的是 data 中的数据
- 绑定数组的时候数组里面存的是data 中的数据
<style type="text/css">
.active {
border: 1px solid red;
100px;
height: 100px;
}
.error {
background-color: orange;
}
.test {
color: blue;
}
.base {
font-size: 28px;
}
</style>
<body>
<section id="app">
<div v-bind:class='[activeClass, errorClass, {test: isTest}]'>测试样式</div>
<div v-bind:class='arrClasses'></div>
<div v-bind:class='objClasses'></div>
<div class="base" v-bind:class='objClasses'></div>
<button v-on:click='handle'>切换</button>
</section>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
样式绑定相关语法细节:
1、对象绑定和数组绑定可以结合使用
2、class绑定的值可以简化操作
3、默认的class如何处理?默认的class会保留
*/
var vm = new Vue({
el: '#app',
data: {
activeClass: 'active',
errorClass: 'error',
isTest: true,
arrClasses: ['active','error'],
objClasses: {
active: true,
error: true
}
},
methods: {
handle: function(){
// this.isTest = false;
this.objClasses.error = false;
}
}
});
</script>
</body>
- 绑定style
- CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来)
- 组语法可以将多个样式对象应用到同一个元素
<body>
<div id="app">
<div v-bind:style="{color: activeColor, fontSize: fontSize,background:'red' }">内联样式</div>
<div v-bind:style='{border: borderStyle, widthStyle, height: heightStyle}'></div>
<div v-bind:style='objStyles'></div>
<div v-bind:style='[objStyles, overrideStyles]'></div>
<button v-on:click='handle'>切换</button>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
样式绑定之内联样式Style:
*/
var vm = new Vue({
el: '#app',
data: {
borderStyle: '1px solid blue',
widthStyle: '100px',
heightStyle: '200px',
activeColor: 'green',
fontSize: "30px",
objStyles: {
border: '1px solid green',
'200px',
height: '100px'
},
overrideStyles: {
border: '5px solid orange',
backgroundColor: 'blue'
}
},
methods: {
handle: function(){
this.heightStyle = '100px';
this.objStyles.width = '100px';
}
}
});
</script>
</body>
流程控制
分支结构
v-if
使用场景- 多个元素 通过条件判断展示或者隐藏某个元素。
- 进行两个视图之间的切换
<section id="app">
<div v-if='score>=90'>优秀</div>
<div v-else-if='score<90&&score>=80'>良好</div>
<div v-else-if='score<80&&score>60'>一般</div>
<div v-else>比较差</div>
<div v-show='flag'>测试v-show</div>
<button v-on:click='handle'>点击</button>
</section>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/* v-show的原理:控制元素样式是否显示 display:none */
var vm = new Vue({
el: '#app',
data: {
score: 10,
flag: false
},
methods: {
handle: function(){
this.flag = !this.flag;
}
}
});
</script>
- v-show 和 v-if的区别
- v-show本质就是标签display设置为none,控制隐藏
- v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。
- v-if是动态的向DOM树内添加或者删除DOM元素
- v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件
- v-show本质就是标签display设置为none,控制隐藏
循环结构
-
v-for应用场景
- 用于循环的数组里面的值可以是对象,也可以是普通元素
-
遍历数组
<body>
<div id="app">
<div>水果列表</div>
<ul>
<li v-for='item in fruits'>{{item}}</li>
<li v-for='(item, index) in fruits'>{{item + '---' + index}}</li>
<li :key='item.id' v-for='(item, index) in myFruits'>
<span>{{item.ename}}</span>
<span>---{{index}}---</span>
<span>{{item.cname}}</span>
</li>
</ul>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/* 循环结构-遍历数组 */
var vm = new Vue({
el: '#app',
data: {
fruits: ['apple', 'orange', 'banana'],
myFruits: [{
id: 1,
ename: 'apple',
cname: '苹果'
},{
id: 2,
ename: 'orange',
cname: '橘子'
},{
id: 3,
ename: 'banana',
cname: '香蕉'
}]
}
});
</script>
</body>
- 遍历对象
<body>
<div id="app">
<div v-if='v==13' v-for='(v,k,i) in obj'>{{v + '---' + k + '---' + i}}</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
// 使用原生js遍历对象
var obj = {
uname: 'lisi',
age: 12,
gender: 'male'
}
for(var key in obj) {
console.log(key, obj[key])
}
/* 循环结构 */
var vm = new Vue({
el: '#app',
data: {
obj: {
uname: 'zhangsan',
age: 13,
gender: 'female'
}
}
});
</script>
</body>
案例:Tab选项卡
<style>
ul {
list-style:none;
float:left;
}
li {
240px;
height: 36px;
overflow: hidden;
float: left;
text-align: center;
line-height: 36px;
border: 1px solid red;
}
.active {
color:#f00;
background-color: orange;
}
.imgs {
960px;
height: 360px;
border: 1px solid yellow;
background-color: rgb(211, 50, 50);
float: left;
margin-left: 40px;
font-size: 96px;
text-align: center;
line-height: 360px;
display: none;
}
.current {
display: block;
}
</style>
<body>
<section id='app'>
<ul>
<li v-on:click='change(index)' v-bind:class='currentIndex==index?"active":""' v-bind:key='item.id' v-for='(item,index) in list' v-text='item.city'></li>
</ul>
<div>
<div class='imgs' v-bind:key='item.id' v-for='(item,index) in list' v-text='item.content' v-bind:class='currentIndex==index?"current":""'>1</div>
</div>
</section>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
currentIndex : 0,
list:[{
id: 1,
city: '江苏',
content: '江苏风光'
},{
id: 2,
city: '浙江',
content: '浙江风光'
},{
id: 3,
city: '云南',
content: '云南风光'
},{
id: 4,
city: '山东',
content: '山东风光'
}],
},
methods: {
change:function(index){
this.currentIndex = index;
console.log(this.list[index].city);
console.log(this.currentIndex);
console.log(this.currentIndex==index?"active":"");
}
}
})
</script>