专栏首页vuevue.js之组件篇

vue.js之组件篇

Vue.js 组件

  • 模块化:是从代码逻辑的角度进行划分的;
  • 组件化:是从UI界面的角度进行划分的。

组件(Component)是 Vue.js 最强大的功能之一,组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树,如下图所示:

使用Vue.extend来创建全局vue组件:

var com1 = Vue.extend({
template: '<h3>这是使用 Vue.extend 创建的组件</h3>' // 通过template属性,指定了组件要展示的HTML结构
})

此时只是声明了一个叫com1的组件,如果要在vue实例中使用组件,还需要通过以下方式来注册组件:

   Vue.component('myCom1', com1)

组件的调用: 

  <div id="app">
    <!-- 如果要使用组件,直接把组件的名称以HTML标签的形式,引入到页面中即可 -->
    <my-com1></my-com1>
  </div>

 注意事项:

  1. 如果使用 Vue.component 注册组件的时候,组件名称使用了驼峰命名,则在引用组件的时候,需要把大写的驼峰改为小写的字母,同时,两个单词之间使用 “-” 连接
  2. 如果不使用驼峰,则直接拿名称来使用即可;

其它两种创建组件的方式:

    Vue.component('myCom1', Vue.extend({
      template: '<h3>这是使用Vue.extend创建的组件</h3>'
    }))
    Vue.component('mycom2', {
      template: '<div><h3>这是直接使用Vue.component创建出来的组件</h3><span>123</span></div>'
    })

注意:不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素

在被控制的#app外面,使用template元素,定义组件的HTML模板结构:

  <template id="tmpl">
    <div>
      <h1>这是通过 template 元素,在外部定义的组件结构,这个方式,有代码的智能提示和语法高亮</h1>
    </div>
  </template>
   Vue.component('mycom3', {
      template: '#tmpl' //引用template的id属性
    })

 私有组件:

  <template id="tmpl2">
    <h1>这是私有的 login 组件</h1>
  </template>
    var vm2 = new Vue({
      el: '#app2',
      components: { // 定义实例内部私有组件的
        login: {
          template: '#tmpl2'
        }
      },
    })

组件中的data和methods:

  1. 组件可以有自己的data数据;
  2. 组件的data和实例的data有点不一样,实例中的data可以为一个对象,但是组件中的data必须是一个方法;
  3. 组件中的data除了必须为一个方法之外,这个方法内部还必须返回一个对象;
  4. 组件中的data数据,使用方式和实例中的data使用方式完全一样
    Vue.component('mycom1', {
      template: '<h1>这是全局组件 --- {{msg}}</h1>',
      data: function () {
        return {
          msg: '这是组件的中data定义的数据'
        }
      }
    })

 为什么组件中的data必须要是一个方法,演示如下:

Html代码:

  <div id="app">
    <counter></counter>
    <hr>
    <counter></counter>
    <hr>
    <counter></counter>
  </div>
  <template id="tmpl">
    <div>
      <input type="button" value="+1" @click="increment">
      <h3>{{count}}</h3>
    </div>
  </template>

javascript代码:

    var dataObj = { count: 0 }
    //这是一个计数器的组件, 身上有个按钮,每当点击按钮,让data中的count值+1
    Vue.component('counter', {
      template: '#tmpl',
      data: function () {
        // return dataObj
        return { count: 0 }
      },
      methods: {
        increment() {
          this.count++
        }
      }
    })
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {}
    });

调用测试结果如下 :

每个计数器的count是独立的,如将将返回的值改为:

        return dataObj
        //return { count: 0 }

结果为:

每个组件的count是共享的,组件的data必须是一个方法,且必须返回一个对象。要解决的问题就是提高组件的复用性,防止组件与组件之间成员干扰。

组件的切换:

<body>
  <div id="app">
    <a href="" @click.prevent="flag=true">登录</a>
    <a href="" @click.prevent="flag=false">注册</a>
    <login v-if="flag"></login>
    <register v-else="flag"></register>
  </div>
  <script>
    Vue.component('login', {
      template: '<h3>登录组件</h3>'
    })
    Vue.component('register', {
      template: '<h3>注册组件</h3>'
    })
    var vm = new Vue({
      el: '#app',
      data: {
        flag: true
      },
      methods: {}
    });
  </script>
</body>

演示结果如下,默认显示登录组件,点击注册切换到注册组件,点击登录切换的登录组件。

缺点分析:如果在一个需求中需要切换更多的组件,这种方式不利于扩展。

    <!-- Vue提供了component ,来展示对应名称的组件 -->

    <!-- component 是一个占位符, “:is”是属性,可以用来指定要展示的组件的名称 -->

  <div id="app">
    <a href="" @click.prevent="comName='login'">登录</a>
    <a href="" @click.prevent="comName='register'">注册</a>
    <component :is="comName"></component>
  </div>
  <script>
    // 组件名称是字符串
    Vue.component('login', {
      template: '<h3>登录组件</h3>'
    })
    Vue.component('register', {
      template: '<h3>注册组件</h3>'
    })
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        comName: 'login' //当前component中的 :is 绑定的组件的名称
      },
    });
  </script>

组件切换动画:

html代码:

  <div id="app">
    <a href="" @click.prevent="comName='login'">登录</a>
    <a href="" @click.prevent="comName='register'">注册</a>

    <!-- 通过 mode 属性,设置组件切换时候的模式为先出后进-->
    <transition mode="out-in">
      <component :is="comName"></component>
    </transition>

  </div>

  <script>
    // 组件名称是 字符串
    Vue.component('login', {
      template: '<h3>登录组件</h3>'
    })

    Vue.component('register', {
      template: '<h3>注册组件</h3>'
    })
    var vm = new Vue({
      el: '#app',
      data: {
        comName: 'login' // 当前 component 中的 :is 绑定的组件的名称
      },
    });
  </script>

css代码:

  <style>
    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateX(150px);
    }

    .v-enter-active,
    .v-leave-active {
      transition: all 0.5s ease;
    }
  </style>

子组件引用父组件的值:

 1     <div id="app">
 2         <com1></com1>
 3     </div>
 4     <script>
 5 
 6             Vue.component
 7             var vm = new Vue({
 8                 el:'#app',
 9                 data:{
10                     msg:"heelo !"
11                 },
12                 methods:{
13                 },
14                 components:{
15                     com1:{
16                         template:'<h1>这是子组件---{{msg}}</h1>'
17                     }
18                 }
19             })
20         </script>

执行结果:

默认情况下子组件是不能引用父组件的属性和对象的,我们可以在引用子组件的时候,通过属性绑定的形式(v-bind)的形式,把需要传递给子组件的数据,以属性绑定的形式传递到子组件内部,供子组件使用,并且在props中声明该属性(props中的数据都是通过父组传递过来的,这里的数据是只读的),代码如下:

 1     <div id="app">
 2         <com1 v-bind:parentmsg="msg"></com1>
 3     </div>
 4     <script>
 5         Vue.component
 6         var vm = new Vue({
 7             el: '#app',
 8             data: {
 9                 msg: "heelo !"
10             },
11             methods: {
12             },
13             components: {
14                 data() {
15                     return {
16                         title: '123',
17                         content: 'pppp'
18                     }
19                 },
20                 com1: {
21                     props: ['parentmsg'],
22                     template: '<h1>这是子组件---{{parentmsg}}</h1>'
23                 }
24             }
25         })
26     </script>

子组件调用父组件的方法:

请详细看下面代码中的注释

 1  <div id="app">
 2      
 3     <com2 @func="show"></com2>
 4     </div>
 5     <template id="tmpl">
 6         <div>
 7             <h1>这是子组件</h1>
 8             <input type="button" value="这是子组件中的点击按钮" @click="myclick">
 9         </div>
10     </template>
11     <script>
12         //定义了一个字面量类型的组件模板对象
13         var com2 = {
14             template: '#tmpl',
15             data() {
16                 return {
17                     sonmsg: { name: 'wjl', age: 16 }
18                 }
19             },
20             methods: {
21                 myclick() {
22                     //当点击子组件的按钮时,通过$emit拿到父组件传递过来的func
23                     //emit的英文愿意为触发、调用、发射的意思
24                     this.$emit('func', this.sonmsg, 123, 456)
25                 }
26             }
27         }
28         var vm = new Vue({
29             el: '#app',
30             data: {
31                 datamsg: null
32             },
33             methods: {
34                 show(data, data1, data2) {
35                     console.log('调用了父组件的show方法:' + data.name + data1 + data2);
36                 }
37             },
38             components: {
39                 com2
40             }
41         })
42     </script>

执行结果:

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2lv2gsiubr6sw

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • sql联合查询

    指尖改变世界
  • 将java项目打包成jar文件并在cmd运行

    指尖改变世界
  • 递归一个List<T>,可自己根据需要改造为通用型。

    指尖改变世界
  • 2020年的12个Vue.js开发技巧和窍门

    随着Vue 2.6的推出,已经引入了插槽的简写方式,可用于事件(例如,@click 表示 v-on:click 事件)或冒号表示方式用于绑定(:src)。例如,...

    Dunizb
  • Vue 05.组件

    组件: 组件是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可; 组件化和模块...

    LittlePanger
  • Vue组件间通信6种方式

    组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。一般来说,组件可以有以下几种关系:

    Fundebug
  • 驳《前端常见的Vue面试题目汇总》

    本文针对 @小明同学哟 的 《前端常见的Vue面试题目汇总》 这篇文章,提出一些错误。

    ssh1995
  • 微信小程序自定义组件(Toast)

    微信官方的wx.showToast这个API用起来限制性太强,在正式项目上根本用不上,但是又没有其他组件或API可以替代,所以就自己通过网上大神的方法自己写了一...

    honey缘木鱼
  • 美团外卖前端可视化界面组装平台 —— 乐高

    1 简介 乐高,是美团点评一个快速搭建后台系统页面的平台。名称来源于大家熟悉的丹麦知名玩具品牌,他们的玩具都是通过组合易拆卸、装配的零件,形成最终的作品。经过长...

    美团技术团队
  • vue开发工具有哪些,那个更合适?

    现在前端除了JavaScript外,还有react,vue,angular这三个框架在市场上用的比较多,可以说这三个框架很大程度上改变了前端的地位,相对于ang...

    北京锐智互动

扫码关注云+社区

领取腾讯云代金券