声明:本文基于黑马程序员VUE课程学习,文中大量引用了公开资料中的图片及代码,如有侵权请联系本人
文章目录
一 . vue 基础
1.事件对象 event
e.target 事件触发源 在这里指的是button 按钮
a.target.style.backgroungColor=nobgcolor==='red' ? '':'red'
nobgcolor===‘red’ ? ‘’:‘red’
三元描述符,判断背景颜色是不是红色 ,是则返回空字符,不是则返回red.最后将返回值赋给a.target.style.backgroungColor。更改本身的背景颜色
2.事件参数$event
如果你想在按钮+1的基础上加上更改背景颜色的事件,怎么办?
addNewCount(step)
addNewCount(e){
this.count+=step,
...事件函数
}
不可以哦,step传进来会覆盖掉e。这时候调用事件处理函数的同时传入事件参数$event,这样就可以用e来接收,接着就可以访问到e.target 。
$event 不能乱写,是固定的
3.双向绑定指令 v-model
只能配合表单元素提起使用使用,<p><div>无效
因为无法让用户输入具体的值。
4. HTML label 标签
MDN Label 文档
你可以点击关联的标签来聚焦或者激活这个输入元素,就像直接点击输入元素一样。这扩大了元素的可点击区域,让包括使用触屏设备在内的用户更容易激活这个元素。
二 . 组件基础
1. vite 创建的项目结构:
2. scipt 的内部节点
2.1 data 节点
data 方法中 return 出去的对象,就是当前组件渲染期间所要用到i的数据对象。
2.2 methods 节点
methods 节点中的 this 指向当前组件的实例,当前组件的数据可以通过 this 访问到。
3. style
支持 less 语法(使用方便,支持定义变量以及实现选择器的嵌套)
<templata>
<h1>这是<i>App.vue</i>的跟组件</h1>
</template>
<style lang="less">
h1{
coclor:red
i{
coclor:blue
}
</style>
4. 组件的使用
4.1 组件的注册(全局和局部)
全局注册 在main.js 中注册
* @param {string} a 注册后在html 中使用的名称,可以以标签的形式直接使用 用kebab-case命名(短横线) 全小写
* @param {string} b 注册组件的名字
app.component('a',b)
局部注册 在被注册组件的vue文件中先引用,再在component 节点中通过键值对的方式添加注册,之后就可以在html 中以标签形式引用。
components:{
'MySearch' : MySearch,
//使用PascalCase命名时,由于键值对中键和值是一样的,因此可以简写为
MySearch, //两者是等价的 标签引用的时候还是<my-search>
}
4.2 组件的命名规则
4.3 组件之间样式冲突 style scoped
定义了父组件中<p>
样式,它会同样渲染到子组件中的<p>
节点中
默认情况下,写在 .vue 组件中的样式会全局生效
,因此很容易造成多个组件之间的样式冲突问题
。导致组件之间样式冲突的根本原因是:
① 单页面应用程序中,所有组件的 DOM 结构,都是基于唯一的 index.html 页面
进行呈现的
② 每个组件中的样式,都会影响整个 index.html 页面
中的 DOM 元素
怎么解决?
为了提高开发效率和开发体验,vue 为 style 节点提供了 scoped
属性,从而防止组件之间的样式冲突问题:
<style scoped>
.....
</style>
4.4 组件样式穿透 :deep( .title
)
//vue3.x版本方法
:deep( .title){
color : blue;
}
4.5 组件的props
为了提高组件的复用性,在封装 vue 组件时需要遵守如下的原则:
⚫ 组件的 DOM 结构、Style 样式
要尽量复用
⚫ 组件中要展示的数据
,尽量由组件的使用者提供
props
是组件的自定义属性
,组件的使用者
可以通过 props 把数据传递到子组件内部
,供子组件内部进行使用。
props 的作用:父组件通过 props 向子组件传递要展示的数据。
props 的好处:提高了组件的复用性。
4.5.1 父子组件
父组件:
在封装 vue 组件时,可以把动态的数据项
声明为 props 自定义属性
。自定义属性可以在当前组件的模板结构中被直接使用。
子组件:(props声明)
4.5.2 动态绑定props的值
4.5.3 props的大小写命名
4.5.4 props验证
使用对象类型
的 props 节点,可以对每个 prop 进行数据类型的校验
,
<my-count :count="1" :state="true"></my-count>
为了保证传入的count的值是数字
而不是字符串,需要在前面加一个:
属性绑定。
props:{
propsA : String, //基本的类型验证
//Number Boolean Array Object Date
// Function(函数类型) Symbol(符号类型)
propsB : [String, Number], //多个可能的类型
propsC : { //必填项
type: String,
required: true
},
propsD : { //属性默认
type: String,
default: abc
},
propsE : { //自定义函数
Validator(value){
//propsE的值必须匹配下列字符串的一个
//return 返回true表示验证通过,false表示验证失败
return['success','warning','danger'].indexof(value)!==-1
}
},
}
5 Class 与 Style 绑定
5.1 动态绑定 HTML 的 class
可以通过三元表达式
,动态的
为元素绑定 class 的类名。示例代码如下:
5.2 以数组语法绑定 HTML 的 class
5.3 以对象语法绑定 HTML 的 class
5.4 以对象语法绑定 HTML 的 class
6 计算属性 computed()
6.1 特点
计算属性本质上就是一个 function 函数,它可以实时监听 data 中数据的变化,并 return 一个计算后的新值,供组件渲染 DOM 时使用。
① 计算属性必须定义在 computed 节点中
② 计算属性必须是一个 function 函数
③ 计算属性必须有返回值
④ 计算属性必须当做普通属性使用
6.2 computer和methods 的区别
相对于方法来说,计算属性会缓存计算的结果
,只有计算属性的依赖项发生变化
时,才会重新进行运算
。因此计算属性的性能更好:
7 自定义事件
7.1 基础
在封装组件时,为了让组件的使用者
可以监听到组件内状态的变化
,此时需要用到组件的自定义事件。
7.2 使用时的三个步骤
在封装组件时:
① 声明自定义事件
开发者为自定义组件封装的自定义事件,必须事先在 emits 节点
中声明
② 触发自定义事件
在 emits 节点下声明的自定义事件,可以通过 this.$emit('自定义事件的名称')
方法进行触发
在使用组件时:
③ 监听自定义事件
在使用自定义的组件时,可以通过 v-on 的形式
监听自定义事件。
7.3 自定义传参
在调用 this.$emit()
方法触发自定义事件时,可以通过第 2 个参数
为自定义事件传参
,
8 v-model 双向绑定
8.1 为什么使用
v-model 是双向数据绑定指令,当需要维护组件内外数据的同步
时,可以在组件上使用 v-model 指令。
⚫ 外界数据的变化
会自动同步到 counter 组件中
⚫ counter 组件中数据的变化
,也会自动同步到外界
8.2 在组件上使用 v-model 的步骤
① 父组件通过 v-bind
: 属性绑定的形式,把数据传递给子组件
② 子组件中,通过 props
接收父组件传递过来的数据
① 在 v-bind: 指令之前添加 v-model
指令
② 在子组件中声明 emits
自定义事件,格式为 update:xxx
③ 调用 $emit()
触发自定义事件,更新父组件中的数据
App组件
<template>
<div>
<h1>App 根组件 ---- {{count}}</h1>
<button @click="count += 1">+1</button>
<hr />
<my-counter v-model:number="count"></my-counter>
</div>
</template>
<script>
import MyCounter from './Counter.vue'
export default {
name: 'MyApp',
data() {
return {
count: 0,
}
},
components: {
MyCounter
}
}
</script>
<style></style>
Counter组件
<template>
<div>
<p>count值是:{{number}}</p>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
name: 'MyCounter',
props: ['number'],
emits: ['update:number'],
methods: {
add() {
this.$emit('update:number', this.number + 1)
}
}
}
</script>
<style></style>