- 02-组件的概念及组件的基本使用方式
- 03-组件之间是如何进行互相通信的
- 04-组件的属性与事件是如何进行处理的
- 05-组件的内容是如何组合与分发处理的
- 06-仿Element Plus框架的el-button按钮组件实现
- 07-单文件组件SFC及Vue CLI脚手架的安装使用
- 08-脚手架原理之webpack处理html文件和模块打包
- 09-脚手架原理之webpack启动服务器和处理sourcemap
- 10-脚手架原理之webpack处理样式模块和图片模块
- 11-脚手架原理之webpack处理单文件组件及loader转换
- 12-Vite3介绍及基本使用
- 13-仿Element Plus的el-rate评分组件实现(单文件组件)
Vue.js文件下载地址
下载地址:https://unpkg.com/vue@3.2.36/dist/vue.global.js
组件的概念及组件的基本使用方式
组件的概念
组件是带有名称的可复用实例,通常一个应用会以一棵嵌套的组件树的形式来组织,比如:页头、侧边栏、内容区等组件。
组件可以拥有自己独立的结构,样式,逻辑。这样对于后期的维护是非常方便的。下面给出评分组件与按钮组件的抽离过程。
组件的命名方式与规范
- 定义组件可通过驼峰、短线两种风格定义
- 调用组件推荐短线方式
<div id="app">
<my-head></my-head>
</div>
<script>
let app = Vue.createApp({
data(){
return {
}
}
})
app.component('my-head', {
template: `
<header>
<div>{{ message }}</div>
<h2>logo</h2>
<ul>
<li>首页</li>
<li>视频</li>
<li>音乐</li>
</ul>
</header>`,
data(){
return {
message: 'hello world'
}
}
});
let vm = app.mount('#app');
</script>
根组件
app容器可以看成根组件,所以根组件跟普通组件都具备相同的配置信息,例如:data、computed、methods等等选项。
<div id="app">
<my-head></my-head>
</div>
<script>
// 根组件
let RootApp = {
data(){
return {
}
}
};
// MyHead组件
let MyHead = {
template: `
<header>
<div>{{ message }}</div>
<h2>logo</h2>
<ul>
<li>首页</li>
<li>视频</li>
<li>音乐</li>
</ul>
</header>
`
};
let app = Vue.createApp(RootApp)
app.component('MyHead', MyHead);
let vm = app.mount('#app');
</script>
根组件与MyHead组件形成了父子组件。
局部组件与全局组件
局部组件只能在指定的组件内进行使用,而全局组件可以在容器app下的任意位置进行使用。
组件之间是如何进行互相通信的
上一个小节中,我们了解了组件是可以组合的,那么就形成了父子组件,父子组件之间是可以进行通信的, 那么为什么要通信呢?主要是为了让组件满足不同的需求。
父子通信
最常见的通信方式就是父传子,或者子传父,那么父传子通过props实现,而子传父则通过emits自定义事件实现。
<div id="app">
<my-head :count="count" @custom-click="handleClick"></my-head>
</div>
<script>
let app = Vue.createApp({
data(){
return {
count: 10
}
},
methods: {
handleClick(data){
console.log(data);
}
}
})
app.component('MyHead', {
props: ['count'],
emits: ['custom-click'],
template: `
<header>
<div>{{ count }}</div>
<h2>logo</h2>
<ul>
<li>首页</li>
<li>视频</li>
<li>音乐</li>
</ul>
</header>`,
mouted(){
this.$emit('custom-click', 'MyHead Data')
}
});
let vm = app.mount('#app');
</script>
父子通信需要注意的点
- 组件通信的props是可以定义类型的,在运行期间会进行检测
- 组件之间的数据是单向流动的,子组件不能直接修改传递过来的值
- 但是有时候也需要数据的双向流动,可利用v-model来实现
组件的属性与事件是如何进行处理的
有时候组件上的属性或事件并不想进行组件通信,那么Vue是如何处理的呢?
组件的属性与事件
默认不通过props接收的话,属性会直接挂载到组件容器上,事件也是如此,会直接挂载到组件容器上。可通过 inheritAttrs 选项阻止这种行为,通过指定这个属性为false,可以避免组件属性和事件向容器传递。可通过 $attrs 内置语法,给指定元素传递属性和事件,代码如下:
<div id="app">
<my-head title="hello world" class="box" @click="handleClick"></my-head>
</div>
<script>
let app = Vue.createApp({
data(){
return {
}
},
methods: {
handleClick(ev){
console.log(ev.currentTarget);
}
}
})
app.component('MyHead', {
template: `
<header>
<h2 v-bind:title="$attrs.title">logo</h2>
<ul v-bind:class="$attrs.class">
<li>首页</li>
<li>视频</li>
<li>音乐</li>
</ul>
</header>
`,
mounted(){
console.log( this.$attrs ); // 也可以完成父子通信操作
},
inheritAttrs: false // 阻止默认的属性传递到容器的操作
});
let vm = app.mount('#app');
</script>
$attrs也可以实现组件之间的间接通信。
组件的内容是如何组合与分发处理的
在前面的小节中,我们学习了组件之间的通信,让组件之间实现了不同的需求,我们通过给组件添加不同的属性来实现。那么在Vue中如何去传递不同的组件结构呢?这就涉及到了组件内容的分发处理。
插槽slot
在Vue中是通过插槽slot方式来进行分发处理的,Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将
<div id="app">
<my-head>
<p>logo</p>
</my-head>
</div>
<script>
let app = Vue.createApp({
data(){
return {
message: 'hello'
}
}
})
app.component('MyHead', {
data(){
return {
};
},
template: `
<header>
<slot></slot>
</header>`,
});
let vm = app.mount('#app');
</script>
组件内的结构,即<p>logo</p>
会被分发到<slot></slot>
所在的区域。
内容分发与插槽的注意点
- 渲染作用域 -> 插槽只能获取当前组件的作用域
- 具名插槽 -> 处理多个插槽的需求,通过v-slot指令实现,简写为#
- 作用域插槽 -> 希望插槽能访问子组件的数据
完整代码如下:
<div id="app">
<my-head>
<template #title>
<p>logo, {{ message }}, {{ count }}</p>
</template>
<template #list="{ list }">
<ul>
<li v-for="item in list">{{ item }}</li>
</ul>
</template>
</my-head>
</div>
<script>
let app = Vue.createApp({
data(){
return {
message: 'hello'
}
}
})
app.component('MyHead', {
data(){
return {
count: 123,
list: ['首页', '视频', '音乐']
};
},
template: `
<header>
<slot name="title"></slot>
<hr>
<slot name="list" :list="list"></slot>
</header>
`,
});
let vm = app.mount('#app');
</script>
单文件组件SFC及Vue CLI脚手架的安装使用
Vue 单文件组件(又名 *.vue 文件,缩写为 SFC)是一种特殊的文件格式,它允许将 Vue 组件的模板、逻辑 与 样式封装在单个文件中。
为什么要使用 SFC
使用 SFC 必须使用构建工具,但作为回报带来了以下优点:
- 使用熟悉的 HTML、CSS 和 JavaScript 语法编写模块化的组件
- 让本来就强相关的关注点自然内聚
- 预编译模板,避免运行时的编译开销
- 组件作用域的 CSS
- 在使用组合式 API 时语法更简单
- 通过交叉分析模板和逻辑代码能进行更多编译时优化
- 更好的 IDE 支持,提供自动补全和对模板中表达式的类型检查
- 开箱即用的模块热更新 (HMR) 支持
如何支持SFC
可通过项目脚手架来进行支持,Vue支持Vite脚手架和Vue CLI脚手架。这里我们先来介绍Vue CLI的基本使用方式。
# 安装
npm install -g @vue/cli
# 创建项目
vue create vue-study
# 选择default
default (babel, eslint)
# 启动脚手架
npm run serve
通过localhost:8080进行访问。
脚手架文件的组成
- src/main.js -> 主入口模块
- src/App.vue -> 根组件
- src/components -> 组件集合
- src/assets -> 静态资源
单文件的代码组成
- template -> 编写结构
- script -> 编写逻辑
- style -> 编写样式
其中style中的scoped属性,可以让样式成为局部的,不会影响到其他组件,只会作用于当前组件生效,同时在脚手架下支持常见的文件进行模块化操作,例如:图片、样式、.vue文件等。
评论 (0)