Vue学习笔记10:组件基础与注册

10 篇文章 0 订阅

组件基础

组件基础

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件基础</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="components-demo1">
    <!-- 组件是可复用的Vue实例 -->
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>
<script>
    // Vue.component 全局注册组件
    Vue.component('button-counter', {
        // 组件内定义data时必须是一个函数
        // 每个实例维护一份返回对象的独立拷贝
        data: function () {
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">You Clicked me {{count}} times.</button>'
    })
    // 经过全局注册的组件可以用在任何新创建的Vue根实例(new Vue)
    new Vue({
        el: '#components-demo1'
    })
</script>
</body>
</html>

在这里插入图片描述

向子组件传递数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>向子组件传递数据</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="components-demo2">
    <!-- title2 自定义的attribute -->
    <!-- 将数据传递到自定义component中 -->
    <blog-post1 title2="title-2"></blog-post1>
    <!-- 通过v:bind动态传递prop -->
    <blog-post2 v-for="post in posts"
                v-bind:key="post.id"
                v-bind:post="post"></blog-post2>
</div>
<script>
    Vue.component('blog-post1', {
        // 使用prop自定义一个attribute
        props: ['title2'],
        // 在模版中使用通过prop传递的数据
        template: `<h3>{{ title2 }}</h3>`
    })
    Vue.component('blog-post2', {
        props: ['post'],
        // 模版只能有一个根元素(使用div标签包裹内容)
        template: `
          <div>
          <h3>{{ post.title }}</h3>
          <p>{{ post.content }}</p>
          </div>`
    })
    new Vue({
        el: '#components-demo2',
        data: {
            posts: [
                {id: 1, title: 'title-aaa', content: 'content-aaa'},
                {id: 2, title: 'title-bbb', content: 'content-bbb'},
                {id: 3, title: 'title-ccc', content: 'content-ccc'},
            ]
        }
    })
</script>
</body>
</html>

在这里插入图片描述

监听子组件事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>监听子组件事件</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="components-demo3" :style="{fontSize: postFontSize + 'em'}">
    <!-- 使用v-on来监听子组件定义的任意事件 -->
    <!-- 在组件实例中实现具体的事件逻辑 -->
    <!-- 使用$event访问模版中提供的特定值 -->
    <blog-post1 title="title-1"
                v-on:enlarge-text="postFontSize +=0.1"
                v-on:reduce-text="postFontSize -=$event"
                v-on:reset-text="onResetText($event)">
    </blog-post1>

    <!-- 在组件上使用v-model -->
    <p>{{text1}}</p>
    <blog-post2 v-model="text1"></blog-post2>
</div>
<script>
    Vue.component('blog-post1', {
        props: ['title'],
        template: `
          <div>
          <h3>{{ title }}</h3>
          <!-- 模版中定义出发方式与调用方法-->
          <!-- 调用内建的$emit方法并传入事件名称来触发事件 -->
          <button v-on:click="$emit('enlarge-text')">
            Enlarge Text
          </button>
          <!-- $emit方法第二个参数为定义的事件提供特定值 -->
          <button v-on:click="$emit('reduce-text', 0.1)">
            Reduce Text
          </button>
          <button v-on:click="$emit('reset-text', 1)">
            Reset Text
          </button>
          </div>`
    })
    Vue.component('blog-post2', {
        // 在组件上使用v-model需要使用如下代码
        // 将其 value attribute 绑定到一个名叫 value 的 prop 上
        // 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
        props: ['value'],
        template: `
          <input
              v-bind:value="value"
              v-on:input="$emit('input', $event.target.value)"/>
        `
    })
    new Vue({
        el: '#components-demo3',
        data: {
            postFontSize: 1,
            text1: "123"
        },
        methods: {
            onResetText: function (resetValue) {
                this.postFontSize = resetValue;
            }
        }
    })
</script>
</body>
</html>

在这里插入图片描述

通过插槽分发内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>通过插槽分发内容</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <style>
        .demo-alert-box {
            padding: 10px 20px;
            background: #eac0ba;
            border-style: solid;
            border-width: 1px;
            border-color: #e29c9a;
        }
    </style>
</head>
<body>
<div id="components-demo4">
    <alert-box>{{msg}}</alert-box>
</div>
<script>
    Vue.component('alert-box', {
        template: `
        <div class="demo-alert-box">
        <strong>Error!</strong>
        <!-- 使用Vue自定义的<slot>元素来加入插槽(替换成组件实例的内容) -->
        <slot></slot>
        </div>`
    })
    new Vue({
        el: '#components-demo4',
        data: {
            msg: 'Something bad happened.'
        }
    })
</script>
</body>
</html>

在这里插入图片描述

动态组件

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>动态组件</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <style>
        .tab-button {
            padding: 6px 10px;
            border-top-left-radius: 3px;
            border-top-right-radius: 3px;
            border: 1px solid #ccc;
            cursor: pointer;
            background: #f0f0f0;
            margin-bottom: -1px;
            margin-right: -1px;
        }

        .tab-button:hover {
            background: #e0e0e0;
        }

        .tab-button.active {
            background: #e0e0e0;
        }

        .tab {
            border: 1px solid #ccc;
            padding: 10px;
        }
    </style>
</head>
<body>
<div id="dynamic-component-demo1" class="demo">
    <button v-for="tab in tabs"
            v-bind:key="tab"
            v-bind:class="['tab-button', { active: currentTab === tab }]"
            v-on:click="currentTab = tab">
        {{ tab }}
    </button>
    <!-- 使用v-bind:is指定已注册组件的名字 -->
    <component v-bind:is="currentTabComponent" class="tab"></component>
</div>
<br/>
<div id="dynamic-component-demo2" class="demo">
    <button v-for="tab in tabs"
            v-bind:key="tab.name"
            v-bind:class="['tab-button', { active: currentTab.name === tab.name }]"
            v-on:click="currentTab = tab">
        {{ tab.name }}
    </button>
    <!-- 使用v-bind:is指定组件的选项对象 -->
    <component v-bind:is="currentTab.component" class="tab"></component>
</div>

<script>
    // 使用已注册组件名示例
    Vue.component("tab-home", {
        template: "<div>Home component</div>"
    });
    Vue.component("tab-posts", {
        template: "<div>Posts component</div>"
    });
    Vue.component("tab-archive", {
        template: "<div>Archive component</div>"
    });
    new Vue({
        el: "#dynamic-component-demo1",
        data: {
            currentTab: "Home",
            tabs: ["Home", "Posts", "Archive"]
        },
        computed: {
            currentTabComponent: function () {
                return "tab-" + this.currentTab.toLowerCase();
            }
        }
    });

    // 使用组件的选项对象示例
    var tabs = [
        {
            name: "Home",
            component: {
                template: "<div>Home component</div>"
            }
        },
        {
            name: "Posts",
            component: {
                template: "<div>Posts component</div>"
            }
        },
        {
            name: "Archive",
            component: {
                template: "<div>Archive component</div>"
            }
        }
    ];
    new Vue({
        el: "#dynamic-component-demo2",
        data: {
            tabs: tabs,
            currentTab: tabs[0]
        }
    });
</script>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

组件注册

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件注册</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app1">
    <!-- 全局注册的组件能用在任何Vue实例的模版中 -->
    <component-a></component-a>
    <component-b></component-b>
    <component-c></component-c>
</div>
<br/>
<div id="app2">
    <!-- 全局注册的组件能用在任何Vue实例的模版中 -->
    <component-a></component-a>
    <component-b></component-b>
    <component-c></component-c>
    <!-- 局部注册的组件只能用在被注册的Vue实例模版中 -->
    <component-d></component-d>
    <component-e></component-e>
    <component-f></component-f>
</div>
<script>
    // 建议使用kebab-case(短横线分隔命名)定义一个组件
    Vue.component('component-a', {template: "<div>Component A</div>"})
    Vue.component('component-b', {template: "<div>Component B</div>"})
    Vue.component('component-c', {template: "<div>Component C</div>"})
    new Vue({el: '#app1'})

    var ComponentD = {template: "<div>Component D</div>"}
    var ComponentE = {template: "<div>Component E</div>"}
    var ComponentF = {template: "<div>Component F</div>"}
    new Vue({
        el: '#app2',
        components: {
            'component-d': ComponentD,
            'component-e': ComponentE,
            'component-f': ComponentF
        }
    })

</script>
</body>
</html>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值