IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 【Vue】组件(component) -> 正文阅读

[JavaScript知识库]【Vue】组件(component)

一、什么是组件

所谓的组件,其实就是我们通过vue自定义的一些标签。在自定义的标签中,其实已经封装好了一些自定义的特定的HTML代码。

你也许会疑问,为什么要特意的将HTML代码封装起来。其实是这样的,我们使用组件一方面可以减少HTML的代码(视觉上是这样的),另一方面可以极大的提高代码的复用。

你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。通过组件可以使你的页面更加的结构化,利于维护。


在这里插入图片描述
正如上图所示,通常一个页面会以一棵嵌套的组件树的形式来组织。



二、为什么需要组件

组件是Vue中的一个重要概念,是一个可以重复使用的Vue是可以复用的Vue实例,它拥有独一无二的组件名称,它可以扩展HTML元素,以组件名称的方式作为自定义的HTML标签。

因为组件是可复用的Vue实例,所以它们与new Vue()接收相同的选项,例如data,computed、watch、methods以及生命周期钩子等。仅有的例外是像el这样根实例特有的选项。

在一个绝大多数的系统网页中,网页都包含header、menu、body、footer等部分。像上述的那些东西可能会在多个页面也重复使用,我们可以将其分装成一个一个的组件,那么当需要使用到的时候,引用这个组件即可。


总结下来:

  • 提高开发效率
  • 方便重复使用
  • 简化调试步骤
  • 提升项目的可维护性
  • 便于多人协同开发



三、创建一个组件

我们现在尝试着创建一个简单的组件,如下:

component():创建组件的方法

// 定义名为 todo-item 的新组件
    Vue.component('my-component', {
        template: '<li>我是 寒江coder</li>'
    })

    let app = new Vue({
        el:"#app"
    })

至此,我们就已经创建了一个简单的组件,其名为 my-component。下面的简单的使用该组件。

<ul>
  <!-- 创建一个 todo-item 组件实例 -->
  <my-component></my-component>
</ul>

在这里插入图片描述


注意:
对于组件的使用,我有话要说。因为我们的组件是在通过Vue创建的,若想让组件生效,需要通过el:"#app"绑定一个根标签,将我们定义好的组件在Vue可以识别的根标签中使用。



四、组件的复用

因为上面说过,组件的意义之一就是实现代码的复用,接下来将会介绍一下,如何实现组件的复用。


我们先定义一个按钮组件:

data:这里的和之前的Vue({…})中的data是不同的。在Vue({…})中的data是一个对象(data:{…});而在这里的data必须是一个方法(data:function(){…})

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

new Vue({ el: '#components-demo' })
<div id="components-demo">
  <button-counter></button-counter>
</div>

在这里插入图片描述


你可以将组件进行任意次数的复用:

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

在这里插入图片描述

我们可以发现,被复用的组件之间是独立的(当点击按钮时,每个组件都会各自独立维护它的 count)。因为你每用一次组件,就会有一个它的新实例被创建。



五、通过 Prop 向子组件传递数据

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

比如说,我们定义一个“博文组件”,如下:

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

我们都知道一篇博文必然要有它的标题,那么我们就可以通过props给这个“博文组件”定义一个“标题”属性“title”。

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。


我们可以像这样直接给自定义属性传递信息,如下:

<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>

在这里插入图片描述


但是通常情况下,我们所需要的数据都是从数据库中层批量的获取到的。我们模拟了一下通常情况下数据的渲染情况,如下:
你所需的数据可能会被存放在data中。

new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
         { id: 1, title: 'My journey with Vue' },
         { id: 2, title: 'Blogging with Vue' },
         { id: 3, title: 'Why Vue is so fun' },
         { id: 2, title: 'Blogging with Vue' },
         { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})

那么我们可以在使用自定义组件时使用v-for和v-bind进行数据的获取与绑定,如下:

<blog-post
	v-for="post in posts"
	v-bind:title="post.title"
></blog-post>

在这里插入图片描述
v-bind:title=“post.title”:从通过v-bind成功绑定title属性,我们可以看到通过pops定义的属性它确实变成了组件实例的一个 property。


在一个博文中,我们不可能只有一个标题,肯定还有文章和发布时间,那么我们是否可以仿照上面的内容添加一个“内容”呢?如下的方式是不对的

    Vue.component('blog-post', {
        props: ['title',"content"],
        template:`
                <h2>{{title}}</h2>
                <div v-html='content'></div>
        `
    })
    new Vue({
        el: '#components-demo',
        data: {
            posts: [
                { id: 1, title: 'My journey with Vue',content:"啥的哈达哈打电话IU是洒水" },
                { id: 2, title: 'Blogging with Vue',content:"我回答碎碎念我肯定帅是ASH其实撒"}
            ]
        }

    })
<div id="components-demo">
    <blog-post
        v-for="post in posts"
        v-bind:title="post.title"
        v-bind:content="post.content"
    ></blog-post>
</div>

在这里插入图片描述

造成< div>{{content}}< /div>无法正常显示的原因是每个组件必须只有一个根元素。你可以将模板的内容包裹在一个父元素内,来修复这个问题,如下

    Vue.component('blog-post', {
        props: ['title',"content"],
        template:`
            <div> <!--这个div就是“父元素”-->
                <h2>{{title}}</h2>
                <div v-html='content'></div>
            </div>

        `
    })

在这里插入图片描述


上述的解决方案虽然解决了问题,但是我们的博文不只需要标题和内容,还需要发布日期、评论等等,这样的话其中会使得整个组件的v-bind使用的次数非常的多。为每个相关的信息定义一个 prop 会变得很麻烦

我们可以重构一下posps的内容,因为在Vue中的data中是有一个post属性的,post属性中包含着我们需要的标题和内容甚至是发布日期、评论等等。

我们可以在props中只是设置一个post属性,只绑定一个post属性,在模版(template)中通过post.title、post.content获取需要的内容。如下:

    Vue.component('blog-post', {
        props: ["post"],
        template:`
            <div>
                <h2>{{post.title}}</h2>
                <div v-html='post.content'></div>
            </div>

        `
    })
    new Vue({
        el: '#components-demo',
        data: {
            posts: [
                { id: 1, title: 'My journey with Vue',content:"啥的哈达哈打电话IU是洒水" },
                { id: 2, title: 'Blogging with Vue',content:"我回答碎碎念我肯定帅是ASH其实撒"}
            ]
        }

    })
<div id="components-demo">
    <blog-post
        v-for="post in posts"
        v-bind:post="post"
    ></blog-post>

</div>

在这里插入图片描述


六、通过插槽分发内容

我们都知道,自定义组件其实就是一个标签,在HTML中的标签我们是可以在标签体中传值的,如下:

<div>这是在div的标签体中传入的值</div>

但是在我们自定义的标签体中,传值是没有任何的效果的,是不会显示的。如下:

<div id="components-demo">
    <blog-post>传值是没有任何的效果的</blog-post>
</div>

为了解决上述的问题,Vue 自定义的 < slot> 元素让这变得非常简单,我可以在template中使用 < slot> 用来接收标签体中的内容。

    Vue.component('blog-post', {
        template:`
            <div>
                <slot></slot>
            </div>
        `
    })
    new Vue({
        el: '#components-demo'

    })
<div id="components-demo">
    <blog-post>这次就有效果了</blog-post>
</div>

在这里插入图片描述



七、动态组件

Vue 中我们可以通过 < component> 元素加一个特殊的 is 属性来实现当前使用哪一个组件。

<component v-bind:is="currentTabComponent"></component>

在上述示例中,currentTabComponent 可以包括

  • 已注册组件的名字
  • 一个组件的选项对象

在进行具体的操作之前,我们需要了解几个新的Vue属性

components:用于创建模板使用的,它和Vue.component(组件名,{})的效果是一样的。在其中定义组件的格式是 组件名:{}。components中可以定义多个组件,属于局部组件

computed:是计算属性的;。它会根据所依赖的数据动态显示新的计算结果, 该计算结果会被缓存起来。可以接收方法的返回值,或者运算表达式的结果。


下面我们来进行具体的操作一下

    new Vue({
        el: '#components-demo',
        data:{
            index:0,
            arr:['home','post','archive'],
        },
        components: {
            home:{template:'<div>我是主页</div>'},
            post:{template:'<div>我是提交页</div>'},
            archive:{template:'<div>我是存档页</div>'},
        },
        computed:{
            currentComponent:function(){
                return this.arr[this.index]
            }
        },
        methods:{
            change:function(){
                this.index = (++this.index)%3
            }
        }
    })
<div id="components-demo">
    <button v-on:click="change">切换页面</button>
    <component v-bind:is="currentComponent"></component>
</div>

当点击按钮的时候,会帝爱用change()方法,将index进行加一取模。

is="currentComponent"会调用currentComponent属性,该属性表示当前的组件名,进而实现当前使用哪个组件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述



八、注意事项

有些 HTML 元素,诸如 < ul>< ol>< table>< select>,对于哪些元素可以出现在其内部是有严格限制的。

而有些元素,诸如 < li>< tr>< option>,只能出现在其它某些特定的元素内部。


通过上述的描述,我知道,在< table>中我们自定义的组件时不会被识别的

<div id="components-demo">
    <table>
        <myRow></myRow>
    </table>
</div>
<script>
    new Vue({
        el: '#components-demo',
        components: {
           myRow:{template:'<div>我是主页</div>'},

        }
    })
</script>

上述的< myRow>是不会被识别的。


为此,vue给出了解决方案,我们可以通过 is 属性来声明那些组件在特殊的父标签中有效

<div id="components-demo">
    <table>
        <tr is="myRow"></tr>
    </table>
</div>

< tr is=“myRow”>表示组件myRow作为tr进行渲染

因此就解决了特殊标签中的组件无法被渲染的问题。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-14 10:46:04  更:2021-07-14 10:48:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/15 19:40:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码