Vue组件化的实现和使用步骤
注册组件的基本步骤
- 创建组件构造器
- 注册组件
- 使用组件
具体实现[最基础的使用]:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue事件监听练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!-- s使用注册好的组件 -->
<userdifine>
</userdifine>
</div>
</body>
</html>
<script>
//创建组件构造器
const compomentConstruct = Vue.extend({
template: `
<div>
<h1>Test</h1>
</div>
`
});
//注册组件
Vue.component('userdifine',compomentConstruct);
//初始化
let app = new Vue({
el: '#calc'
,data: {
}
,methods:{
}
,computed: {
}
})
</script>
运行结果如下:
这是最简单的组件化使用,第一步先定义好组件,然后第二步进行注册。值得一提的是,上面在template中用到了ES6语法,``
,使用这个可以空行。
全局组件、局部组件
上面的方式是全局注册组件
Vue.component('userdifine',compomentConstruct);
实例,代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue事件监听练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!-- s使用注册好的组件 -->
<userdifine>
</userdifine>
</div>
<div id="appS">
我是第二个vue实例
<userdifine ></userdifine>
</div>
</body>
</html>
<script>
//创建组件构造器
const compomentConstruct = Vue.extend({
template: `
<div>
<h1>Test</h1>
</div>
<div>
`
});
//注册组件
Vue.component('userdifine',compomentConstruct);
//初始化
let app = new Vue({
el: '#calc'
,data: {
}
,methods:{
}
,computed: {
}
})
let appS = new Vue({
el: '#appS'
})
</script>
运行结果如下:
可以看到,第二个vue实例也可以使用我们注册的组件。
全局组件可以在多个Vue实例下使用。
下面是创建注册局部组件的方式,代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue事件监听练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!-- s使用注册好的组件 -->
<userdifine></userdifine>
</div>
<div id="appS">
我是第二个vue实例
<userdifine ></userdifine>
</div>
</body>
</html>
<script>
//创建组件构造器
const compomentConstruct = Vue.extend({
template: `
<div>
<h1>Test</h1>
</div>
<div>
`
});
//初始化
let app = new Vue({
el: '#calc'
,data: {
}
,methods:{
}
,computed: {
}
,components: {
//局部注册组件
userdifine: compomentConstruct
}
})
let appS = new Vue({
el: '#appS'
})
</script>
运行结果如下:
可以看到,第二个vue实例里面不能使用局部组件。
父组件和子组件
即,组件构造器里面可以进行写components
,对其进行组件嵌套,代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue事件监听练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!--使用注册好的组件 -->
<userdifine></userdifine>
</div>
</body>
</html>
<script>
//创建组件构造器
const compomentConstruct_Child = Vue.extend({
template: `
<div>
<h6>我是儿子</h6>
</div>
`
});
const compomentConstruct_Father = Vue.extend({
template: `
<div>
<h1>我是爸爸</h1>
<userdifine2></userdifine2>
</div>
`
,components: {
userdifine2: compomentConstruct_Child
}
});
//初始化
let app = new Vue({
el: '#calc'
,data: {
}
,methods:{
}
,computed: {
}
,components: {
//局部注册组件
userdifine: compomentConstruct_Father
}
})
</script>
运行结果如下:
从结果可以看出,组件定义compomentConstruct_Father
中使用了子组件compomentConstruct_Child
。
注册组件的语法糖写法
简洁,利于阅读代码,代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue事件监听练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!-- s使用注册好的组件 -->
<!-- 全局组件语法糖使用测试 -->
<test></test>
<!-- 局部组件语法糖使用测试 -->
<apple></apple>
</div>
</body>
</html>
<script>
//创建组件构造器
Vue.component('test',{
template: `
<div>
<h6>hello</h6>
</div>
`
});
//初始化
let app = new Vue({
el: '#calc'
,data: {
}
,methods:{
}
,computed: {
}
,components: {
//局部注册组件
'apple': {
template: `
<h1>aaaaaaaaaa</h1>
`
}
}
})
</script>
运行结果如下:
组件化抽离方法
这么做,使代码变得更容易阅读。代码示例如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue组件a练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!-- 全局组件语法糖使用测试 -->
<test></test>
</div>
</body>
</html>
<script type="text/x-template" id="testTemplate">
<div>
<table>
<thead>
<th>
A
</th>
<th>
B
</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
</div>
</script>
<script>
//创建组件构造器
Vue.component('test',{
template: testTemplate
});
//初始化
let app = new Vue({
el: '#calc'
,data: {
}
,methods:{
}
,computed: {
}
,components: {
}
})
</script>
运行结果如下:
还可以使用标签来定义其内容。
往组件里面传vue参数
注意: 组件不可以访问Vue示例数据!
组件也可以有data等属性,给个代码示例如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue组件a练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!-- 全局组件语法糖使用测试 -->
<test></test>
</div>
</body>
</html>
<script type="text/x-template" id="testTemplate">
<div>
<!-- 引用组件自己的数据 -->
<h3>{{myname}}</h3>
</div>
</script>
<script>
//创建组件构造器,并且是组件自己的数据!
Vue.component('test',{
template: testTemplate
,data(){
return {
myname: 'CharLinHeng'
}
}
});
//初始化
let app = new Vue({
el: '#calc'
,data: {
}
,methods:{
}
,computed: {
}
,components: {
}
})
</script>
代码运行结果如下:
上面中,组件里面的data为什么是一个函数?原因总结如下:
-
假设不是函数,是像vue示例那样的data对象属性,那么使用多个组件的时候,data的值就会共享,示例代码如下:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>vue组件a练习</title> </head> <script src="./js/vue.js"></script> <body> <div id="calc"> <!-- 全局组件语法糖使用测试 --> <test></test> <test></test> <test></test> </div> </body> </html> <script type="text/x-template" id="testTemplate"> <div> <!-- 引用组件自己的数据 --> <h6>这个是计数器</h6> <button @click="sub">-</button> <input type="text" :value="values"> <button @click="add">+</button> </div> </script> <script> //创建组件构造器,并且是组件自己的数据! Vue.component('test',{ template: testTemplate ,data(){ return { values: 0 } } ,methods: { sub(){ this.values--; } ,add(){ this.values++; } } }); //初始化 let app = new Vue({ el: '#calc' ,data: { } ,methods:{ } ,computed: { } ,components: { } }) </script>
运行结果如下:
组件之间的通信
案例: 父组件, 传值给子组件,代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue组件a练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!-- 全局组件,然后下面试 prop属性 绑定根组件传过来得值 -->
<test :message ="movicename" :va="vas"></test>
</div>
</body>
</html>
<script type="text/x-template" id="testTemplate" >
<div>
<!--根组件,传值进来了,然后咱调用-->
<h2>{{message}}</h2>
<button>{{va}}</button>
</div>
</script>
<script>
//创建组件构造器,并且是组件自己的数据!
Vue.component('test',{
template: testTemplate
,props: ["message","va"]
,data(){
return {
}
}
,methods: {
}
});
//初始化
let app = new Vue({
el: '#calc'
,data: {
movicename:[
{Appe: "苹果"}
,{Xueli: "雪梨"}
,{QinJ: "青椒"}
]
,vas: "Hello"
}
,methods:{
}
,computed: {
}
,components: {
}
,watch: {
}
})
</script>
运行结果如下:
发现,父组件传值到子组件了。
prop指定类型,代码修改如下:
Vue.component('test',{
template: testTemplate
,props: {
//这里是另一种写法,定义数据变量类型
message: String
,va : Array
}
,data(){
return {
}
}
,methods: {
}
});
prop指定类型,并且定义默认值
Vue.component('test',{
template: testTemplate
,props: {
//这里是另一种写法,定义数据变量类型,而且定义默认值
message: {
type:String
,default: "Hi,i am default"
}
,va :{
type: Array
,default(){
return [];
}
}
}
,data(){
return {
}
}
,methods: {
}
});
更具体常用的类型有:
子组件通信父组件 [子传父]
可以通过自定义事件来实现子组件将数据传给父组件。
通过下面的实例来描述,代码如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue组件a练习</title>
</head>
<script src="./js/vue.js"></script>
<body>
<div id="calc">
<!-- 全局组件,然后下面试 prop属性 绑定根组件传过来得值 -->
<test :message ="movicename" :va="vas" @clicktoather="fatherlisten"></test>
</div>
</body>
</html>
<script type="text/x-template" id="testTemplate" >
<div>
<button v-for="(item,index) in catolog" :id="index+1" @click="showclick(item.name)" :value="item.id">{{item.name}}</button>
</div>
</script>
<script>
//创建组件构造器,并且是组件自己的数据!
Vue.component('test',{
template: testTemplate
,props:{
}
,data(){
return {
catolog: [
{id:1, name: "电脑"}
,{id:2,name: "家具"}
,{id:3,name: "五金"}
,{id:4,name: "一次性"}
,{id:5,name: "垃圾袋"}
]
}
}
,methods: {
showclick(value){
// console.log(value);
//发射,传值给父组件
this.$emit('clicktoather',value)
}
}
});
//初始化
let app = new Vue({
el: '#calc'
,data: {
}
,methods:{
fatherlisten(...num){
console.log("父亲监听到了,儿子传过来的值是:"+num[0])
}
}
,computed: {
}
,components: {
}
,watch: {
}
})
</script>
然后,运行结果: