Vue组件化开发--公共组件的封装
目录
为什么要封装组件
应用场景
vue自己封装组件(局部、全局)
Vue组件的三要素
①全局组件
1)方式:
2)示例:
②局部组件
1)方式:
2)示例:
命名规范:(注意)
脚手架vue-cli中的组件
父传子(props)
通过 $on 传递父组件方法
$parent获取父组件然后使用父组件中的数据(不推荐)
通过$emit传递父组件数据 (推荐)
refs获取
组件样式修改 样式穿透
插件使用:slot
为什么要封装组件
用vue开发的项目,都是采用组件化的思想开发的。
一般在搭建项目的时候,会创建一个views目录、一个commen目录和一个feature目录。
- views目录中放页面级的组件
- commen中放公共组件(如:head(公共头组件),foot(公共底部组件)等)
- feature目录内放功能组件(如:swiper(轮播功能组件),tabbar(切换功能组件)、list(上拉加载更多功能组件))
组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性低等问题。
使用组件的好处
- 组件是可以复用性的
- 易于维护
- 有封装性,易于使用
- 大型项目中降低组件之间重复性
应用场景
项目中很多模块经常会复用:侧边导航组件、分页、文件下载、项目中常用的 echarts图表的封装(比如折线图、柱状图等),或者一些后台管理、菜单管理中很多可复用组件,表单之类的。
封装组件需要考虑复用性:
- 预留插槽slot, 多次调用如果 子组件视图结构不一样那么就要在子组件template预留好插槽(单个插槽、具名插槽,作用域插槽)
- 考虑到数据传递,定义props 组件接收父组件传递的数据,同时需要注意单向数据流,props不能直接修改,$emit自定义事件,父组件修改
- 业务逻辑不要在子组件中处理,子组件在不同父组件中调用时,业务处理代码不同,切记不要直接在子组件中处理业务,应该子组件 $emit自定义事件,将数据传递给父组件,父组件处理业务。
vue自己封装组件(局部、全局)
封闭性:当在组件定义好外部不能修改;
开放性:将动态内容和组件通讯方式进行传递数据保证组件可扩展性;
Vue组件的三要素
1. props参数
2. slot定制插槽
3. event自定义事件
①全局组件
1)方式:
可以在main.js中注册成全局组件。
import Bread from '@/layout/bread';// 引入
Vue.component("Bread",Bread);// 全局注册
2)示例:
引用全局组件my-header
注册全局组件my-header
//全局组件:在任何地方,任何方式,任何地点都可以使用的标签组件
vue.component("my-header", {// h1标签是我们在自定义主键里面写的参数的标签template: '标题{{msg}}
',data(){return {msg:100}}})new Vue({el: '#main'});new Vue({el: '#main2'});new Vue({el: '#main3'});
②局部组件
1)方式:
- 新建一个vue文件
- 在需要使用的组件里引入:import UploadIDCard from “./fillInfo/upIDCard”;
- 注册
components: {Position: () => import("@/layout/position"),UploadIDCard
},
注册后,UploadIDCard可以当做一个标签使用。(局部组件)。
2)示例:
局部组件:只是在我们规定的范围之内才会生效。
new Vue({el: '#main',components: {"my-header": {template: '标题{{vue}}
'}}})
命名规范:(注意)
- 当使用 kebab-case(中划线命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如
- 当使用 PascalCase (驼峰式命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。 也就是说
和 都是可接受的。注意,尽管如此,直接在 DOM(即非字符串的模板) 中使用时只有kebab-case 是有效的。 - 总结:中划线命名在使用时必须保持命名一致,而驼峰命名在使用时既可以用驼峰也可以用中划线。
//中划线 使用语法: `
Vue.component('my-component-name', { /* ... */ })
//驼峰 使用语法: `和` `都可以
Vue.component('MyComponentName', { /* ... */ })
脚手架vue-cli中的组件
组件之间的数据传递
我们一般通过脚手架vue-cli开发项目,每个 .vue单文件就是一个组件。在父组件中使用import 导入一个子组件,并在components中注册子组件,子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用$emit方法触发自定义事件传递参数。
父传子(props)
prop 的定义应该尽量详细,至少需要指定其类型
父组件通过属性的形式向子组件传递数据,子组件使用props接收数据,但是通用组件的应用场景比较复杂,对 props 传递的参数应该添加一些验证规则,即:
props: {propA: Number, // 基础类型检测 (`null` 意思是任何类型都可以)propB: [String, Number], // 多种类型propC: { // 必传且是字符串type: String,required: true},propD: { // 数字,有默认值type: Number,default: 100},propE: { // 数组/对象的默认值应当由一个工厂函数返回type: Object,default: function () {return { message: 'hello' }}},propF: { // 自定义验证函数validator: function (value) {return value > 10}}}
由于存在一个单项数据流的问题,父组件传递给子组件的数据不要直接修改,因为会将父组件中的数据也修改,当这个数据也传入其他组件的时候就会出问题了。vue2.5已经针对 props 做出优化,这个问题已经不存在了 如果一定需要有这样的操作,可以这么写:
let copyData = JSON.parse(JSON.stringify(this.data))
为什么不直接写 let myData = this.data 呢? 因为直接赋值,对于对象和数组而言只是浅拷贝,指向的是同一个内存地址,其中一个改变另一个也会改变。而通过 JSON颠倒转换之后,实现了深拷贝,则可以互不影响。
{{ parentMessage }}
通过 $on 传递父组件方法
通过$on传递父组件方法是组件通信中常用的方法传递方式。它可以与通过props传递方法达到相同的效果。相比于props传递function,它更加的直观和显示的表现出了调用关系
子组件
$parent获取父组件然后使用父组件中的数据(不推荐)
准确来说这种方式并不属于数据的传递而是一种主动的查找。父组件并没有主动的传递数据给子组件,而是子组件通过与父组件的关联关系,获取了父组件的数据。
该方法虽然能实现获取父组件中的数据但是不推荐这种方式,因为vue提倡单向数据流,只有父组件交给子组件的数据子组件才有使用的权限,不允许子组件私自获取父组件的数据进行使用。在父与子的关系中子应当是处于一种被动关系
通过$emit传递父组件数据 (推荐)
子组件向父组件中传递数据
子组件向父组件中传递数据:触发父组件方法,并传递参数data到父组件
与父组件到子组件通讯中的
$on配套使用,可以向父组件中触发的方法传递参数供父组件使用
子组件
refs获取
可以通过在子组件添加ref属性,然后可以通过ref属性名称获取到子组件的实例。准确来说这种方式和this.$parent
一样并不属于数据的传递而是一种主动的查找。尽量避免使用这种方式。因为在父子组件通信的过程中。父组件是处于高位是拥有控制权,而子组件在多数情况下应该为纯视图组件,只负责视图的展示和自身视图的逻辑操作。对外交互的权利应该由父组件来控制。所以应当由父组件传递视图数据给子组件,子组件负责展示。而子组件的对外交互通过$emit触发父组件中相应的方法,再由父组件处理相应逻辑。
组件样式修改 样式穿透
sass中语法
有些像sass之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/操作符取而代之——这是一个>>>的别名,同样可以正常工作
插件使用:slot
一个通用组件,往往不能够适应所有应用场景,所以在封装组件的时候只需要完成组件 80% 的功能,剩下的 20% 让父组件通过 solt 解决。solt 起到一个占位的作用,给按钮的设置提前预留一个位置,然后在父组件中写入按钮即可。
在开发通用组件的时候,只要不是独立性很强的组件最好是都加一个slot。并且,开发过程中,常常需要在子组件内添加新的内容,这时候可以在子组件内部留一个或者多个插口,然后在调用这个子组件的时候加入内容,添加的内容就会分发到对应的 slot 中:
父组件
不具名插槽
这里对应的是s1插口
这里对应的是s2插口
子组件
这是一个头部组件
slot 中还可以作为一个作用域,在子组件中定义变量,然后在父组件中自定义渲染的方式:(项目中使用的比较多,vue+elementUI中ajax获取数据显示在表格中,很多时候每一条数据不是直接显示的,需要做一些额外的处理)
子组件
这是一个头部组件
父组件
{{ props.text }}
参考链接:vue组件化开发_star@星空的博客-CSDN博客
Vue公共组件的封装_Milly_Liu的博客-CSDN博客_vue公共组件的封装
vue组件化开发_star@星空的博客-CSDN博客
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
