组件分为全局注册与局部注册
全局注册 (不常用)
优点: 所有vue实例都可以使用
缺点: 权限太大 容错率降低
<body>
<div id="demo">
<my-component></my-conponent>
</div>
</body>
<script>
Vue.component('my-component',{
template:'<div>我是一个组件</div>'
})
var app = new Vue({
el:'#demo'
})
</script>
复制代码
输出结果
代码解构:
局部注册
<body>
<div id="demo">
<app-component></app-component>
</div>
</body>
<script>
var app = new Vue({
el:'#demo',
components:{
'app-component':{
template:'<span>局部注册的组件</span>'
}
}
})
</script>
</html>
复制代码
显示结果
DOM结构
Tip: html标签受限
例如再table中加入span
<body>
<div id="demo">
<!-- <my-component></my-component>
<app-component></app-component> -->
<table>
<app-component></app-component>
</table>
</div>
</body>
复制代码
显示结果 虽然显示了 但是dom结构不对
解决方法 is
<body>
<div id="demo">
<!-- <my-component></my-component>
<app-component></app-component> -->
<table>
<tbody is='app-component'></tbody>
</table>
</div>
</body>
复制代码
显示结果 dom结构
组件注意事项
- 纯小写字母 name
- 小写字母 加 - 例 my-name
- template中的内容必须被DOM元素包裹 例:
template也可以嵌套
- 再组件中除了template 还可以有data computed mehods
- 组件中data 必须是一个方法
点哪个按钮 哪个按钮变化 虽然都是 但是返回值不一样
body>
<div id="demo">
<btn-s></btn-s>
<btn-s></btn-s>
</div>
</body>
<script>
Vue.component('my-component',{
template:'<div>全局注册组件</div>'
})
var app = new Vue({
el:'#demo',
data:{
count:1
},
components:{
'btn-s':{
template:'<button @click="count++">{{count}}</button>',
data:function(){
return {
count:0
}
}
}
}
})
</script>
复制代码
输出结果:
父组件像子组件传递内容
<body>
<div id="demo" >
<div ></div>
<child-node msg='父组件传递的内容' ></child-node>
</div>
</body>
<script>
var app = new Vue({
el:'#demo',
data:{
},
components:{
'child-node':{
props:['msg'],
template:'<div>{{msg}}</div>'
}
}
})
</script>
复制代码
显示结果:
- 使用v-bind进行数据动态绑定
<body>
<div id="demo" >
<div ></div>
<input type="text" v-model="parentText">
<child-text :mtext="parentText"></child-text>
</div>
</body>
<script>
var app = new Vue({
el:'#demo',
data:{
parentText:'父组件内容'
},
components:{
'child-text':{
props:['mtext'],
template:'<div>{{mtext}}</div>'
}
}
})
</script>
</html>
复制代码
输出结果:
使用v-bind 使用与否的区别
* <child-node msg='[1,2,3,4]' ></child-node> 传递的是字符串 * * <child-node :msg='[1,2,3,4]' ></child-node> 传递的是数组
可以用length 检验
复制代码
vue组件的命名
- 再html中 不区分大小写 所以只能以短横线形式命名 c-ode
<body>
<div id="demo" >
<codName></codName> '错误的名字书写方式 输出是所有字母都会转为小写找不到vuejs对应的组件名所以无法正确渲染'
<cod-name></cod-name> 'vuejs中的驼峰命名对应html中的短横线命名'
</div>
</body>
<script>
var app = new Vue({
el:'#demo',
components:{
'codName':{
template:'<div>template</div>'
}
}
})
</script>
复制代码
输出结果
- vue JS中是区分大小写的 再vuejs中必须用驼峰 不能写短横线
<body>
<div id="demo" >
<cod-name contentType="一朵花"></cod-name> <!-- '错误 插件名没有用短横线' -->
<cod-name content-type="一棵树"></cod-name>
<cod-name content-type="一片海"></cod-name>
</div>
</body>
<script>
var app = new Vue({
el:'#demo',
data:{
parentText:'父组件内容'
},
components:{
'codName':{
props:['contentType'],
// props:['text-type'], '错误 名字不可以用短横线'
template:'<div>{{contentType}}</div>'
//template:'<div>{{content-type}}</div>' 这里也不可以使用短横线
}
}
})
</script>
</html>
components:{
'codName':{
props:['contentType'],
// props:['text-type'], '错误 名字不可以用短横线'
template:'<div>{{contentType}}</div>',
data:function(){
return{
abc:this.contentType '这里也要驼峰'
}
}
}
}
复制代码
数据验证 验证类型 自定义验证
<body>
<div id="demo" >
<vle-type :a='a' :b='b' :c='c' :d='d' :f='f' :g='g' :h='h' :i='i'></vle-type>
</div>
</body>
<script>
var app = new Vue({
el:'#demo',
data:{
parentText:'父组件内容',
a:1,
b:'string类型',
// 'vue.js:597 [Vue warn]: Invalid prop: type check failed for prop "c". Expected Number, got String.'
c:'props 判定为Number类型 但是我是string类型 会报错 但不还是会渲染',
d:6666,
e:'', //假如为空 就取默认值 传入字符串也会渲染传入的值 但是会报错
f:3224234, //假如为空 报错
g:[0999],
h:88,
i:console.log()
},
components:{
'vleType':{
props:{
a:Number, //判断接受的绑定值 是否为Number类型
b:String, //判断接受的绑定值 是否为String类型
c:Number,
d:[Number,String], //即可意识 Number 又可以是 String
//必须布尔类型 默认true 指定类型 又要指定默认值 就要写成一个对象 里边可以有的选项 type(类型)---required(是否为必传项)----default(默认值)
e:{
type:Boolean,
default:true
},
f:{
type:Number,
required:true //必传项 如果不传 报错-->[Vue warn]: Missing required prop: "f"
},
//数组或对象默认值设定
g:{
type:Array,
default:function(){
return [555] //如果父组件没有响子组件传 那么就会显示 这个555
}
},
//自定义一个验证函数
h:{
validator:function(value){
return value>10
}
},
//验证是否为function
i:{
type:Function
}
},
template:'<div>{{a}} -- {{b}} --{{c}}----{{d}} ---- {{e}} ----{{f}} --{{g[0]}} ---{{h}} ----{{i}}</div>'
}
}
})
</script>
</html>
复制代码
子组件像父组件通信
javacsript的设计模式--观察者模式 有两个方法 dispatchEvent(触发事件)和addEventListener(添加事件监听器) vue组件中也有一套模式 子组件用 $emit() '触发事件' 父组件用 $on()'来监听子组件的事件'
例子 子组件像父组件更新数据
<body>
<div id="demo">
你兜里有{{tal}}
<vl-text @change="changexx"> </vl-text>
</div>
</body>
<script>
var app = new Vue({
el:'#demo',
data:{
tal:1000
},
methods:{
changexx:function(value){
//出处的形参value 就是this.tal
this.tal=value
}
},
components:{
'vlText':{ //template data mdehods 同级
template:'<div>\
<button @click="buttonadd"> + </button> \
<button @click="buttonlost"> - </button> \
</div>',
data:function(){
return{
tal:1000
}
},
methods:{
buttonadd:function(){
this.tal=this.tal+1000
this.$emit('change',this.tal) // 时间名 参数 后面可以加N个参数 只要顺序顺序要正确
},
buttonlost:function(){
this.tal=this.tal-1000
this.$emit('change',this.tal)
}
}
}
}
})
</script>
</html>
复制代码