父子通信,动态组件,异步加载组件

2.组件基础

2-1父传子props

父传子:水往低处流(单向绑定的原则),子不能修改父传过来的属性,它是只读的,但是可以使用监听和计算属性进行修改

父组件

<template>
    <div>
      
        <navbar mytitle="电影" isShow="false"></navbar>
        <navbar mytitle="影院"></navbar>
       //动态绑定状态
        <navbar :mytitle="parentTitle"></navbar>

     
    </div>
</template>
<script>
import Navbar from './Navbar.vue'
export default {
    data() {
        return {
            //状态
            parentTitle: "父组件定义的一个状态",
        
          
        }
    },
    components: {
        Navbar
        
    }
}
</script>

子组件

<template>
    <div>
        //显示内容
        <p>{{ mytitle }}</p>
        <button @click="handler()" v-if="isShow">按钮</button>
    </div>
</template>
<script>
export default {
    // props: ["mytitle","left","right"],
    //通过props接受父组件传过来的内容
    props:{
        mytitle: String,
        
        isShow:{
            type:Boolean,
            default:true,
            // required:true
        }
    },
        methods: {
            handler() {
                 // 无法直接访问状态和修改状态
                	console.log(this.parentTitle)
            }
        },
    }
</script>
2-2属性验证&默认属性
export default {
  props: {
    // 基础类型检查
    //(给出 `null` 和 `undefined` 值则会跳过任何类型检查)
    propA: Number,
    // 多种可能的类型
    propB: [String, Number],
    // 必传,且为 String 类型
    propC: {
      type: String,
      required: true
    },
    // Number 类型的默认值
    propD: {
      type: Number,
      default: 100
    },
    // 对象类型的默认值
    propE: {
      type: Object,
      // 对象或者数组应当用工厂函数返回。
      // 工厂函数会收到组件所接收的原始 props
      // 作为参数
      default(rawProps) {
        return { message: 'hello' }
      }
    },
    // 自定义类型校验函数
    propF: {
      validator(value) {
        // The value must match one of these strings
        return ['success', 'warning', 'danger'].includes(value)
      }
    }
  }
}
2-3子传父:$emit

如果 在vue中要用sass,需要安装这个模块,npm i sass

在子页面通过$emit进行传值,在父页面通过event事件进行获取值

子组件

<template>
    <div>
        //,在父页面通过event事件进行获取值,
        //不要写小括号,会有一个event事件
       <Child @event="handleEvent"></Child> 
      
    </div>
</template>
<script>
 import Child from './Child.vue'


export default {
    data() {
        return {
            isShow: true
        }
    },
    components: {
        Child
       
    },
    methods: {
        //,在父页面通过event事件进行获取值
         handleEvent(event) {
           console.log("父组件",event);
        }
       
    },
}
  
</script>

子组件

<template>
    <div>
       <button @click="send()">子传父</button>
    </div>
</template>
<script>
export default {
    data() {
        return {
            childTitle:"子组件的状态"
        }
    },
        methods: {
        send() {
	进行传值给父组件   event必须和父页面的一致             this.$emit("event",this.childTitle)
            }
        },
    }
</script>
2-4$refs-父组件的强权
  • ref如果绑定在dom节点上,拿到的就是 原生dom节点
  • ref如果绑定在组件上,拿到的就是 组件对象,可以实现通信功能

父组件

<template>
    <div>
        $ref
        <filed label="用户名" type="text" ref="username"></filed>
        <filed label="密码" type="password" ref="password"></filed>
        <button @click="login">登录</button>
        <button @click="rest" >重置</button>
    </div>
</template>
<script>
import filed from './filed-父子通信.vue'
export default {
    components: {
        filed
    },
    methods: {
        login() {
            //通过$refs获取子组件的值
         console.log(this.$refs.username.value,this.$refs.password.value);
        },
        rest() {
            this.$refs.username.value="",
            this.$refs.password.value=""
        }
    },
}
</script>

子组件

<template>
    <div>
        <label for="">{{  label}}</label>
       <input  :type="type" v-model="value">
    </div>
</template>
<script>
export default {
    props: ["label", "type"],
        data() {
            return {
                value:""
            }
    },
      
    }
</script>
2-5 KaTeX parse error: Expected 'EOF', got '&' at position 7: parent&̲root - 子组件的无法无天
<template>
    <div>
        parent
        <Child></Child>
        <div v-show="isShow">
            sidebar
        </div>
    </div>
</template>
<script>
import Child from './Child.vue'
export default {
    components: {
        Child
    },
    data() {
        return {
            parentTitle: "父组件11111",
            isShow: true
        }
    },
}
</script>

子组件

<template>
    <div>
        Child
        <button @click="handleClick">$parent</button>
    </div>
</template>
<script>
export default {
    methods: {
        handleClick() {
            //----------------子组件无法无天-----------------
            //在子组件中通过`$parent`访问父组件,通过`$root`访问根组件
            console.log(this.$parent.parentTitle,this.$root);
            this.$parent.isShow=!this.$parent.isShow;
        }
    },
}
</script>
2-6.跨级通信provide和inject

provideinject 是 Vue.js 中用于跨组件通信的一对高级特性。它们允许祖先组件(提供者)向所有后代组件(使用者)传递数据,而不需要通过 props 或事件的方式。

provide ,inject 搭配组合式api使用,具备响应性

provide ,inject 搭配选项式使用, 没有响应性, 把app组件实例

父组件

<!-- 

    provide ,inject 搭配组合式api使用,具备响应性
provide ,inject 搭配选项式使用, 没有响应性, 把app组件实例
 -->
<template>
    <div>
        <navbar></navbar>
        <tabber></tabber>
    </div>
</template>
<script>
import navbar from './Navbar.vue'
import tabber from './Tabber.vue'
export default {
    components: {
        navbar,
        tabber
    },
    // 是一个函数
    provide() {
        return {
            app:this
      }
    },
    data() {
        return {
            title:"首页"
        }
    },
}
</script>

navbar

<template>
    <div style="text-align: center;">
      {{ app.title}}
    </div>
</template>
<script>
export default {
    inject: ['app'],
   
}
</script>

tabber

<template>
    <ul>
        <li v-for="(item, index) in list" :key="index" @click="handlerClick(item.name)">
        {{ item.name }}
        </li>
    </ul>
</template>
<script>
export default {
    inject:["app"],
    data() {
        return {
            list: [
                { name: "首页" },
                { name: "分类" },
                { name: "购物车" },
                { name: "我的" }
            ]
        }
    },
    methods: {
        handlerClick(val) {
           this.app.title=val
        }
    },
}
</script>
<style scoped>

ul{
    list-style: none;
    display: flex;
    position: fixed;
    bottom: 0;
    width: 100%;
  
}
li{
        flex: 1;
        text-align: center;
        height: 60px;
        line-height: 60px;
    }
</style>
2-7动态组件 - 墙头草

在切换时创建新的组件实例通常是有意义的,但在这个例子中,我们的确想要组件能在被“切走”的时候保留它们的状态。要解决这个问题,我们可以用 `` 内置组件将这些动态组件包装起来:

  <!-- 动态组件方式
            它允许你根据当前组件的状态或其他条件,动态地选择渲染不同的组件
            include="Home":这句话的意思,就是Home这个页面,在里面定义了一个名字为Home的,改页面的将会有缓存,没有加的则没有
include,可以包含多个
        -->
    <keep-alive include="List">
        <component :is="obj[title]"></component>
    </keep-alive>
<!-- 以英文逗号分隔的字符串 -->
<KeepAlive include="a,b">
  <component :is="view" />
</KeepAlive>

<!-- 正则表达式 (需使用 `v-bind`) -->
<KeepAlive :include="/a|b/">
  <component :is="view" />
</KeepAlive>

<!-- 数组 (需使用 `v-bind`) -->
<KeepAlive :include="['a', 'b']">
  <component :is="view" />
</KeepAlive>
2-8异步组件(按需加载)

在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件。Vue 提供了 defineAsyncComponent 方法来实现此功能:

//----------------异步组件(按需加载)提高性能-----------------
import { defineAsyncComponent } from 'vue'
 components: {
        navbar,
        tabber,
        Center,
        // 这样定义以后,这两个页面,在一开始不会加载,直到使用了之后才会有缓存
        // **加载与错误提示**
        Home: defineAsyncComponent( () => import('./components/Home.vue')),
        List: defineAsyncComponent({
              //   // 加载组件
              loader: () => import('./components/List.vue'),
             // 加载异步组件时使用的组件
         loadingComponent: LoadingComponent,
         // 展示加载组件前的延迟时间,默认为 200ms
         delay: 0,
         // 加载失败后展示的组件
         errorComponent: ErrorComponent,
         // 如果提供了一个 timeout 时间限制,并超时了
         // 也会显示这里配置的报错组件,默认值是:Infinity
         timeout: 3000
        }),
    },
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值