Vue 组件化

1. 组件介绍

组件简单来说就是将代码封装,便于后续重复使用,被封装的代码可以包含多种例如 html、css、js。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树
在这里插入图片描述

2. 创建组件

全局注册

流程

  • 通过 new Vue 创建的 Vue 根实例,组件代码需要在根代码前
  • 语句 Vue.component(tagName, options) 注册组件,tagName 为组件名,options 为配置选项
  • 使用语句 <组件名></组件名>
  • 在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中
<div id="app">
    <child></child>
</div>
<script>
    Vue.component('Child', {
        template: `
          <div>
          <p><input type="text" v-model="name">  {{ name }}</p>
          <p><input type="button" @click="func"></p>
          </div>
        `,
        data() {
            return {
                name: '',
            }
        },
        methods: {
            func() {
                console.log('这是全局组件')
            }
        }
    })

    var vm = new Vue({
        el: '#app',
        data: {
            name: 'xwx'
        },
        methods: {},
        computed: {},
    })
</script>

因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 datacomputedwatchmethods 以及生命周期钩子等。除了像 el 这样根实例特有的选项。

还有需要注意的是 data 必须是函数。

局部注册

局部注册可以写在 Vue 实例或者 组件实例中。

<div id="app">
    <child></child>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        components: {
            'Child': {
                template: `<div>这是局部组件</div>`
            }
        }
    })
</script>

Vue.component('navbar', {
    template: `
        <div>
            <p>全局组件</p>
            <child></child>
        </div>
    `,
    components: {
            child: {
                template: `<p>局部组件</p>`,
            }

        }
})

注意点局部注册的子组件只能在已经注册过的父组件中使用,也可以多层嵌套

3. Prop 组件间通信之父传子

组件之间数据默认不互通,如下所示

<div id="app">
    <one></one>
</div>
<script>
    var two = {
        template: `<p>局部组件{{name}}</p>`,
        data() {
            return {
                'name': 'zzz'
            }
        },
    }
    
    Vue.component('one', {
        template: `
          <div>
          <p>全局组件{{name}}</p>
          <two></two>
          </div>
        `,
        data() {
            return {
                'name': 'xwx'
            }
        },
        components: {
            'two': two
        }
    })
    
    var vm = new Vue({
        el: '#app',
    })
</script>

在这里插入图片描述

  • 全局与局部

此时可以将全局看成是父,局部是子

<div id="app">
    <one></one>
</div>
<script>
    var two = {
        props: ['message',],
        template: `<p>局部组件-----{{ message }}</p>`,
    }
    
    Vue.component('one', {
        template: `
          <div>
              <p>全局组件--{{ name }}</p>
              <two :message="name"></two>
          </div>
        `,
        data() {
            return {
                name: 'xwx'
            }
        },

        components: {
            'two': two
        }
    })

    var vm = new Vue({
        el: '#app',
    })
</script>
  • 根实例与全局组件
<div id="app">
    <one :message="name"></one>
</div>
<script>
    Vue.component('one', {
        template: `
          <div>
          <p>全局组件-----{{ message }}</p>
          </div>
        `,
        props: ['message',]
    })

    var vm = new Vue({
        el: '#app',
        data: {
            name: 'xwx'
        }
    })
</script>
  • 流程
  1. 父组件中需要有数据
  2. 调用子组件标签时创建自定义属性,属性的值就是父组件的数据
  3. 父组件的数据需要通过 props 把数据传给子组件,在子组件中需要声明 props
  4. 动态的 props 就是用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件

Prop 属性验证

组件可以为 props 指定验证要求。
可以在子组件中添加定制 prop 的验证方式,将原本的 props: [‘message’,] 修改如下所示

props: {
      'message': Number
  }

若是类型不符合,虽然会报错,但也会显示出来。
在这里插入图片描述

定制的类型如下所示

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

4. 组件间通信之子传父

父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件

我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口,即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件
<div id="app">
    <p>子组件中myfunc的数据是:{{name}}</p>
    <one @myfunc="func"></one>
</div>
<script>
    Vue.component('one', {
        template: `
          <div>
          <button @click="handleClick">点击按钮把子组件数据传递到父组件</button>
          </div>
        `,
        data() {
            return {
                name: 'xwx'
            }
        },
        methods: {
            handleClick() {
                this.$emit('myfunc', this.name)
            }
        }
    })

    var vm = new Vue({
        el: '#app',
        data: {
            name: ''
        },
        methods: {
            func(name) {
                console.log(123)
                this.name = name
            }
        }
    })
</script>

在这里插入图片描述

  • 流程
  1. 子组件创建数据
  2. 创建自定义事件 mufunc,在使用子组件标签时调用父组件函数。
  3. 在子组件内容中调用函数,函数中使用 this.$emit('myfunc', this.name) ,myfunc 就是自定义事件,后面的参数就是需要传给绑定的函数的参数,也就是执行了自定义事件的函数
  4. 在自定义事件函数中将子组件的值赋值即可

5. ref 属性

  • ref 放在普通标签上,拿到的是原生节点,原生 dom 操作
  • ref 放在组件上,拿到的是组件对象
  1. 看以下例子了解简易用法
<div id="app">
    <p ref="p1">xwx</p>
    <button @click="handleClick">点我执行函数</button>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        methods: {
            handleClick() {
                this.$refs['p1'].innerHTML = 'XWenXiang'
            }
        }
    })
</script>
上面的例子中,给一个标签添加 'ref' 属性,然后执行函数,从 'this.$refs' 中获取的就是原生节点,
可以使用原生的 DOM 操作
  1. 实现子传父
    同理放在组件上能获取组件对象,只要操作组件对象即可。
<div id="app">
    <one ref="one1"></one>
    <p>这是子传父的属性{{name}}</p>
    <button @click="handleClick">点我执行函数</button>
</div>
<script>
    Vue.component('one', {
        template: `
          <div></div>
        `,
        data() {
            return {
                name: 'xwx'
            }
        }
    })

    var vm = new Vue({
        el: '#app',
        data: {
            name: ''
        },
        methods: {
            handleClick() {
            	// 同理可以调用子组件的函数
                this.name = this.$refs['one1'].name
            }
        }
    })
</script>
  1. 实现父传子

可以获取子组件的数据,也可以设置子组件的数据

<div id="app">
    <one ref="one1"></one>

    <button @click="handleClick">点我执行函数</button>
</div>
<script>
    Vue.component('one', {
        template: `
          <div><p>这是父传子的属性{{name}}</p></div>
        `,
        data() {
            return {
                name: ''
            }
        }
    })

    var vm = new Vue({
        el: '#app',
        data: {
            name: 'xwx'
        },
        methods: {
            handleClick() {
                this.$refs['one1'].name = this.name
            }
        }
    })
</script>

6. 数据总线

事件总线可以对不同层级的不通组件通信

<div id="app">
    <one></one>
    <two></two>
</div>
<script>
    var bus = new Vue()

    Vue.component('one', {
        template: `
          <div>
          <button @click="handleClick">点我</button>
          </div>
        `,
        data() {
            return {
                name: 'xwx'
            }
        },
        methods: {
            handleClick() {
                bus.$emit('func', this.name)
            }
        }
    })

    Vue.component('two', {
        template: `
          <div>收到的数据是 {{ name }}</div>
        `,
        data() {
            return {
                name: ''
            }
        },
        mounted() {
            bus.$on('func', (name) => {
                this.name = name
            })
        }
    })
    
    var vm = new Vue({
        el: '#app',
    })
</script>

流程

  • 创建数据总线,也就是空的 vue 实例
  • 准备俩个全局组件,在一个组件中绑定点击事件,$emit 触发指定函数并传递参数。在另外一个组件中 $on 监听指定函数

7. 动态组件

当有多个组件时,切换起来较为繁琐,使用动态组件可以减轻冗余
Vue 的 <component> 元素加一个特殊的 is attribute 来实现

<component> 元素,动态地绑定多个组件到它的 is 属性
<keep-alive> 保留状态,避免重新渲染,适合表单标签

<div id="app">
    <button @click="who='one'">第一个组件</button>
    <button @click="who='two'">第二个组件</button>
    <button @click="who='three'">第三个组件</button>

    <component :is="who">
    </component>

</div>
<script>

    Vue.component('one', {
        template: `
          <div style="background: red; width: 265px; height: 200px;"></div>
        `,
    })


    Vue.component('two', {
        template: `
          <div style="background: green; width: 265px; height: 200px;"></div>
        `,
    })

    Vue.component('three', {
        template: `
          <div style="background: blue; width: 265px; height: 200px;"></div>
        `,
    })

    var vm = new Vue({
        el: '#app',
        data: {
            who: 'one'
        }
    })
</script>

在这里插入图片描述
流程

  • Vue 的 <component> 元素加一个特殊的 is attribute 可以判断展示哪一个组件,我们只需要修改 is 的值即可。
  • is 属性进行动态绑定,使其绑定到根实例的 data 中,在 data 中可以设置默认展示的组件,属性的值是组件的名字。
  • 对组件添加点击事件,用于修改 is 绑定的属性值达到切换组件的作用。

8. slot 插槽

在调用组件的适合使用的是 <组件名></组件名> 的形式,标签内部还可以存放内容,这就是插槽

<div id="app">
    <one>你好</one>
</div>
<script>
    Vue.component('one', {
        template: `
          <div>
          <slot></slot>
          </div>
        `,
    })

    var vm = new Vue({
        el: '#app',
        data: {}
    })
</script>

在标签之间存放的值可以用 <slot></slot> 在组件中表示

当存在多个值的时候,可以添加名称,如下所示

<div id="app">
    <one>
        <p slot="p1"></p>
        <p slot="p2"></p>
        <p slot="p3"></p>
    </one>
</div>
<script>
    Vue.component('one', {
        template: `
          <div>
          <slot name="p1"></slot>
          <slot name="p2"></slot>
          <slot name="p3"></slot>
          </div>
        `,
    })

    var vm = new Vue({
        el: '#app',
        data: {}
    })
</script>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue组件开发规范是基于Web Components的思想而来的。在Vue中,组件开发可以帮助我们更好地组织和重用代码。 Vue组件注册有两种方式:全局组件注册和局部组件注册。 全局组件注册语法是通过Vue.component(组件名称, {data:组件数据, template:组件模板内容})来实现的。这样注册的组件可以在整个应用程序中被使用。 局部组件注册可以在一个父组件中注册子组件,只在父组件的作用域内可见。这样可以避免组件之间的命名冲突。 在组件开发中,我们希望尽可能多地重用代码,并且避免组件之间的冲突。因此,编写自定义组件的方式并不容易,需要考虑到HTML、CSS和JS的各个方面。 总结起来,Vue组件开发规范遵循了Web Components的思想,通过全局组件注册和局部组件注册来实现组件的重用和代码的组织。这样可以提高代码的可维护性和可复用性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Vue系列之组件](https://blog.csdn.net/weixin_62277266/article/details/128213687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值