09.组件

goer ... 2022-01-06 Vue
  • Javascript
  • Vue
大约 2 分钟

组件

[toc]

# 组件

组件:也是vue的一个特色

重复的功能封装为组件

// 定义一个点击的组件 
// 标签   就是  组件名称
    <nva-box></nva-box>
    <nva-box></nva-box>  
//注册组件名字
Vue.component('nva-box',{
    data: function(){
        return{
        	num:1,
    	}
    },
    methods:{
        addnum:function(){
        	this.num ++
        }
    },
    //组件内容
    template:'<button v-on:click="addnum">点了我{{num}}次了</button>'
})

// 可以多次调用了
思考下 data(){}  和 data{} 区别 
也可以试下看下效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

不然就会一个变全都变了

props组件定义==属性==,向子==组件传递数据==

// 向子组件传递参数
<div id="app">
    <vue-box title="title1" sex="sex1"></vue-box>
	<vue-box title="title2" sex="sex2"></vue-box>
	<vue-box title="title3" sex="sex3"></vue-box>
	<vue-box title="title4" sex="sex4"></vue-box>
</div>


//定义组件
Vue.component('vue-box',{
    props:['title','sex'], //属性
    template:'<h3>{{title}}-----{{sex}}</h3>',
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

组件的模板必须具有==根节点==

Vue.component('vue-box',{
    props:['title','sex'], //属性
    template:'<h3>{{title}}-----{{sex}}</h3>',
})
// h3 不具备根节点 ,所以只能有一个html标签
1
2
3
4
5
Vue.component('vue-box2',{
    template:'<div>
    	<h1>hello</h1>
    	<button>aaa</h1>
    </div>',
})
// div 就是根节点  可以带多个html标签
1
2
3
4
5
6
7

组件的事件监听 $emit()方法


<!-- @clicknum="clicknum" 事件绑定-->
<vue-box title="title1" sex="sex1" @clicknum="clicknum"></vue-box>

//定义组件
Vue.component('vue-box',{
    props:['title','sex'],
    data:function(){
        return{
            num:0,
        }
    },
    template:'<div><h3>{{title}}-----{{sex}}</h3><button @click="connum">次数:{{num}}</button></div>',
    methods:{
        connum(){
            this.num++
            // $emit 事件监听
            this.$emit('clicknum',this.num)
        },
    }
})

const app = new Vue({
    el:'#app',
    data:function(){
        return{

        }
    },
    // 事件绑定接受 组件传来的值
    methods:{
        clicknum(e){
            console.log(e)
        }
    }
})

// 1. $emit 事件监听
// 2. 在组件上 @clicknum="clicknum" 事件绑定
// 3. 事件绑定接受 组件传来的值 函数接受到
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

插槽: <slot></slot>在组件内容加插值我们就可以在子组件插入html标签了,不然不行


<but-add title="hello" @clicknum="clicknum">
    <h1>hello</h1>
</but-add>

 Vue.component('but-add',{
     props:['title'],
     data(){
         return{
             num:0,
         }
     },
     template:'<div> <h1>{{title}}</h1> <button @click="numadd">点击:{{num}}</button> <slot></slot></div>',
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14

有点复杂,好好理解,你会发现很棒

小作业:做一个可以添加的列表 也可以删除

    <div id="list-shop">
        <!-- 
            v-on:submit.prevent 提交表单不刷新页面修饰符
         -->
        <form v-on:submit.prevent="addnew">
            <input type="text" placeholder="添加tool" v-model="newtool">
            <button>add tool</button>
        </form>
        <ul>
            <!-- 
                is="list-item" 绑定组件
                v-bind:key="tool.id" 绑定:key,提高性能
                v-bind:title="tool.title" 子组件的 props 给他传值过去
                v-on:remove="tools.splice(index,1)"  子组件的 事件绑定 click="$emit(\'remove\')"
             -->
            <li
                is="list-item"
                v-for ="tool,index in tools"
                v-bind:key="tool.id"
                v-bind:title="tool.title"
                v-on:remove="tools.splice(index,1)"  
            ></li>
        </ul>
    </div>

    <script src="./script/vue.js"></script>
    <script>

        Vue.component('list-item',{
            template:'<li>\
                {{title}}\
                <button v-on:click="$emit(\'remove\')">remove</button>\
                </li>',
            props:['title'],
        })

        const listShop = new Vue({
            el:'#list-shop',
            data(){
                return{
                    newtool:'',
                    newid:4,   
                    tools:[
                        {
                            id:1,
                            title:'aaaaaaaa',
                        },
                        {
                            id:2,
                            title:'bbbbbbbb',
                        },
                        {
                            id:3,
                            title:'cccccccc',
                        }
                    ]
                }
            },
            methods:{
                addnew(){
                    this.tools.push({  // 数组添加一个对象
                        id:this.newid++,
                        title:this.newtool,
                    })
                    this.newtool = ''
                }
            }
        })
    </script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69