【前端】组件基础使用

一、Vue的组件-第一个实例

组件是可复用的Vue实例,它们与 new Vue 接收相同的选项,即一种自定义模板;
在这里插入图片描述

为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。
使用Vue.component进行全局注册

<div id="app">
  <mycomponent></mycomponent>
 </div>
 <script src="../js/vue.js"></script>
 <script>
     // 声明一个组件 第一个参数是组件名称,第二个是具体参数
     Vue.component('mycomponent', {
         template: '<h1>Hello</h1>'
     })
 </script>

这里不能使用大写字母,最开始使用的myComponent,页面渲染失效;
组件的名字使用驼峰命名,在使用组件的时候必须大写改为小写,然后用 “-” 链接。
在这里插入图片描述
在渲染失败的时候,标签名称可以看到变成了全部小写

第二种创建组件的方式

在第一种方式中,template的内容使用字符串的方式写在js中,没有提示很容易写错;可以使用< template >的方式在html中进行声明,然后利用id进行注册。

<div id="app" v-cloak>
    <my-second></my-second>   // 命名要小写
 </div>

 <template id="test">   // 在html中使用<template> 定义组件
     <ul>
         <li>1</li>
         <li>2</li>
         <li>3</li>
         <li>4</li>
         <li>5</li>
     </ul>
 </template>

 <script src="./vue.js"></script>
 <script>
     Vue.component('mySecond', {   // 定义全局组件
         template: '#test'   // 使用id引入组件
     })
     new Vue({
         el: '#app',
         data: {
             a: 1,
             
         }
     })
 </script>

定义私有组件

私有组件-一个Vue实例中使用的组件

<div id="app" v-cloak>
       <my-private-com></my-private-com>
    </div>

    <template id="private">
        <span>这是一个私有的组件</span>
    </template>
<script>
    // 私有组件
    new Vue({
        el: '#app',
        data: {
            a: 1,
            
        },
        components: {
            myPrivateCom: {
                template: '#private'
            }
        }
    })
</script>

二、组件中的data和methods

data属性和methods的使用

组件中的data需要显示的返回对象而不能是一个具体的数据

  1. 组件中的data返回的是一个对象
  2. 组件中的methods和实例中定义相同
  1. 基础页面:
<div id="app">
  <my-com></my-com>
</div>

<template id="first">
    <h1>这是 一个测试组件</h1>
</template>

<script src="./vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {},
        components: {
            myCom: {
                template: '#first'
            }
        }
    })
</script>
  1. 属性添加
    修改html如下:
<template id="first">
    <div>
        <h1>这是 {{ name }}一个测试组件</h1>  <!-- 组件中返回的数据对象 -->
        <button @click="onclick">点击</button>  <!-- 绑定方法 -->
    </div>  <!-- 同样的一个组件只能有一个root -->
</template>
<script>
    new Vue({
        el: '#app',
        data: {},
        components: {
            myCom: {
                template: '#first',
                data: function() {  // 定义data属性
                    return {  // 返回对象
                        name: 'righteye'  // 具体的数据部分
                    }
                },
                methods: {  // 定义方法,和在实例中类似
                    onclick() {
                        console.log("按钮被点击")
                    }
                }
            }
        }
    })
</script>

在这里插入图片描述

为什么组件中的data要返回对象

Q: 为什么组件中的data属性要返回对象?
A:组件的意义是重用,表示我们可以在html中定义多个相同的组件,那么同一个组件模板中的动态属性应该是相互独立的,因此需要返回对象将数据保存在不同的实例对象中。

三、使用props向子组件传值

Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。

2.1 第一个实例:传递单值

<div id="app">
 <mycomponent com_val="Java"></mycomponent>
</div>
<script src="../js/vue.js"></script>
<script>
    // 声明一个组件 第一个参数是组件名称,第二个是具体参数
    Vue.component('mycomponent', {
        props: ['com_val'],
        template: '<h3>{{com_val}}</h3>'
    })
    let vue = new Vue({
        el: '#app',
    })
</script>

在这里插入图片描述

2.2 遍历数组获取值

<div id="app">
    <mycomponent v-for="item in items" :com_val="item"></mycomponent>
</div>
<script src="../js/vue.js"></script>
<script>
    // 声明一个组件 第一个参数是组件名称,第二个是具体参数
    Vue.component('mycomponent', {
        props: ['com_val'],
        template: '<h3>{{com_val}}</h3>'
    })
    let vue = new Vue({
        el: '#app',
        data: {
            items: ['Java', 'Python', 'Go', 'C++']
        }
    })
</script>

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

2.3 单个根元素

<div id="app">
  <mycomponent com_val="Java" title="入门Vue"></mycomponent>
</div>
<script src="../js/vue.js"></script>
<script>
    // 声明一个组件 第一个参数是组件名称,第二个是具体参数
    Vue.component('mycomponent', {
        props: ['com_val', 'title'],
        template: `  // 这里使用 飘 号,能够写多行
            <div class="mycomponent">  // 指定一个父标签进行包裹
                <h3>{{com_val}}</h3>
                <div>{{title}}</div>
            </div>
        `
            
    })
    let vue = new Vue({
        el: '#app',
    })
</script>

官网里说不进行父元素包裹:Vue 会显示一个错误,并解释道 every component must have a single root element (每个组件必须只有一个根元素)。

// 多个根元素,此时会报错
<h3>{{com_val}}</h3><div>{{title}}</div>

当props中属性增多的时候,对于标签中的代码会显的很冗余,因此可以使用下面的写法:

<div id="app">
   <mycomponent v-for="item in items" :post="item"></mycomponent>
</div>
<script src="../js/vue.js"></script>
<script>
    // 声明一个组件 第一个参数是组件名称,第二个是具体参数
    Vue.component('mycomponent', {
        props: ['post'],
        template: `
            <div class="mycomponent">
                <li>{{post.id}}</li>
                <li>{{post.title}}</li>
                <li>{{post.coment}}</li>
                <br>
            </div>
        `
            
    })
    let vue = new Vue({
        el: '#app',
        data: {
            items: [
                {id: 1, title: 'Java入门', coment: 'Java语法'},
                {id: 2, title: 'Go入门', coment: 'Go语法'},
                {id: 3, title: 'C++入门', coment: 'C++语法'}
            ]
        }
    })
</script>

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

四、插槽

在使用Html的时候,对于页面的某些数据会是动态出现的,官方的例子:
在这里插入图片描述

查看其它的实例,可以感觉使用插槽是代替了其它省略的内容部分;该内容可以包括:文本,Html或者组件

在对一个数组进行遍历的时候,只是使用v-for遍历然后渲染到html中,会产生一些间隙;其实我还没感受很深对这个插槽

<div id="app" >
    <h1>这是标题</h1>
    <ul v-for="item in items">
         <li>{{item}}</li>
    </ul>
</div>

在这里插入图片描述
使用插槽后:

<div id="app" >
    <todo>
        <todo-title slot="todo-title" :title="title"></todo-title>
        <todo-hobby slot="todo-hobby"
         v-for="item in items"
         :hobby="item"></todo-hobby>
    </todo>
</div>
<script src="../js/vue.js"></script>
<script>
    Vue.component("todo", {
        template: `
            <div>
                <strong>Error!</strong>
                <slot name="todo-title"></slot>
                <ul>
                    <slot name="todo-hobby"></slot>
                </ul>
            </div>
        `
    }),
    Vue.component("todo-title", {
        props: ['title'],
        template: `<h1>{{title}}</h1>`
    }),
    Vue.component("todo-hobby", {
        props: ['hobby'],
        template: `<li>{{hobby}}</li>`
    })
    let vue = new Vue({
        el: "#app",
        data: {
            title: "语言分类",
            items: ['Java', 'Python', 'Go']
        }
    })
</script>

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

在这里插入图片描述

五、自定义事件发布

基础样例

从子组件中传值给父组件

  1. 基础模板
<div id="app">
  <div>这是父组件: {{ msg }}</div>
    <my-com1 v-on:func="show"></my-com1>   // 定义一个自定义的事件
</div>

<template id="com1">
    <div>
        <div>这是子组件</div>
        <button >调用父组件的方法</button>
    </div>
</template>

<script>
    new Vue({
        el: '#app',
        data: {
            msg: ''
        },
        methods: {
            show(data) {   // 父组件中定义显示的方法
                console.log(data)
                this.msg = data;
            }
        },
        components: {
            myCom1: {
                template: '#com1',
                data() {
                    return {
                        name: 'righteye'   // 要将这个数据传回父组件
                    }
                },
                methods: {
                }
            }
        }
    })
</script>

思路:在子组件中触发时间,然后将name利用$emit 调用 子组件中的 func 自定义函数

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

使用插槽

继续上面的例子,现在想对数据进行双向绑定,能够动态的增加删除数据;但是组件实例和模板中的方法是不能相互调用的,因此引入了自定义事件发布,使用this.$emit(‘自定义事件名称’, 参数)

<div id="app" >
    <todo>
        <todo-title slot="todo-title" :title="title"></todo-title>
        <todo-hobby slot="todo-hobby"
         v-for="(item, index) in items"
         :hobby="item" :index="index"
         @remove="removeItems(index)"></todo-hobby>
    </todo>
</div>
<script src="../js/vue.js"></script>
<script>
    Vue.component("todo", {
        template: `
            <div>
                <strong>Error!</strong>
                <slot name="todo-title"></slot>
                <ul>
                    <slot name="todo-hobby"></slot>
                </ul>
            </div>
        `
    }),
    Vue.component("todo-title", {
        props: ['title'],
        template: `<h1>{{title}}</h1>`
    }),
    Vue.component("todo-hobby", {
        props: ['hobby', 'index'],
        template: `
            <li>{{hobby}}  <button @click="remove(index)">删除</button></li>
        `,
        methods: {
            remove(index) {
                this.$emit('remove', index);
            }
        }
    })
    let vue = new Vue({
        el: "#app",
        data: {
            title: "语言分类",
            items: ['Java', 'Python', 'Go']
        },
        methods: {
            removeItems(index) {
                console.log(index)
                this.items.splice(index, 1);
            }
        }
    })
</script>

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

总结

先对组件的使用进行快速入门;查看官网组件部分还有组件间的传值操作,后期进行补充

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值