# vue的一些高级特性

# 自定义v-mdoel

其实本质上,v-model是v-bind以及v-on配合使用的语法糖:

<input v-model="value" />
// 就是相当于: 
<input :value="value" @input="value= $event.target.value" />
# model

允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。

结合第一点的代码概括起来是个什么意思呢?就是说,本来默认是这样的:

  • 子接收到的prop值 = value

  • 监听子组件触发的事件名event = input 我们要在自定义组件上用啊,老是用默认的那岂不是限制了我的发挥?于是,vue在2.2.0版本中新增了一个model选项,可以让我们这样:

  • 子接收到的prop值 = "想什么值就什么值"

  • 监听子组件触发的事件名event = "想什么事件名就什么事件名"

// 父组件
<Child v-model='iptValue'></Child>

// 子组件
Vue.components('Child',{
        model: {
            prop: 'ipt',
            evnet: change    
        }
        props: {
            ipt: Number
        }
        template: `<input type='number' :value='ipt' @change='$emit("change",parseInt($event.target.value))'>`
		})

v-model

# $nextTick

nextTick

# slot

slot

# vue动态组件

动态组件是使用 component 组件,通过一个特殊的attribute is 来实现

在不同组件之间进行动态切换是非常有用的,①tab栏切换②在一个多标签的界面里[一个广告,五秒后消失,同一个地方,有一个实用的功能出现]

<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>

在上述示例中,currentTabComponent 可以包括

  • 已注册组件的名字,或
  • 一个组件的选项对象
<template>
	<div>
		<component :is="k1"></component>
	</div>
</template>

<script>
    import mo from './module.vue'
	import m1 from "./Display.vue"
	export default{
		data(){
			return {
				k1:"mo"
			}
		},
		mounted(){
			setTimeout(()=>{
				this.k1="m1"
			},5000)
			//5秒后子组件变成了m1
		},
		components:{
			mo,m1
		}
	}
</script>

# vue异步组件

  1. 默认的打包过程:
    • 默认情况下,在构建整个组件树的过程中,因为组件和组件之间是通过模块化直接依赖的,那么webpack在打包时就会将组件模块打包到一起(比如一个app.js文件中);
    • 这个时候随着项目的不断庞大,app.js文件的内容过大,会造成首屏的渲染速度变慢;
  2. 打包时,代码的分包:
    • 所以,对于一些不需要立即使用的组件,我们可以单独对它们进行拆分,拆分成一些小的代码块chunk.js;
    • 这些chunk.js会在需要时从服务器加载下来,并且运行代码,显示对应的内容;
  • import()函数
  • 按需加载,异步加载大组件
  • 什么时候用到什么时候加载
  • webpack发现是动态import引入的内容会单独分包处理
<!--当需要的时候让x为true-->
<B v-if="x"/>
import A from "a.vue"//这是同步加载

compontnets:{
	A,
	B:()=>import("./b.vue")
}

# 异步组件

  • 方法一:使用import,组件导入:( 实际应用子组件的mounted内容会在没点击到第二个组件就打印出来了? )
<template>
<div class="tenantinfo">
   <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
    <el-tab-pane label="基本信息" name="first">
      1
    </el-tab-pane>
    <el-tab-pane label="用户管理" name="second">
      <tenantbasic/>
    </el-tab-pane>
    <el-tab-pane label="查看权限" name="third">
      3
    </el-tab-pane>
  </el-tabs>
</div>
 
</template>
<script>
  const One =()=>import("@/views/platform/components/tenantbasic.vue")
  export default {
    data() {
      return {
        activeName: 'first'
      };
    },
    components:{
      tenantbasic:One
    },
}
</script>

方法二:使用require,借助vue内置组件component(动态组件的写法)

<component  :is="yhgl" ></component> //is绑定的就是动态组件的名称
<template>
<div class="tenantinfo">
   <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
    <el-tab-pane label="基本信息" name="first">
      1
    </el-tab-pane>
    <el-tab-pane label="用户管理" name="second">
      <component  :is="yhgl" ></component>
    </el-tab-pane>
    <el-tab-pane label="查看权限" name="third">
      3
    </el-tab-pane>
  </el-tabs>
</div>
 
</template>
<script>

  const tenantbasic = resolve => require(['@/views/platform/components/tenantbasic.vue'], resolve)
  export default {
    data() {
      return {
        activeName: 'first'
      };
    },
    methods: {
      handleClick (tab, event) {
        this.checkVue(tab.name)
     },
     checkVue (name) {
       console.log(name)
       switch (name) {
        case 'second' :
          this.yhgl = tenantbasic
          break
        case 'third' :
          this.lszhzVue = lszhzCont
          break;
        default:
          break;
      }

    }
  }}
</script>

# Vue3异步组件 Vue.defineAsyncComponent

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>lesson 21</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // 动态组件: 根据数据的变化,结合 compoent 这个标签,来随时动态切换组件的现实
  // 异步组件: 是异步执行某些组件的逻辑,这叫做异步组件

  const app = Vue.createApp({
    template: `
      <div>
        <common-item />
        <async-common-item />
      </div>
    `
  });

  app.component('common-item', {
    template: `<div>hello world</div>`
  });

  app.component('async-common-item', Vue.defineAsyncComponent(() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({
          template: `<div>this is an async component</div>`
        })
      }, 4000)
    })
  }))

  const vm = app.mount('#root');
</script>
</html>

Vue3中给我们提供了一个函数:defineAsyncComponent。defineAsyncComponent接受两种类型的参数:

  • 类型一:工厂函数,该工厂函数需要返回一个Promise对象;
  • 类型二:接受一个对象类型,对异步函数进行配置;
  import { defineAsyncComponent } from 'vue';
  const AsyncCategory = defineAsyncComponent(() => import("./AsyncCategory.vue"))
  export default {
    components: {
      AsyncCategory,
    }
  }
  import { defineAsyncComponent } from 'vue';
  import Loading from './Loading.vue';
  const AsyncCategory = defineAsyncComponent({
    loader: () => import("./AsyncCategory.vue"),
    loadingComponent: Loading,
    // errorComponent,
    // 在显示loadingComponent组件之前, 等待多长时间
    delay: 2000,
    /**
     * err: 错误信息,
     * retry: 函数, 调用retry尝试重新加载
     * attempts: 记录尝试的次数
     */
    onError: function(err, retry, fail,attempts) {

    }
  })
  export default {
    components: {
      AsyncCategory,
      Loading
    }
  }

# 异步组件结合Suspense

<template>
  <div>
    App组件
    <home></home>
    <suspense>
      <template #default>
        <async-category></async-category>
      </template>
      <template #fallback>
        <loading></loading>
      </template>
    </suspense>
  </div>
</template>
<script>
  import { defineAsyncComponent } from 'vue';
  import Loading from './Loading.vue';
  const AsyncCategory = defineAsyncComponent(() => import("./AsyncCategory.vue"))
  export default {
    components: {
      AsyncCategory,
      Loading
    }
  }
</script>

suspense内置组件处理异步

# keep-alive

keep-alive

# mixin

抽离公共逻辑或者功能,使用mixin会是变量来源不明确,不利于阅读 mixin

最后更新: 9/5/2022, 8:26:49 AM