当前位置:   article > 正文

vue官网-02 组件基础_vue官网button

vue官网button

基础

组件可以复用
组件data必须是函数
methods和生命周期函数不可以使用箭头函数
组件树的概念
// HTML:
<div id="app">
    <button-counter></button-counter>
</div>

<script src="../vue.js"></script>
<script>
	// 声明组件
    Vue.component('button-counter',{
        data:function () {
            return {
                count:0,
            }
        },
        methods:{
            add:function(num){
                this.count+=num;
            }
        },
        template:'<button @click="add(3)">点击{{count}}次</button>'
    })
	
	
    new Vue({
        el:"#app",
    })
</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

注:
1.声明组件在前(全局)。否则报错信息如下:
2.data是个函数,return一个对象。否则复用的时候就共用变量了。报错如下:
3.可以使用函数缩写。
4.不可以使用箭头函数,eg:
5.组件复用

1.报错信息:

Unknown custom element: <button-counter> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
  • 1

2.报错信息:

The "data" option should be a function that returns a per-instance value in component definitions.
  • 1

3.函数缩写

<div id="app">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>

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

    var vm=Vue.component('button-counter',{
        data(){
            return {
                count:0,
            }
        },
        methods:{
            add2(num){
                this.count+=num;
            }
        },
        template:'<button @click="add2(3)">点击{{count}}次</button>'
    })
    new Vue({
        el:"#app",
    })
</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

4.怎么处理箭头函数?=>函数缩写。

var vm = Vue.component('button-counter', {
    data() {
        return {
            count: 0,
        }
    },
    methods: {
        add: (num) => {
            console.log(this); // Window类型
            console.log(this===window); // true
            console.log(this.count); // undefined 或者NaN
            console.log(this.vm);
            console.log(this.vm.count); // undefined
            this.count += num;
        }
    },
    template: '<button @click="add(3)">点击{{count}}次</button>'
})

new Vue({
    el: "#app",
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

正确使用如下:

    methods: {
        add(num) {
            console.log(this);  // Vue
            console.log(this.count); // 0
            this.count += num;
        }
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

methods生命周期函数$watch都不可以使用箭头函数(获取this的时候,指向window了)。
前两种可以使用函数缩写;$watch必须使用function了。

prop传递数据(父传子)

自己的(写死的):

<div id="app">
    <blog-post title="aaa"></blog-post>
    <blog-post title="bbb"></blog-post>
    <blog-post title="ccc"></blog-post>
</div>

<script src="../vue.js"></script>
<script>
    var vm = Vue.component('blog-post', {
        props:['title'],
        template: '<h3>{{title}}</h3>'
    })
     new Vue({
        el: "#app",
    })
</script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

父组件传递的:

<div id="app">

    <blog-post v-for="(item,index) of posts"
               :key="item.id"
               :title="item.title">

    </blog-post>
</div>

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

    var vm = Vue.component('blog-post', {
        props: ['title'],
        template: '<h3>{{title}}</h3>'
    })

    new Vue({
        el: "#app",
        data: {
            posts: [
                {id: 1, title: 'aaaaaa'},
                {id: 2, title: 'bbbbbb'},
                {id: 3, title: 'cccccc'},
            ]
        },
    })
</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

单个根元素

报错信息:

Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
  • 1

监听子组件事件(子传父)

组件声明事件的时候,使用烤串式,不能使用驼峰式,报错eg:

 Note that HTML attributes are case-insensitive and you cannot use v-on to listen to camelCase events when using in-DOM templates.You should probably use "change-font-size" instead of "changeFontSize".

  • 1
  • 2
<div id="app">
    <div :style="{fontSize:postFontSize+'em'}">
        <blog-post v-for="(item,index) of posts"
                   :key="item.id"
                   :item="item"
                   @change-font-size='big();'>

        </blog-post>
    </div>

</div>

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

    var vm = Vue.component('blog-post', {
        props: ['item'],
        template: `<div>
			<h3>{{item.title}}</h3>
			<button @click="$emit('change-font-size')">放大</button>
			</div>`
    })

    new Vue({
        el: "#app",
        data: {
            posts: [
                {id: 1, title: 'aaaaaa'},
                {id: 2, title: 'bbbbbb'},
                {id: 3, title: 'cccccc'},
            ],
            postFontSize: 1,
        },
        methods: {
            big() {
                this.postFontSize += 0.1;
            }
        },
        computed: {},

    })
</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

传递参数:

<div id="app">
    <div :style="{fontSize:postFontSize+'em'}">
        <blog-post v-for="(item,index) of posts"
                   :key="item.id"
                   :item="item"
                   @change-font-size='big'>

        </blog-post>
    </div>

</div>

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

    var vm = Vue.component('blog-post', {
        props: ['item'],
        template: `<div>
                <h3>{{item.title}}</h3>
                <button @click="$emit('change-font-size',0.1)">放大</button>
            </div>`
    })

    new Vue({
        el: "#app",
        data: {
            posts: [
                {id: 1, title: 'aaaaaa'},
                {id: 2, title: 'bbbbbb'},
                {id: 3, title: 'cccccc'},
            ],
            postFontSize: 1,
        },
        methods: {
            big(e) {
                this.postFontSize += e;
            }
        },
        computed: {},

    })
</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

通过插槽分发内容

<div id="app">
  <alert-box>传递过去的文字</alert-box>

</div>

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

    var vm = Vue.component('alert-box', {
        template: `<div>
            <strong>Error!</strong>
            <slot></slot>
            </div>`
    })

    new Vue({
        el: "#app",
    })
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

slot把子组件中间的内容带过去。

问题:
1.slot与props的区别是什么???

动态组件

<style>
    .active {
        color: red;
    }
</style>
<div id="app">
    <button v-for='item of tabs' 
    		:key='item'
            :class="{'active':currentTab==item}"
            @click="changeTab(item)">{{item}}
    </button>

	<!--component可以是其他标签-->
    <component :is="currentTabComponent"></component>
    <div>
        {{currentTabComponent}}
    </div>

</div>

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

    Vue.component('tab-home', {
        template: `<div>Home 组件</div>`
    });
    Vue.component('tab-posts', {
        template: `<div>posts 组件</div>`
    });
    Vue.component('tab-archive', {
        template: `<div>archive 组件</div>`
    });

    new Vue({
        el: "#app",
        data: {
            currentTab: 'Home',
            tabs: ['Home', 'Posts', 'Archive'],
        },
        methods: {
            changeTab(item) {
                this.currentTab = item;
            }
        },
        computed: {
            currentTabComponent() {
                return 'tab-' + this.currentTab.toLowerCase();
            }
        },

    })
</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
 <component :is="currentTabComponent"></component> 
// 代替了*ngIf来判断显示哪个。
// 等同于:

<tab-home v-if='currentTab=="Home"'></tab-home>
<tab-posts v-if='currentTab=="Posts"'></tab-posts>
<tab-archive v-if='currentTab=="Archive"'></tab-archive>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

is的用法:

<table>
  <blog-post-row></blog-post-row>
</table>

// 修改为:

<table>
  <tr is="blog-post-row"></tr>
</table>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

问题:

大小写:
组件名:
子组件属性:
子组件事件:

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号