vue3学习11、12、13组件化开发(vue组件化开发案例)
ztj100 2024-11-12 14:22 14 浏览 0 评论
利用vue脚手架创建一个项目
vue create component_demo
可以在vscode中安装Vue VSCode Snippets插件或vue3 snippets,帮助生成一些代码片段
vbase-css
可以快速生成vue3模板
组件通信
父子组件之间通信
- 父组件传递给子组件:通过props属性
- 子组件传递给父组件:通过$emit触发事件
在父组件中引入组件传值
<show-message :title="title"></show-message>
子组件中在props中定义
props: {
title: {
type: String,
require: true, //表示这个属性是必传的
default: '123' //默认属性
},
//当属性是Object型时,默认值要为一个函数.因为多个组件会引用同一个对象
info: {
type: Object,
default() {
return {name: 'juju'}
}
},
//自定义验证函数
man: {
validator(value) {
//这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].include(value)
}
}
}
props命名 建议父组件中要传递的值采用驼峰写法
<show-message :message-info="title"></show-message>
...
data() {
return {
messageInfo: 'damn'
}
}
非props的Attribute
当我们传递给一个组件某个属性,但是该属性并没有定义对应的props或者emits,就称之为非props的Aaaribute
常见的包括css,style,id属性等 例如当给子组件设置一个class属性
<show-message class="liin" :title="title"></show-message>
当组件有单个根节点时,会自动添加到根节点的attribute
<template>
<div class="liin">
<h2>{{ title }}</h2>
<h2>{{ info.name }}</h2>
</div>
</template>
如果我们不希望根组件继承attribute,可以在子组件中设置inheritAttrs: false 我们可以通过$attrs来访问所有的非props的attribute
<h2 :class="$attrs.class">{{ title }}</h2>
通过v-bind绑定所有属性 父组件
<show-message id="xixi" class="liin" :title="title"></show-message>
子组件
<h2 v-bind="$attrs">{{ title }}</h2>
子组件传递给父组件 子组件中与vue2不同的是多了个emit参数,里面存放着可能要触发的事件
export default {
//emits属性,里面存放着待会会触发的事件
emits: ["add", "sub"],
//emits的对象写法,目的是为了进行参数的验证
emits: {
sub: null,
add: (name, age) => {
if(name == 'juju') {
return true
}
return false
}
},
methods: {
increament() {
this.$emit("add","juju",18) //后面多个参数跟着的是要传的参数
},
decreament() {
this.$emit("sub")
},
}
}
父组件中写法与vue2相同
<counter-operation @add="addOne" @sub="subOne"></counter-operation>
非父组件的通信
- provide/inject
- mitt全局事件总线
- vuex
provide和inject
无论层级结构有多深,父组件都可以作为其所有子组件的依赖提供者; 父组件有一个provide选项来提供数据,子组件有一个inject选项来使用这些数据
在父组件中添加一个provide
components: {
Home
},
provide: {
name: 'juju',
age: 18
},
在子孙组件中注入
export default {
inject: ["name", "age"]
}
当然,许多情况下数据都要从data中拿并从后台请求了,此时的provide要写成函数形式
provide() {
return {
name: juju,
age: 18,
title: this.title
}
},
如果后续title改变的话,inject里的值并不是响应式的,可以使用vue中的computed函数
import {computed} from 'vue'
provide() {
return {
name: juju,
age: 18,
title: computed(() => {
this.title
})
}
},
全局事件总线mitt库
安装mitt库
npm install mitt
创建一个eventbus.js文件
import mitt from 'mitt'
const emitter = mitt();
export default emitter;
// 也可以创建多个mitt对象
测试叔侄组件之间通信 在叔组件中传递
import emmiter from '../util/eventbus.js'
methods: {
btnClick() {
emmiter.emit("handle", "juju",18); //第一个参数方法名,后面跟着的是参数
}
}
在侄组件的生命周期中监听
import emitter from '../util/eventbus.js'
created() {
emitter.on("handle", (name,age)=> {
console.log(name)
})
}
mitt事件取消
emitter.all.clear(); //全部取消监听
function onFoo(){}
emitter.on('foo', onFoo) //监听
emitter.off('foo', onFoo) //取消监听
插槽slot
对于不同的区域可能存放不同的内容,因此要使用slot
- 插槽的使用过程其实是抽取共性,预留不同
- 我们会将共同的元素,内容依然在组件内进行封装
- 同时将不同的元素使用slot作为占位,让外部决定到底显示什么样的元素
简单插槽的使用
定义一个子组件
<h2>组件开始</h2>
<slot></slot>
<h2>组件结束</h2>
在父组件中使用
<my-slot-cpn>
<button>我是按钮</button>
</my-slot-cpn>
此时中间部分可以展示按钮或者图片或者组件,vue会将内容替换到slot的位置
具名插槽的使用
插槽的默认使用 如果子组件是这样的
<div>
<h2>组件开始</h2>
<slot>
<i>我是默认内容</i>
</slot>
<h2>组件结束</h2>
</div>
父组件
<my-slot-cpn>
</my-slot-cpn>
则显示默认内容
具名插槽
在子组件中编写有name属性的插槽
<template>
<div class="nav-bar">
<div class="left">
<slot name="left"></slot>
</div>
<div class="center">
<slot name="center"></slot>
</div>
<div class="right">
<slot name="right"></slot>
</div>
</div>
</template>
在父组件中用template v-slot方式分配元素至对于的slot内
<!-- 具名插槽的使用 -->
<nar-bar>
<template v-slot:left>
<button>左边按钮</button>
</template>
//等价于
<template #left>
<button>左边按钮</button>
</template>
<template v-slot:center>
<h2>我是标题</h2>
</template>
<template v-slot:right>
<i>右边的元素</i>
</template>
</nar-bar>
效果
如果名字是不定的话,template应该这么写
<template v-slot:[name]>
<i>右边的元素</i>
</template>
作用域插槽
即子组件中的slot属性,可以传给父组件 子组件
<template>
<div>
<template v-for="(item,index) in names" :key="item">
<slot :item="item" :index="index"></slot>
</template>
</div>
</template>
父组件通过v-slot取得
<show-names>
<template v-slot="slotProps">
<button>{{slotProps.item}}-{{ slotProps.index }}</button>
</template>
</show-names>
//是下面的简写,v-slot后跟插槽名字
<show-names>
<template v-slot:default="slotProps">
<button>{{slotProps.item}}-{{ slotProps.index }}</button>
</template>
</show-names>
当只有默认插槽时,可以使用独占默认插槽写法
<show-names v-slot="slotProps">
<button>{{slotProps.item}}-{{ slotProps.index }}</button>
</show-names>
动态组件的实现
根据不同的场景,去渲染不同的组件。以前基本都使用v-if去判断从而渲染不同的组件。但是当组件很多的时候,组件会显得很臃肿。此时可以考虑采用动态组件去实现。
动态组件是使用component组件,通过特殊的attribute is来实现。 例如
<component is="hello-world"></component>
此时就会渲染HelloWorld组件
动态组件传递参数
<component is="hello-world" name="juju" :age="18" @helloClick="handleClick"></component>
此时在helloworld组件可以用props接收,同时动态组件可以接受子组件的点击事件
keep-alive
默认情况下,切换组件会被销毁,再次回来会重新创建组件。此时,在开发中某些情况我们希望继续保持组件的状态,而不是销毁掉,这时我们可以使用一个内置组件:keep-alive。
<keep-alive>
<component is="hello-world" name="juju" :age="18" @helloClick="handleClick"></component>
<keep-alive>
keep-alive有一些属性,
- include.[string|regexp|array]只有名称匹配的组件会被缓存。
- exclude[string|regexp|array]任何匹配的组件都不会会被缓存。
- max[number|string]最多可以缓存多少组件实例,一旦达到这个数字,那么缓存组件中最近没有被访问的实例会被销毁
include是根据组件的name属性来进行适配,因此有时需要给组件加上name属性
export default {
name: 'about',
}
webpack分包
正常打包的话会将所有资源打包到一个app.js文件中,采用webpack分包方式会将利用分包的资源打包到一个chunk文件中,需要时再去加载,可以优化首屏渲染。
//通过import函数导如的模块,后续webpack对其进行打包的时候就会进行分包的操作
import('./utils/math').then(res => {console.log(sum(10,20))})
异步组件
同时vue3提供一个函数可以使打包后的组件成为一个单独的文件夹,加快首屏渲染速度 defineAsyncComponent接受两种类型的参数: 类型一:工厂函数,该工厂函数需要返回一个promise对象 类型二:接受一个对象类型,对异步函数进行配置
import {defineAsyncComponent} from 'vue'
const AsyncHello = defineAsyncComponent(() => import('./components/HelloWorld.vue'))
一般开发中使用路由懒加载比较多
获取元素和refs
在某些情况下,我们组件想要直接获取到元素对象或者子组件实例 在vue开发中我们不推荐dom操作的,这个时候,可以给元素或者组件绑定以恶搞ref的attribute属性
<h2 ref="title">哈哈哈哈哈哈</h2>
mounted() {
console.log(this.$refs.title)
},
打印结果
对于组件来说,调用this.refs.xx可以获取组件实例,取得data中的数据或调用一些方法。 同时,可以在子组件中采用this.parent取得父组件实例以及parent取得父组件实例以及parent取得父组件实例以及root获取根组件
组件的生命周期
- beforecreated
- created
- beforemounted
- mounted
- beforeUpdate
- updated
- beforeUnmount
- unmounted
对于有缓存的组件来说,再次进入时,我们是不会执行created或者mounted等生命周期的,这时我们可以使用activated和deactiveated这两个生命周期钩子函数来监听。
组件的v-model
//组件绑定v-model与下列的等价
<hy-input v-model="title"></hy-input>
<!-- <hy-input :modelValue="title" @update:model-value="title = $event"></hy-input> -->
<template>
<div>
<button @click="btnClick">input按钮</button>
{{ modelValue }}
</div>
</template>
<script>
export default {
props: {
modelValue: String
},
emits: ["update:modelValue"],
methods: {
btnClick() {
this.$emit("update:modelValue", '嘿嘿')
}
}
}
</script>
$event为update:model-value事件传出来的参数
如果子组件中有input可以实现v-model绑定计算属性的操作,因为不能绑定到props里
<input v-model="value" />
...
computed: {
value: {
get(){
return this.modelValue
},
set(value) {
this.$emit("update:modelValue", value)
}
}
},
绑定多个v-model,后面加名字,此时why为子组件prop的值
<hy-input v-model="title" v-model:why="why"></hy-input>
相关推荐
- 告别手动操作:一键多工作表合并的实用方法
-
通常情况下,我们需要将同一工作簿内不同工作表中的数据进行合并处理。如何快速有效地完成这些数据的整合呢?这主要取决于需要合并的源数据的结构。...
- 【MySQL技术专题】「优化技术系列」常用SQL的优化方案和技术思路
-
概述前面我们介绍了MySQL中怎么样通过索引来优化查询。日常开发中,除了使用查询外,我们还会使用一些其他的常用SQL,比如INSERT、GROUPBY等。对于这些SQL语句,我们该怎么样进行优化呢...
- 9.7寸视网膜屏原道M9i双系统安装教程
-
泡泡网平板电脑频道4月17日原道M9i采用Win8安卓双系统,对于喜欢折腾的朋友来说,刷机成了一件难事,那么原道M9i如何刷机呢?下面通过详细地图文,介绍原道M9i的刷机操作过程,在刷机的过程中,要...
- 如何做好分布式任务调度——Scheduler 的一些探索
-
作者:张宇轩,章逸,曾丹初识Scheduler找准定位:分布式任务调度平台...
- mysqldump备份操作大全及相关参数详解
-
mysqldump简介mysqldump是用于转储MySQL数据库的实用程序,通常我们用来迁移和备份数据库;它自带的功能参数非常多,文中列举出几乎所有常用的导出操作方法,在文章末尾将所有的参数详细说明...
- 大厂面试冲刺,Java“实战”问题三连,你碰到了哪个?
-
推荐学习...
- 亿级分库分表,如何丝滑扩容、如何双写灰度
-
以下是基于亿级分库分表丝滑扩容与双写灰度设计方案,结合架构图与核心流程说明:一、总体设计目标...
- MYSQL表设计规范(mysql表设计原则)
-
日常工作总结,不是通用规范一、表设计库名、表名、字段名必须使用小写字母,“_”分割。...
- 怎么解决MySQL中的Duplicate entry错误?
-
在使用MySQL数据库时,我们经常会遇到Duplicateentry错误,这是由于插入或更新数据时出现了重复的唯一键值。这种错误可能会导致数据的不一致性和完整性问题。为了解决这个问题,我们可以采取以...
- 高并发下如何防重?(高并发如何防止重复)
-
前言最近测试给我提了一个bug,说我之前提供的一个批量复制商品的接口,产生了重复的商品数据。...
- 性能压测数据告诉你MySQL和MariaDB该怎么选
-
1.压测环境为了尽可能的客观公正,本次选择同一物理机上的两台虚拟机,一台用作数据库服务器,一台用作运行压测工具mysqlslap,操作系统均为UbuntuServer22.04LTS。...
- 屠龙之技 --sql注入 不值得浪费超过十天 实战中sqlmap--lv 3通杀全国
-
MySQL小结发表于2020-09-21分类于知识整理阅读次数:本文字数:67k阅读时长≈1:01...
- 破防了,谁懂啊家人们:记一次 mysql 问题排查
-
作者:温粥一、前言谁懂啊家人们,作为一名java开发,原来以为mysql这东西,写写CRUD,不是有手就行吗;你说DDL啊,不就是设计个表结构,搞几个索引吗。...
- MySQL 之 Performance Schema(mysql安装及配置超详细教程)
-
MySQL之PerformanceSchema介绍PerformanceSchema提供了在数据库运行时实时检查MySQL服务器的内部执行情况的方法,通过监视MySQL服务器的事件来实现监视内...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)