vue组件化开发
在vue中开发,都是用的组件化的思想开发的,一般在都会在搭建项目的时候,都会先建立组件的模板,把架子搭起来。也就是在组件中定义好
<template>
视图层,<script>
逻辑层,<style>
css样式层。
一般在项目src中创建一个components文件夹存放我们自定义的组件,在需要的页面中导入并注册后,通过标签的形式使用。
1.第一步:在页面中引入子组件,(假设在components文件下有一个myHeader.vue组件)
import myHeader from '@/components/myHeader.vue'
2.第二步:注册子组件
components:{
myHeader
}
3.第三步:作为标签使用
<myHeader />
或者
<myHeader></myHeader>
使用组件的好处
- 组件是可以
复用
性的 - 易于
维护
- 有
封装
性,易于使用 - 大型项目中降低组件之间
重复
性
组件的分类
组件分为:全局组件和局部组件
全局组件
import Loading from '@/components/myLoading.vue'
Vue.component('loading',Loading)
局部组件
<script>
import Loading from '@/components/myLoading.vue'
export default {
data() {
return {}
},
components:{
Loading,
}
}
</script>
组件之间的通讯方式
父传子
父组件:<list :my-list="list"></list>
// props接收过来的数据和data类似 可以直接像data一样使用
# 第一种方法
父组件给子组件绑定一个属性,子组件通过props来接收数据
子组件:
props:["myList"] //利用数组接收
props:{ //利用对象接收
list:Array, //对象接收的简写方式
list:{
type:Array,
default:()=>{
return []
},
required:true //定义该属性是否必须传递
}
}
# 第二种方法
使用provide/inject
provide vue官方建议使用在高阶组件中 provide提供的数组 在它的任意后代组件中都可以使用 inject接收 可以使用数组的方法接收数据
# 第三种方法
使用$parent
子组件中可以通过this.$parent找到父组件 从而找到父组件的所有数据和方法
# 第四种方法
使用vuex
总结:
1.对于第一种方法:
在vue2中: 引用数据类型(数组、对象)的默认值需要通过一个函数返回才能使用,默认值当属性值为undefined或者不传属性才会生效
2.子组件接受父组件的值分为–引用类型和普通类型两种
普通类型:string,number,boolean,null
引用类型:array(数组),object(对象)
子组件不能自行修改
prop
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样是为了防止子组件意外修改父组件的值,从而造成文档数据流混乱。
在组件中修改 prop 传递过来的数据 Vue 会发出警告
,所以有两种常见的用法去修改 prop 传递过来的值
export default {
props:["msg"],
data() {
return {
// 本地data中定义属性,并将 prop 作为初始值(第一种)
message:this.msg
}
},
computed:{
// 使用computed 将prop 的值进行处理(第二种)
message() {
return this.msg + '哈哈哈'
}
}
};
prop验证
props: {
// 基础的类型检查 (null 匹配任何类型)
propA: Number,
// 多个可能的类型
propB: [String, Number],
propC: {
type: String,
required: true, // 必填的字符串
default: 'uu盘' // 默认值
},
// 自定义验证函数
propD: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
子传父
# 第一种方法
父组件给子组件绑定一个自定义事件,子组件通过this.$emit('自定义事件名',参数)发送数据
子组件:
<button @click="add"></button>
<script>
data(){
return {},
methods:{
add(){
// 参数一:父组件定义的方法[事件名称]
// 参数二:可选,子组件向父组件传递的数据,可以是多个
this.$emit("add",this.name)
}
}
}
</script>
父组件:
<list @add="add"></list>
<script>
data(){
return{},
methods:{
add(i){
console.log(i) // 子组件向父组件传递的数据
}
}
}
</script>
# 第二种方法
使用this.$children获取到组件的所有子组件
# 第三种方法
使用vuex
总结:
对于第一种方法:
1.子组件中需要以某种方式例如点击事件的方法来触发一个自定义事件
2.将需要传的值作为$emit的第二个参数,该值将作为实参传给响应自定义事件的方法
3.在父组件上绑定子组件$emit自定义的方法
兄弟之间
# 首先在main.js中给全局挂在一个bus对象
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
Vue.prototype.$bus = new Vue()
new Vue({
router,
render: h => h(App)
}).$mount('#app')
# 在需要传递数据的组件中
<template>
<div @click="sendData">这是组件一</div>
</template>
<script>
export default {
data() {
return {
money: "我又五毛,买不起辣条"
}
},
methods: {
sendData() {
// console.log(this);
this.$bus.$emit('getData', this.money)
}
}
}
</script>
// 在需要接收数据的组件中
<template>
<div>{{msg}}</div>
</template>
<script>
export default {
data() {
return {
msg: ''
}
},
created() {
$on监听方法 他的第一个参数是要监听的函数的函数名 第二个是回调函数
this.$bus.$on('getData', (data) => {
this.msg = data
})
// 关闭监听事件的方法是 this.$bus.$off('事件名')
}
}
</script>
总结:
通过main.js初始化一个全局的$bus,在发送事件的一方通过this.$bus.$emit(“事件名”,传递的参数信息)发送,在接收事件的一方通过this.$bus.$on("事件名",参数)接收传递的事件
组件样式穿透
为了让组件中的样式不影响其他组件的样式,只在当前组件起作用,我们会加上scoped
<style lang='scss' scoped></style>
有时候我们想让某个样式影响子组件,这时候我们就可以使用操作符
css中
<style scoped>
>>> .active {}
</style>
sass中
<style lang='scss' scoped>
/deep/ .active {}
</style>