Vue3组件化开发

Posted coder斌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3组件化开发相关的知识,希望对你有一定的参考价值。

动态组件的使用

若我们想不依靠vue-router实现tab-bar的功能

image-20210610162853041

实现一:v-if v-else-if v-else 实现

<template>
<div class="app">
    <button v-for="item in list" 
            :key="item" 
            :class="{current:item === currentItem}"
            @click="btnClic(item)"
            >{{item}}</button>
    <template v-if="currentItem === '首页'">
        <h2>首页</h2>
    </template>
    <template v-else-if="currentItem === '分类'">
        <h2>分类</h2>
    </template>
    <template  v-else-if="currentItem === '购物车'">
        <h2>购物车</h2>
    </template>
    <template v-else>
        <h2>我的</h2>
    </template>
</div>
</template>

实现二:利用vue提供的component组件

<template>
<div class="app">
    <button v-for="item in list" 
            :key="item" 
            :class="{current:item === currentItem}"
            @click="btnClic(item)"
            >{{item}}</button>
     <!-- 方法二 : 动态组件的基本使用 -->
    <!-- 注意: 切换后组件是不会被缓存的 -->
    <!-- include的三种写法::include="['home','category']"  include="home,category" :include="/home|category /" -->
   <keep-alive :include="['home','category']" > 
        <component :is="componentsList[list.indexOf(currentItem)]"
                    @btnClic="shopCartClic"
                    :name="info.name">
        <h2>HELLO VUE3</h2>
    </component>
    </keep-alive>
</div>
</template>
  • 动态组件切换依靠的是is这个属性,它的值是平常在template组件内使用的名字。
  • 可以像其他普通的组件一样,父组件向子组件传值(props),子组件向父组件传值($emit)。
  • 同时和其他自定义组件一样可以使用插槽

组件的缓存 keep-alive

  • component组件,默认是没有缓存的,组件切换之后对应的状态不会保存,可以使用keep-alive组件
  • keep-alive组件有include,exclude,max对应的值,值是vue文件内的name值。
  • vue文件内的name属性,其实在vue中主要有两个地方使用。其一就是keep-alive,另一个就是devtool调试工具

webpack中的import函数的分包

我们在webpack中通过require()或者import .. from ..引入文件打包,会将主入口文件依赖的文件全部打包的主入口一个文件内,若文件过多,代码量庞大,势必会造成浏览器首屏加载速度太慢,用户体验下降。

在vue脚手架中为例,main.js中通过上述引用文件的两种方式,进行打包。结果如下 >>>

image-20210610165123774

所有写的代码都会打包到app.js着一个文件内。

解决: 在引用时采用 import(...),返回值是一个promise对象。

image-20210610165734968

Vue中定义异步组件和代码分包

  • 利用vue提供的defineAsyncComponent方法
  • 下面这样打包的时候Home.vue文件就会被单独打包成一个文件
<script>
import {defineAsyncComponent} from 'vue'
// 直接引入模块
const Home = defineAsyncComponent(()=>import('./Home.vue'))
// 通过配置信息
import LoadingComponents from './LoadingComponents.vue'
import ErrorComponent from './ErrorComponent.vue'
const Home = defineAsyncComponent({
    loader:()=>import('./Home.vue'),
    loadingComponent:LoadingComponents, // 加载等待时展示的vue文件
    errorComponent:ErrorComponent,  // 加载出错后展示的vue文件
    delay:2000,
    timeout:2000,
    onError(err,retry,fail,attempts){
    }
})
export default {
    components:{
        Home
    },
  data () {
    return {
    }
  }
}
</script>

异步组件和suspence组件结合

  • 个人感觉就是通过配置信息创建异步组件的另一种表现形式。在html代码里面就设置好加载等待时展示的vue文件
  • 该组件有两个插槽
    • default:如果default可以显示,就显示default的内容
    • fallback:若default不可以显示,就显示fallback的内容

image-20210610171222615

$refs $parent$root的使用

  • 注意:vue3已经取消掉$children

$refs的使用

<template>
<div class="app">
    <div ref="div">我是div内容</div>
    <home ref="home"></home>
    <button @click="btnClic">获取内容</button>
</div>
</template>
<script>
import Home  from './Home.vue'
export default {
    components:{
        Home
    },
  data () {
    return {
    }
  },
  methods:{
      btnClic(){
          // 直接用在元素上是获取元素
          console.log(this.$refs.div);
          // 作用在组件上是获取组件的实例
          console.log(this.$refs.home.message);
          // $el获取子组件的元素
          console.log(this.$refs.home.$el);
      }
  }
}
</script>
<style  scoped>
</style>

$parent$root的使用

image-20210610172206788

打印结果:

image-20210610172441854

组件的生命周期

由于CSDN无法添加SVG图片,就提供一下地址,另外打开查看吧。
生命周期图示

**注意:**主要是我自己注意,我在这个update这里我以为只要响应式数据变化了,update钩子函数就会调用。其实只有挂载到页面上的数据引起变化,需要重新渲染内容才会触发

缓存组件的生命周期

在上面的钩子函数基础上又加了两个:activateddeactivated

  • 从不活跃太到活跃态,回调**activated**
  • 从不活跃太到活跃态,回调**deactivated**

自定义组件v-model的使用

  • 就是饿了么组件的封装实现形式

基本使用

<template>
    <home v-model="name"></home>
    <!-- 上面的写法就是下面的简写 modelValue向子组件传递一个值 子组件返回 update:modelValue 的一个函数 -->
    <home :modelValue="name" @update:modelValue="name = $event"></home>
</template>

子组件Home.vue

<template>
<div class="home">
    <input type="text" :value="modelValue" @input="iptInpt">
</div>
</template>

<script>
export default {
    props:{
        modelValue:{
            type:String,
            default:'aaa'
        }
    },
    emits:['update:modelValue'],
    methods:{
      iptInpt(e){
          this.$emit('update:modelValue',e.target.value)
      }
   }
}
</script>

<style  scoped>
</style>

计算属性实现

子组件Home.vue

 computed:{
      getTitle:{
          set(value){
               this.$emit('update:title',value)
          },
          get(){
              return this.title
          }
      }
  },

自定义组件多个v-model的实现

App.vue

<home v-model="name" v-model:title="age"></home>

Home.vue

  • props内添加 title
  • emits里的事件增加对应名字 update:title
  • 再增加对应计算属性就ok了

以上是关于Vue3组件化开发的主要内容,如果未能解决你的问题,请参考以下文章

简单体验Vue2和Vue3开发组件的区别-案例

vue3基础练习

Vue3的表单和开发模式

Vue3基础知识总结

Vue3基础知识总结

Vue3基础知识总结