1. 在table/ul/ol/select中显示子组件
- bug
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件使用中的细节点1</title>
<script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<table>
<tbody>
<row></row>
<row></row>
<row></row>
</tbody>
</table>
</div>
<script>
/*希望每一行的数据都是一个子组件的时候*/
Vue.component('row', {
template:'<tr><td>this is a row</td></tr>'
})
var vm=new Vue({
el:"#root",
data:{
}
})
</script>
</body>
</html>
效果如下,我们会发现出现了…跑到tbody外面和table同级的情况,违反了H5的要求,即tr必须在tbody中,tbody必须在table中。:
- 解决
<div id="root">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>
2. 子组件中的data函数
在子组件中data应该是一个函数,而不是一个对象;在根组件里data定义为一个对象;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件使用中的细节点2</title>
<script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<table>
<tbody>
<tr is="row"></tr>
</tbody>
</table>
</div>
<script>
Vue.component('row',{
/*data:{
content:'this is a row'
},这样会出现问题,data必须是一个函数*/
data:function() {
return {
content:'this is a row'
}
},
template:'<tr><td>{{content}}</td></tr>'
})
var vm=new Vue({
el:"#root",
data:{
}
})
</script>
</body>
</html>
是因为子组件也许会被调用多次,这样定义使每一个子组件都拥有一个独立的数据存储,互相之间不会影响。
3. ref引用
Vue虽然不建议我们操作 dom ,但是在一些情况下必须要操作dom,这时通过我们要通过 ref引用 来获取dom。通过下面的这个例子来打印div中的内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件使用中的细节点3-ref</title>
<script src=".././node_modules/vue/dist/vue.js"></script>
</head>
<body>
<!--在vue中操作dom通过ref引用的方式-->
<div id="root">
<div
ref="hello"
@click="handleClick"
>
hello world
</div>
</div>
<script>
var vm=new Vue({
el:"#root",
data:{
},
methods:{
handleClick:function () {
/*this.refs.ref指的是vue实例中的所有引用refs,其中一个引用叫ref*/
/*console.log(this.$refs.hello)打印出来的是div这个dom节点*/
alert(this.$refs.hello.innerHTML)
}
}
})
</script>
</body>
</html>
4. 单向数据流
首先来看一个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件传值2</title>
<script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<counter :count="1" @inc="handleChange"></counter>
<counter :count="2" @inc="handleChange"></counter>
<div>{{total}}</div>
</div>
<script>
var counter={
props:['count'],
data:function() {
return{
step:2
}
},
template:'<div @click="handleClick">{{count}}</div>',
methods:{
handleClick:function () {
this.count++; //会发出警告,子组件不能改变从父组件传递过来的数据
this.$emit('inc',2) /*触发这个事件,每次新增2*/
}
}
}
var vm=new Vue({
el:"#root",
data:{
total:3
},
components:{
counter:counter
},
methods:{
handleChange:function (step) {
this.total+=step
}
}
})
</script>
</body>
</html>
在这段代码中,我们实现了子组件向父组件传值:
this.$emit('inc',2)
父组件通过属性向子组件传值:
<counter :count="1" @inc="handleChange"></counter>
<counter :count="2" @inc="handleChange"></counter>
理想的情况是点击子组件渲染的元素,实现数字加一;点击父组件渲染的元素,实现数字加二,但是点击子组件渲染出的元素时发现并不能实现加一的效果,打开控制台,报错信息:
告诉我们说要避免直接修改从父组件接收的参数count,所以可以定义count的副本number:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件传值2</title>
<script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
<counter :count="1" @inc="handleChange"></counter>
<counter :count="2" @inc="handleChange"></counter>
<div>{{total}}</div>
</div>
<script>
var counter={
props:['count'],
data:function() {
return{
number:this.count,
step:2
}
},
template:'<div @click="handleClick">{{number}}</div>',
methods:{
handleClick:function () {
/*this.count++会发出警告,子组件不能改变从父组件传递过来的数据*/
this.number=this.number+2
this.$emit('inc',2) /*触发这个事件,每次新增2*/
}
}
}
var vm=new Vue({
el:"#root",
data:{
total:3
},
components:{
counter:counter
},
methods:{
handleChange:function (step) {
this.total+=step
}
}
})
</script>
</body>
</html>