实现相同的东西造成代码冗余
<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>