实现相同的东西造成代码冗余
<template><div id="app"><h1>组件基础---为什么要使用组件</h1><!-- 使用场景---很多地方都要用到这个组件 --><div><div>一级菜单---<span @click="changeMenu(1)">{{flag?'收起':"展开"}}</span></div><div v-if="flag1"><div>二级菜单</div></div></div><div><div>一级菜单---<span @click="changeMenu(2)">{{flag?'收起':"展开"}}</span></div><div v-if="flag2"><div>二级菜单</div></div></div><div><div>一级菜单---<span @click="changeMenu(3)">{{flag?'收起':"展开"}}</span></div><div v-if="flag3"><div>二级菜单</div></div></div></div>
</template><script>
// 一个.vue文件就是一个组件,组件的选项
// 你可以在一个组件的选项中定义本地的过滤器:局部过滤器
// vue2选项式API--代码应该写在什么地方给你规定好了
export default {name: 'App',data(){return {flag1:true,flag2:true,flag3:true}},methods:{changeMenu(type){let that =this;if(type==1){that.flag1 = !that.flag1}else if(type==2){that.flag2 = !that.flag2}else{that.flag3 = !that.flag3}}}}
</script><style></style>
组件的基本使用
基础使用
每个组件都是一个独立的个体, 代码里体现为一个独立的.vue文件
哪部分标签复用, 就把哪部分封装到组件内
组件内template只能有一个根标签
组件内data必须是一个函数, 独立作用域
命名方式驼峰式命名(大驼峰推荐)-2个单词
步骤:
-
创建组件/引入组件 components/XxxXxxx.vue
-
注册组件: 创建后需要注册
-
使用组件
全局 - 注册使用
全局入口在main.js, 在new Vue之上注册
局部 - 注册使用
任意vue文件中引入, 注册, 使用,在components里创建组件/引入组件 components/XxxXxxx.vue
main.js
import Vue from 'vue'
import App from './App.vue'
// 第一步引入你的公共组件
// 全局注册组件 在其他.vue文件可以直接使用
// 定义组件名的方式有两种:// 使用 kebab-case
// Vue.component('my-component-name', { /* ... */ })
// 使用 PascalCase
// Vue.component('MyComponentName', { /* ... */ })
import MenuPage from './components/MenuPage.vue'
Vue.component('MenuPage',MenuPage)
Vue.config.productionTip = false
// 全局过滤去
Vue.filter('stan', function (value,money) {if (!value) return ''value = value.toString()return value.charAt(0).toUpperCase() + value.slice(1)+money
})
new Vue({render: h => h(App),
}).$mount('#app')
App.vue
<template><div id="app"><h1>组件基础---为什么要使用组件</h1><!-- 使用场景---很多地方都要用到这个组件 --><!-- 公共的组件当成标签来使用 --><MenuPage></MenuPage><MenuPage></MenuPage><MenuPage></MenuPage><MenuPage></MenuPage><MenuPageOne></MenuPageOne></div>
</template><script>import MenuPageOne from './components/MenuPage.vue'
export default {name: 'App',data(){return {}},methods:{},components:{MenuPageOne}}
</script><style></style>
MenuPage.vue
MenuPage.vue写在components里面
<template><div><div><div>一级菜单---<span @click="changeMenu(1)">{{flag1?'收起':"展开"}}</span></div><div v-if="flag1"><div>二级菜单</div></div></div></div>
</template>
<script>
export default{// 因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,// 例如 data、computed、watch、methods 以及生命周期钩子等// 每一个.vue文件就是一个组件(一个页面)name:'MenuPage',data(){return{flag1:true,}},methods:{changeMenu(type){let that =this;that.flag1 = !that.flag1}}
}
</script>
父组件向子组件传值
组件发送的形式是以属性的形式绑定值到子组件身上。
然后子组件用属性props接收
<template><div id="app"><h1>组件基础---组件之间的传值</h1><!-- 父传子在子组件上自定义属性进行值的传递 --><!-- 动态绑定属性 v-bind : --><SonOne msg="hello world" :arr="arr1"></SonOne></div>
</template><script>
// 组件之间的关系
// 父传子
// app.vue是父亲
// sonone.vue是儿子
// 谁被引入谁就是儿子
// 一个.vue文件就是一个组件,组件的选项import SonOne from '@/components/SonOne.vue'
export default {name: 'App',data(){return {arr1:['小米','小火']}},methods:{},components:{SonOne}}
</script><style></style>
SonOne.vue
<template><div><h1>我是sonOne</h1><div>{{title}}--{{ msg }}</div><div v-for="(item,index) in arr" :key="index">{{item }}</div></div>
</template>
<script>
export default{name:"SonOne",// props: ['title','msg',"arr"],props:{title:{type:String,default:'我是默认值' //设置默认值},msg:{type:String,required:true //设置必传},arr:Array},data(){return{}},methods:{}
}
</script>
<style>
</style>
子组件向父组件传值
子组件用$emit()
触发事件
$emit()
第一个参数为 自定义的事件名称 第二个参数为需要传递的数据
父组件用v-on:注册子组件的事件
<template><div id="app"><h1>组件基础---组件之间的传值</h1><div>{{ msg }}</div><button @click="gainMsg">获取msg数据</button><div>{{ testFun() }}</div><!-- 父传子在子组件上自定义属性进行值的传递 --><!-- 动态绑定属性 v-bind : --><SonTwo @giveFahterMoney="acceptMoney"></SonTwo></div>
</template><script>import SonTwo from './components/SonTwo.vue';
export default {name: 'App',data(){return {arr1:['小明','小米'],msg:"hellow world"}},methods:{gainMsg(){console.log(this.msg)console.log(this)let rel = this.testFun()console.log(rel)},testFun(){return '嘟嘟'},acceptMoney(money){console.log(money)}},components:{SonTwo}}
</script><style></style>
SonTwo.vue
<template><div><h3>这是儿子二</h3><button @click="giveFather">父亲给儿子钱</button></div>
</template>
<script>
export default{name:"SonTwo",data(){return{}},methods:{giveFather(){this.$emit('giveFahterMoney','100')}}
}
</script>
兄弟之间的传值
初始化一个全局的事件中心hub,在发送事件的一方通过hub.$emit(“事件名”,传递的参数信息)发送,在接收事件的一方通过hub.$on("事件名",参数)接收传递的事件
<template><div id="app"><h1>组件基础---组件之间的传值</h1><SonThree></SonThree><SonFour></SonFour></div>
</template><script>import SonThree from '@/components/SonThree'
import SonFour from '@/components/SonFour'
export default {name: 'App',data(){return {}},methods:{},components:{SonThree,SonFour}}
</script><style></style>
SonThree.vue
<template><div><h1>这是儿子三</h1><button @click='giveBrother'>儿子三要给儿子四money</button></div>
</template>
<script>
import hub from '@/utils/index.js'
console.log('hub',hub)
export default {name:"SonThree",methods:{giveBrother(){hub.$emit('giveMoney',100)}}
}
</script>
SonFour.vue
<template><div><h1>这是儿子四</h1></div>
</template>
<script>
import hub from '@/utils/index.js'
export default {name:"SonFour",mounted(){console.log('hub-four',hub)hub.$on('giveMoney',(data)=>{console.log('data',data)})}
}
</script>