0
点赞
收藏
分享

微信扫一扫

vue封装自定义组件

慕容冲_a4b8 2022-02-11 阅读 63
  1. 你封装过组件吗??
  2. 说一下组件封装????
  3. 你在项目中是如何封装组件的?????
以上问题是面试官,最常问到的问题?那么你应该如何回答呢?

答: 我用vue开发的所有项目,都是采用组件化的思想开发的。一般我在搭建项目的时候,会创建一个views目录和一个commen目录和一个feature目录,views目录中放页面级的组件,commen中放公共组件(如:head(公共头组件),foot(公共底部组件)等),feature目录内放功能组件(如:swiper(轮播功能组件),tabbar(切换功能组件)、list(上拉加载更多功能组件))

首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性低等问题。

使用组件的好处

  • 组件是可以复用性的
  • 易于维护
  • 封装性,易于使用
  • 大型项目中降低组件之间重复

全局组件

引用全局组件my-header

<body>
<div id="main1">
<!-- 正常模板解析的时候,不会将自定义标签解读出来,而是将自己定义组件里的参数解读出来,也就是下面template中的h1标签 -->
<my-header></my-header>
</div>
<div id="main2">
<!-- 自定义组件具有复用性 -->
<my-header></my-header>
</div>
<div id="main3">
<my-header></my-header>
</div>
</body> 

注册全局组件my-header

//全局组件:在任何地方,任何方式,任何地点都可以使用的标签组件
vue.component("my-header", {
// h1标签是我们在自定义主键里面写的参数的标签
template: '<h1>标题{{msg}}</h1>',
data(){
   return {msg:100}
}
})
new Vue({
el: '#main'
});
new Vue({
el: '#main2'
});
new Vue({
el: '#main3'
});

局部组件

局部组件:只是在我们规定的范围之内才会生效。

 <body>
<div id="main">
<my-header></my-header>
<my-header></my-header>
</div>
</body>
new Vue({
el: '#main',
components: {
  "my-header": {
  template: '<h1>标题{{vue}}</h1>'
  }
}
})

注意:

//中划线 使用语法: <my-component-name>`
Vue.component('my-component-name', { /* ... */ })
//驼峰  使用语法:<my-component-name> `和` <MyComponentName>`都可以
Vue.component('MyComponentName', { /* ... */ })

脚手架vue-cli中的组件

我们一般通过脚手架vue-cli开发项目,每个 .vue单文件就是一个组件。在父组件中使用import 导入一个子组件,并在components中注册子组件,子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用$emit方法触发自定义事件传递参数。
父传子(props)
prop 的定义应该尽量详细,至少需要指定其类型

<!-- 父组件 -->
<template>
<div>
  <my-child :parentMessage="parentMessage"></my-child>
</div>
</template>

<script>
import MyChild from '@components/common/MyChild'

export default {
  components: {
      MyChild
  },
  data() {
      return {
          parentMessage: "我是来自父组件的消息"
      }
  }
}
</script>
<!-- 子组件 -->
<template>
<div>
  <span>{{ parentMessage }}</span>
</div>
</template>

<script>
export default {
  props: {
      parentMessage: {
          type: String,
          default: '默认显示的信息'
          // require: true // 必填
      }
  }
}
</script>

通过 $on 传递父组件方法

<!-- 父组件 -->
<template>
<div>
  <my-child @childEvent="parentMethod"></my-child>
</div>
</template>

<script>
import MyChild from '@components/common/MyChild'

export default {
  components: {
      MyChild,
  },
  data() {
      return {
          parentMessage: '我是来自父组件的消息',
      }
  },
  methods: {
      parentMethod() {
          alert(this.parentMessage)
      }
  }
}
</script>
<!-- 子组件 -->
<template>
<div>
  <h3>子组件</h3>
</div>
</template>

<script>
export default{
  mounted() {
      this.$emit('childEvent')
  }
}
</script>

$parent获取父组件然后使用父组件中的数据(不推荐)

// 此处的this为子组件实例
this.$parent

通过$emit传递父组件数据 (推荐)
与父组件到子组件通讯中的$on配套使用,可以向父组件中触发的方法传递参数供父组件使用

<!-- 父组件 -->
<template>
<div>
  <my-child @childEvent="parentMethod"></my-child>
</div>
</template>

<script>
import MyChild from '@components/common/MyChild'

export default {
  components: {
      MyChild
  },
  data() {
      return {
          parentMessage: '我是来自父组件的消息'
      }
  },
  methods: {
      parentMethod({ name, age }) {
          console.log(this.parentMessage, name, age)
      }
  }
}
</script>
<!-- 子组件 -->
<template>
<div>
  <h3>子组件</h3>
</div>
</template>

<script>
export default {
  mounted() {
      this.$emit('childEvent', { name: 'zhangsan', age:  10 })
  }
}
</script>

refs获取

<!-- 父组件 -->
<template>
<div>
  <my-child ref="child"></my-child>
</div>
</template>

<script>
import MyChild from '@components/common/MyChild'

export default {
  components: {
      MyChild
  },
  mounted() {
      console.log(this.$refs['child'].getData());
  }
}
</script>
<!-- 子组件 -->
<script>
export default {
  methods: {
      getData() {
          // do something...
      }
  }
}
</script>

组件样式修改 样式穿透

css父组件修改子组件中的样式
如果你希望scoped样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符:

<style scoped>
.a >>> .b { /* ... */ }
</style>

上述代码将会编译成:

.a[data-v-f3f3eg9] .b { /* ... */ }

sass中语法
有些像sass之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/操作符取而代之——这是一个>>>的别名,同样可以正常工作

<style scoped>
.a /deep/ .b { /* ... */ }
</style>
举报

相关推荐

0 条评论