全面解析Vue组件化开发

186 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

组件基本使用

  • 1.组件的本质就是一个自定义的html标签

    • 默认的标签:只有html结构
    • 组件 :html结构 + js业务 + css样式
  • 2.一个组件相当于一个vue实例

    • 组件的作用 : 盒子复用
  • 3.在vue项目开发中,组件与页面的关系如下

    • 页面 = 盒子 = 组件 = .vue文件 = html+css+js

组件三个组成部分

一个组件(.vue文件)由三个标签组成

  1. <template>标签,这里写组件的html结构

注意点: 一个template只能有一个子元素,vue会自动把<template>里面的根元素作为当前组件(vue实例)的挂载点

  1. <script>标签,这里写组件的js代码

注意点: 以前vue实例的代码写在 export default { } 里面。 它的本质是一个ES6模块化语法,作用就是让组件可以实现复用(导入导出到其他组件)

注意点 : 组件里面的data必须是一个函数, 这个函数返回值就是之前vue实例的data对象

原因: cn.vuejs.org/v2/guide/co…

  1. <style>标签,这里写组件的css代码
<!-- 1.html标签: 放模板(html结构)
细节:组件中的最外层父元素只能有一个,不能添加两个平级父元素
        正确:  <div> <div></div> <div>
        错误:   <div></div> <div></div>
 -->
<template>
    <div>
        <h1>Hello!</h1>
        <div class="box">{{ msg }}</div>
        <button @click="doClick">点我试试</button>
        <local01></local01>
    </div>
</template>

<!-- 2.js代码,写组件js业务逻 -->
<script>

export default {
    //之前vue实例的代码写在这里:可以放data,methods,计算属性、侦听器等
    //注意哟:组件里面的data是一个函数,返回值就是之前vue实例中的data对象
    data(){
        return{
            msg:'我是dj'
        }
    },
    methods: {
        doClick(){
            alert('我被点击了')
        }
    }
}
</script>

<!-- 3.css:写组件样式 -->
<style>
.box{
    width: 100px;
    height: 100px;
    background-color: red;
}
</style>

注册局部组件

官方文档:cn.vuejs.org/v2/guide/co…

注册局部组件

1.导入局部组件 : 在scrip标签中导入

import 组件名 from '组件路径'

2.挂载组件 : 在export default里面写一个属性components

export default {

components: {

"标签名": 组件名

}

}

使用局部组件 : 像标签一样使用即可,组件可以理解为一个自定义标签

<组件名></组件名>

注册全局组件

官方文档:cn.vuejs.org/v2/guide/co…

注册全局组件 : 在main.js文件中

1.导入组件 import 组件名 from '组件文件路径'

2.注册全局组件 Vue.component('标签名', 组件名)

一旦注册全局组件之后,可以在任何组件直接使用,并且不需要导入和挂载

局部组件和全局组件区别:

  • 局部组件 : 在哪里用就在哪里注册 (用一次,注册一次)

    • 如果一个组件只在一两个页面用到,就可以局部注册(例如商品详情)
  • 全局组件 : 在main.js中注册,任何地方都能直接使用 (注册一次,终生可用)

    • 如果一个组件需要在很多个页面用到,就可以全局注册(例如,弹框、自定义按钮这些)
//1.导入vue框架
import Vue from 'vue'
//2.导入App.vue根组件
import App from './App.vue'
//3.控制台打印提示开关
Vue.config.productionTip = false


/* 注册全局组件 : 在main.js文件中 
1.导入组件
  import 组件名 from '组件文件路径'
2.注册全局组件
  Vue.component('标签名', 组件名)
一旦注册全局组件之后,可以在任何组件直接使用,并且不需要导入和挂载
*/
//1.导入组件
import global from './components/global.vue'
//2.注册全局组件
//参数1 : 组件的id  (id叫什么,自定义标签名就叫什么)
//参数2 :  组件
Vue.component('test', global)


//4.创建vue实例
new Vue({
  //默认渲染App.vue组件(根组件)
  render: h => h(App),
}).$mount('#app')//设置挂载点,相当于 el:'#app'

组件CSS作用域scoped属性介绍

<style scoped>
/* 
1.默认情况下,如果父组件与子组件有相同的css选择器样式,则父组件的样式会覆盖子组件的样式
2.scoped属性作用 : 如果子组件与父组件有相同样式,则优先加载子组件自身的。如果没有则加载父组件的
 */
/* css */
.box{
    width: 100px;
    height: 100px;
    background-color: blue;

}
</style>

组件的name属性介绍

官方文档:cn.vuejs.org/v2/api/#nam…

name属性的作用是给这个组件一个标识符,用于快速查找组件

  • 关于name属性更多的作用,将会在后面项目课程有更多的了解

    • name属性的作用是给这个组件一个标识符,用于快速查找组件

      • 关于name属性更多的作用,将会在后面项目课程有更多的了解

name属性特点

-   a. 必须是唯一,不能与其他组件name属性冲突

    -   建议最好与组件名一致

-   b.name属性值不能是中文



vue组件传值

准备工作(新建两个组件, 一个父组件,一个子组件)

  • App.vue (父组件)
  • goods.vue (子组件)

父组件传值子组件:props

官网文档:cn.vuejs.org/v2/guide/co…

使用步骤

第一步:给子组件添加props属性(与data平级)

作用:类似于声明变量,定义要接收的属性名

第二组:在父组件中使用行内自定义 attribute传值 <子组件 属性名="属性值"></子组件>

注意点: prop中的属性不能有大写字母,不要使用驼峰命名。建议使用-作为分隔符。

原因:行内自定义属性attribute不支持大写

单向数据流

  • 官方文档:cn.vuejs.org/v2/guide/co…

  • 1.单向数据流: vue规定,父组件传递给子组件的数据是只读的.

    • 简单说就是:当数据是从父组件的属性中传递过来的时候,子组件不要直接去修改。
  • 2.单向数据流原因: 子组件修改了父组件传递过来的数据,不会通知父组件。就会造成数据不统一问题

  • 3.细节:引用类型赋值本质是赋值地址,一但修改互相影响,非常不便于维护

子组件:给按钮绑定一个事件,去修改价格。发现vue会报错。并且就算修改了子组件的数据,父组件的数据还是不变,就会造成数据不统一的问题

子组件传递数据给父组件:$emit

子组件不能直接修改父组件中的数据,但是可以通过emit来通知父组件修改

1.监听子组件事件:cn.vuejs.org/v2/guide/co…

2.$emit用法:cn.vuejs.org/v2/api/#vm-…

3.使用事件抛出一个值:cn.vuejs.org/v2/guide/co…

使用步骤

  • 1.子组件中发出通知: this.$emit('事件名',参数)

  • 2.父组件中接收通知: <子组件 @事件名="函数名"></子组件>

    • 父组件中的事件名要与子组件$emit中的事件名一致
  • 3.在父组件的methods中实现这个事件处理函数

    • 一定要搞清楚事件名事件处理函数区别。别蒙圈了,多屡屡。
  • 本质:自定义事件

父子组件传值总结

  • 父传子: 使用props

    • 单向数据流
  • 子传父: 使用$emit

    • 事件监听

wallhaven-725qz3.jpg