vue-组件

文章目录

  • 1.组件使用
    • 1.1 组件创建
    • 1.2 组件注册(局部和全局)
  • 2.组件通信(传值)
    • 2.1 父传子(使用prop)
    • 2.2 子传父(ref)
    • 2.3 自定义事件(即事件车, $emit触发, v-on监听)
    • 2.4 非父子组件传值($emit $on, newVue())
  • 3.插槽 (slot)
    • 3.1 (无名)插槽
    • 3.2 具名插槽(name=' ' ,v-slot:)
  • 4.动态组件
  • 5.异步组件

1.组件使用

1.1 组件创建

创建所需的vue文件即可,可放在创建的类似component文件夹下。
在这里插入图片描述

1.2 组件注册(局部和全局)

1.局部注册

如何注册组件:在需要挂载的父组件内部直接引入子组件

(1)引入子组件文件

//设置的文件名异同都可。
import topnav from './component/topnav';
import leftmenu from './component/leftmenu';
import rightcon from './component/rightcon';

(2)注册局部组件
在components属性中注册

  • 常规键值法
export default{
  components:{
    "v-topnav":topnav,
    "v-leftmenu":leftmenu,
    "v-rightcon":rightcon
  }
  • 省略法:在键值一致情况下,直接使用组件变量
export default{
  components:{
    topnav,  
    leftmenu,
    rightcon
  }

(3)注册完成之后使用局部组件

<template>
<div id="app">
   <v-topnav>v-topnav>
   <v-leftmenu>v-leftmenu>
   <v-rightcon>v-rightcon>
div>
template>

2.全局注册

  • 引入组件:

(1)在main.js中引入组件

import time from './component/child/time.vue'

(2)使用Vue.component( )注册全局组件
Vue.component() 第二个参数可以是引入组件,也可是构造函数。

Vue.component("v-time",time);

(3)直接用标签的方式使用全局组件(同局部组件使用法)

或:

  • 直接创建组件:
Vue.component("counter",{  
 //data 写函数;  template 写组件的内容
 //data 必须是有返回值的函数,而不是对象
 //可能需要创建多次实例(独立维护,互不冲突)
	data:function(){
			return {count:0}
			},
	template:''
    })

独立维护,互不冲突:
在这里插入图片描述

2.组件通信(传值)

2.1 父传子(使用prop)

1.父组件:父组件通过数据绑定的方式进行传值


<v-logo :logosrc="logo" :logoname="name">v-logo>
  data(){
    return{
      logo:"src/assets/logo.png",
      name:"后台管理系统"
    }
  }

2.在子组件中,定义props属性接受父组件传递的数据(3种方式),并引用到标签里

 <img src="logosrc" alt="">
 <span>{{logoname}}span>
//定义props属性的三种写法:
//第一种:简单式写法
//(传递的数据没有类型的约束)
props:['logosrc','logoname'],
//第二种:约束数据类型式写法
//(如果数据类型不一致,会报警告,但传的值显示)
props:{
    logosrc:String,
    logoname:String
    }

vue-组件_第1张图片

//第三种:带默认值且约束数据类型式写法
//(如果父组件没有传递数据,则走默认值)
props:{
    logosrc:{
        type:String,
        default:
        "https://imgpp.ztupic.com/images/202103/OAs2TY1GH21111.jpg"
    },
     logoname:{
        type:String,
        default:"系统"
     }
}
  • 例如,当子组件想获取父组件所有的内容时,利用props属性这样操作:

 <v-logo :parentinfo="this">v-logo>
//父组件
 methods: {
    childsend(){
      console.log("子组件在调用");
    }
  }
//子组件
props:{
     parentinfo:Object
},
mounted() {
    // 通过定义prop属性,获取父组件内容
    let parentcomponent = this.parentinfo;
    console.log(parentcomponent);
    // 调用父组件方法
    parentcomponent.childsend();
}

vue-组件_第2张图片

或使用this.$parent方法让子组件获取父组件所有的内容:

   console.log(this.$parent);//vue给子组件提供获取父组件全部内容的方法

vue-组件_第3张图片

2.2 子传父(ref)

父组件获取子组件的所有内容,使用ref获取虚拟dom来获取子组件

ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例.
关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。

 <v-logo ref="logolist">v-logo>
mounted() {
    // 获取到整个子组件
    let logoinfo = this.$refs.logolist;
    console.log(logoinfo);
    // 父组件执行子组件方法
    logoinfo.sendmsg();
  }

调试结果:
在这里插入图片描述

2.3 自定义事件(即事件车, $emit触发, v-on监听)

先监听,后触发;在子组件内部做触发,在父组件上提前做监听处理,监听后执行调用的是父组件的方法。使用this直接实现。
父组件:

 <v-logo @myevent="dosomething">v-logo>
 methods: {
    dosomething(){
          console.log("监听");
      }
  }

子组件:

 <button @click="emitmsg">触发button>
 methods: {
     emitmsg(){
     //父子组件直接用this.调用,非父子组件不可以
      this.$emit("myevent");
    }

调试结果:
在这里插入图片描述 在这里插入图片描述

作用是子组件修改父组件的相关变量。

2.4 非父子组件传值($emit $on, newVue())

vue-组件_第4张图片
main.js文件:

//非父组件直接使用事件车通信 来源于new Vue()
Vue.prototype.emitEvent = new Vue();

其一组件:

 <button @click="sendright">传送到右边button>
 methods: {
 //发送数据 发布自定义事件 携带数据
 // this.emitEvent.$emit(,)第二个参数可以传任意数据类型的数据
    sendright(){
      this.emitEvent.$emit("go-right",{
        name:"jm",
        age:12
      })
    }
  }

另一组件:

 mounted() {
 //该组件渲染完成之后自动监听自定义事件
    this.emitEvent.$on("go-right",(res)=>{
        console.log(res);
      })
  }

3.插槽 (slot)

父组件不能直接在引入的子组件标签中添加dom元素,不会显示。所以需要使用slot插槽。
插槽就是占位置,在子组件加入插槽,父组件给子组件标签添加的元素会自动进入插槽空间,并显示。
提供组件的复用。

3.1 (无名)插槽

子组件:

<template>
<div id="userlist">
    <p>我是用户的列表组件p>
    <slot>slot>
div>
template>

父组件:

<template>
<div id="rightcon">
    <p>我是右边内容区组件p>
    
    <v-userlist> <p>加了slot后我可以显示了p> v-userlist>
div>
template>

在这里插入图片描述

可以使用默认插槽(插槽内添加默认数据),如果父组件不在子组件标签内添加元素(没有给插槽内容),会显示默认数据,反之显示新添加的数据。

3.2 具名插槽(name=’ ’ ,v-slot:)

子组件:

  <header>
 
         <slot name="header"> slot>
   header>
   <main>
        <slot name="content"> slot>
   main>
   <footer>
        <slot name="footer"> slot>
   footer>

父组件:

<v-userlist>
	
	
      <template v-slot:header> <p>头部p> template>
      <template v-slot:content> <p>内容p> template>
      <template v-slot:footer> <p>底部p> template>
v-userlist> 

vue-组件_第5张图片

4.动态组件

1.在一个多标签的界面中使用 is attribute 来切换不同的组件;
2.同时在组件之间切换的时候,想保持这些组件的状态,以避免反复重渲染导致的性能问题。使用keep-alive标签。

vue-组件_第6张图片
vue-组件_第7张图片

选项卡1对应1-x页面,选项卡2对应2-x页面。实现的效果是:切换回上一页面,状态仍保持。



 <keep-alive>
      <component :is="componentId">component>
  keep-alive>


 
  
 
 
  

并且 具有两个属性:(“变量”是vue组件的name,以字符串或正则表达式形式)
:include="变量" 需要缓存的组件
:exclude=" " 除此组件之外都缓存

5.异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。

1.这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。

<v-async>v-async>
import Async from './components/async';
export default {
components:{
    // 异步加载  引入但没有挂载    
     'v-async':function(resolve,reject){
        setTimeout(function(){
        // 返回组件名
         resolve(Async);
      },2000)
   }
 }

2.也可以将异步组件和 webpack 的 code-splitting 功能一起配合使用,写成按需加载require

<component :is="componentId">component>
export default {
	components:{
    	'async':(resolve,reject)=>{
    	//resolve是全部引入成功以后的回调函数,第一个参数是依赖,require会先引入依赖模块,再执行回调函数。
    	 	return require(['./components/async'],resolve);
		}
	 },
	data(){
    	return{
        	componentId:'async'
    }
  }
 }

3.也可以在工厂函数中返回一个 Promise,所以把 webpack 2ES2015 语法加在一起,我们可以这样使用动态导入:

<async>async>
components:{
'async':
  // 这个动态导入会返回一个 `Promise` 对象。
  ()=>import('./components/async')
  }
 }
  1. 2.3.0+ 新增,异步组件工厂函数也可以返回一个如下格式的对象:
<async>async>
 'async':() => ({
  // 需要加载的组件 (应该是一个 `Promise` 对象)
  component: import('./components/async'),
  // 异步组件加载时使用的组件
  // loading: LoadingComponent,
  // 加载失败时使用的组件 (引入的组件)
  // error: ErrorComponent,
  // 展示加载时组件的延时时间。默认值是 200 (毫秒)
  delay: 200,
  // 如果提供了超时时间且组件加载也超时了,
  // 则使用加载失败时使用的组件。默认值是:`Infinity`
  timeout: 3000
})

上面代码的component属性也可以这样写:

component: new Promise((resolve,reject)=>{
      let data = true;
      if(data){
      //tabone是引入组件
        setTimeout(resolve,2000,tabone);
      }
      else{
        reject(new Error('失败'))
      }
  })

你可能感兴趣的:(vue,vue,组件通信,插槽)