一、使用组件的细节点
当使用table、select等标签时,组件标签化可能会有bug,此时应该使用 is 接受组件。
<div id="app">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>
<script type="text/javascript">
Vue.component('row', {
template:'<tr><td>This is a row</td></tr>'
})
var app = new Vue({
el:"#app"
})
</script>
在子组件定义data时,data必须是一个函数,不能是一个对象。
在vue中如果要操作dom,需要使用 ref 引用,从而获取dom节点。
需求:定义一个子组件,使其数字自加,在父组件中对子组件的数字求和。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>组件中的细节点</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<counter ref='number1' @change="changeClick"></counter>
<counter ref='number2' @change="changeClick"></counter>
<div>{{total}}</div>
</div>
<script>
//定义一个子组件
Vue.component('counter', {
template:"<div @click='handleClick'>{{count}}</div>",
data:function() {
return {
count: 0
}
},
methods:{
handleClick: function() {
this.count++;
//通过$emit 让父组件监听到状态变化
this.$emit('change');
}
}
})
var app = new Vue({
el:"#app",
data:{
total:0
},
methods:{
changeClick: function() {
this.total = this.$refs.number1.count + this.$refs.number2.count;
}
}
})
</script>
</body>
</html>
二、父子组件之间的数据传递
单向数据流:父组件可以向子组件传递参数,传递的参数父组件可以任意修改。子组件不能修改父组件传来的参数,只能使用。
父组件向子组件传值:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>父子组件传值</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<counter :count="0"></counter>
<counter :count="1"></counter>
</div>
<script type="text/javascript">
//定义一个局部组件
var counter = {
//使用props接受父组件的值
props: ['count'],
data: function(){
return {
number: this.count
}
},
template: '<div @click="handleClick">{{number}}</div>',
methods: {
handleClick: function() {
this.number++;
}
}
}
var app = new Vue({
el:"#app",
//注册组件
components:{
counter: counter
}
})
</script>
</body>
</html>
子组件向父组件传值:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>父子组件传值</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<counter :count="8" @incnumber="handleChangeClick"></counter>
<counter :count="2" @incnumber="handleChangeClick"></counter>
<div>{{total}}</div>
</div>
<script type="text/javascript">
//定义一个局部组件
var counter = {
//使用props接受父组件的值
props: ['count'],
data: function(){
return {
number: this.count
}
},
template: '<div @click="handleClick">{{number}}</div>',
methods: {
handleClick: function() {
this.number++;
//通过事件向父组件传值
this.$emit('incnumber', 1)
}
}
}
var app = new Vue({
el:"#app",
data:{
total: 10
},
//注册组件
components:{
counter: counter
},
methods:{
handleChangeClick: function(step) {
this.total += step
}
}
})
</script>
</body>
</html>
三、给组件绑定原生事件
使用native修饰符监听:
<div id="app">
<child @click.native="handleClick"></child>
</div>
<script>
Vue.component('child', {
template:"<div>Child</div>"
})
var app = new Vue({
el:"#app",
methods:{
handleClick: function() {
alert(222)
}
}
})
</script>
四、非父子组件之间的传值(Bus/总线/发布订阅模式/观察者模式)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>非父子组件之间的传值(Bus/总线/发布订阅模式/观察者模式)</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<child content="xiao"></child>
<child content="mo"></child>
</div>
<script>
Vue.prototype.bus = new Vue()
Vue.component('child', {
data: function() {
return {
selfContent : this.content
}
},
props:{
content: String
},
template:'<div @click="handleClick">{{selfContent}}</div>',
methods:{
handleClick: function() {
this.bus.$emit('change', this.selfContent)
}
},
mounted: function() {
var this_ = this
this.bus.$on('change', function(msg) {
this_.selfContent = msg
})
}
})
var app = new Vue({
el:"#app"
})
</script>
</body>
</html>
五、Vue中的插槽(slot)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue中的插槽(slot)</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="app">
<child>
<h1>Xiaomo</h1>
</child>
</div>
<script>
Vue.component('child', {
template:`<div>
<p>Hello</p>
<slot>可以定义默认值</slot>
</div>`
})
var app = new Vue({
el:"#app"
})
</script>
</body>
</html>
局部插槽需要使用template标签括起来。
六、动态组件
<component>标签表示动态组件,根据is值判断加载不同的组件。
v-once 可以有效提高静态页面展示效率。
网友评论