class样式绑定
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用 v-bind
处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"> </div> //和如下 data: data: { isActive: true, hasError: false }
或者
<div v-bind:class="classObject"></div>
//和如下data
data: {
classObject: {
active: true,
'text-danger': false
}
}
//结果渲染为:
<div class="static active"></div>
也可以和计算属性一起用
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
key值解决复用
在vue中会出现,缓存复用的现象,简单的说就是,比如说代码中有两个input框,我在页面中只显示一个,在点击button后显示另一个,我在一个input中输入值,切换后另一个input中会出现值,但是有时这不符合需求,那么这时就要使用key值使其唯一了
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> Document </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <div v-if="show"> 用户名:<input key="username"> 用户名:<input> </div> <div v-else> 邮箱名:<input key="email"> 邮箱名:<input> </div> </div> <script> var app=new Vue({ el:"#app", data:{ show:false, } }) </script> </body> </html>
set方法
通过set方法向data数据中键入值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> Document </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <div v-for="(item,key,index) of list"> {{index}}--{{key}}--{{item}} </div> </div> <script> var app=new Vue({ el:"#app", data:{ list:{ firstname:"Li", lastname:"Ming" } }, mounted:function(){ this.$set(this.list,"a","b"); } }) </script> </body> </html>
is属性的应用
在html中比如说tr元素后面的子节点必须为td,使用is属性解决在ttable、ul、ol等元素在引入组件模板的出错问题,
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> Document </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <table> <tbody> <tr is="row"></tr> </tbody> </table> </div> <script> Vue.component("row",{ template:'<tr><td>this is a row</td></tr>' }) var app=new Vue({ el:"#app", data:{ list:{ firstname:"Li", lastname:"Ming" } }, }) </script> </body> </html>
子组件中data的问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> Document </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <table> <tbody> <tr is="row"></tr> </tbody> </table> </div> <script> Vue.component("row",{ data:function(){ return { content:"this is a row" } }, template:'<tr><td>{{content}}</td></tr>' }) var app=new Vue({ el:"#app", data:{ list:{ firstname:"Li", lastname:"Ming" } }, }) </script> </body> </html>
ref操作DOM
虽然Vue一般操作数据层即可,但是有时你会发现操作Dom会很方便,而Vue提供了ref可以获取DOM
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> Document </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <div ref="hello" @click="handleClick">1</div> </div> <script> var app=new Vue({ el:"#app", data:{ }, methods:{ handleClick:function(){ console.log(this.$refs.hello.innerHTML) } } }) </script> </body> </html>
父子组件的数据传递
父组件通过属性向子组件传值
子组件通过事件触发向父组件传值
单向数据流,子组件不可以修改父组件传递的内容,一旦修改有可能对引用的其他子组件产生影响,可以在子组件中的data中复制父组件传过来的值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> Document </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <counter :count="2" @change="handleChange"> </counter> <counter :count="3" @change="handleChange"> </counter> <div > {{total}} </div> </div> <script> var counter={ props:['count'], data:function(){ return{ number:this.count } }, template:"<div @click='handleClick'>{{number}}</div>", methods:{ handleClick:function(){ this.number++; this.$emit("change",1); } } } var app=new Vue({ el:"#app", components:{ counter:counter }, data:{ total:5 }, methods:{ handleChange:function(step){ this.total+=step; } } }) </script> </body> </html>
组件绑定原生事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> 组件绑定原生事件 </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <child @click.native="handleClick"> </child> </div> <script> var child={ template:"<div>Child</div>", } var app=new Vue({ el:"#app", components:{ child:child }, methods:{ handleClick:function(){ alert("1") } } }) </script> </body> </html>
非父子组件的传值问题
总线机制
VUEXE:https://vuex.vuejs.org/
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> 非父子组件(Bus/总线/发布订阅模式/观察者模式) </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <child content="Li"> </child> <child content="Ming"> </child> </div> <script> Vue.prototype.bus=new Vue();//加bus属性 var child={ props:{ content:String }, data:function(){ return{ selfcontent:this.content } }, template:"<div @click='handleClick'>{{selfcontent}}</div>", methods:{ handleClick:function(){ this.bus.$emit('change',this.selfcontent) } }, mounted:function(){ var that=this; this.bus.$on('change',function(msg){that.selfcontent=msg}) } } var app=new Vue({ el:"#app", components:{ child:child }, }) </script> </body> </html>
Vue中使用插槽slot和具名插槽
slot标签内部可以定义默认值,在子组件内无内容时显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> Vue中使用插槽 </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <child> <div class="header" slot="header"> header </div> <div class="footer" slot="footer"> footer </div> </child> </div> <script> var child={ template:`<div><slot name='header'></slot><p>hello</p><slot name='footer'></slot></div>`, } var app=new Vue({ el:"#app", components:{ child:child }, }) </script> </body> </html>
作用域插槽
必须template开头结尾
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> Vue中使用插槽 </title> </meta> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <child> <template slot-scope='props'> <h1>{{props.item}}</h1> </template> </child> </div> <script> var child={ template:`<div> <ul> <slot v-for="item of list" :item=item></slot> </ul> </div>`, data:function(){ return{ list:[1,2,3,4] } }, } var app=new Vue({ el:"#app", components:{ child:child }, }) </script> </body> </html>
v-once可以提高静态组件的性能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> <title> 动态组件和v-once指令 </title> <script src="./vue.js" type="text/javascript"> </script> </head> <body> <div id="app"> <!-- <child-one v-if="type==='child-one'"> </child-one> <child-two v-if="type==='child-two'"> </child-two> --> <!-- 动态组件 --> <component :is="type"> </component> <button @click="handleBtnClick"> change </button> </div> <script> Vue.component('child-one',{ template:'<div v-once>child-one</div>' }) Vue.component('child-two',{ template:'<div v-once>child-two</div>' }) var app=new Vue({ el:"#app", data:{ type:"child-one" }, methods:{ handleBtnClick:function(){ this.type=this.type=='child-one'?'child-two':'child-one'; } } }) </script> </body> </html>