当前位置:   article > 正文

VUE 2 ---->快速入门_vue2

vue2

目录

vue 基础入门

1、解读核心关键词:框架

2、vue 的版本

3、vue 的调试工具

vue 基础入门

 vite 的基本使用

1. 创建 vite 的项目

2. 梳理项目的结构

3. vite 项目的运行流程

组件的基本使用

1. 组件的注册

2. 组件之间的样式冲突问题

3. 组件的 props

4. Class 与 Style 绑定

6、自定义事件

7、组件上的 v-model

组件高级 (上)

1、watch 侦听器

2、组件的生命周期

3、组件之间的数据共享

4、vue 3.x 中全局配置 axios 

组件高级 (下)

1、ref 引用

2、动态组件

3、插槽

4、自定义指令

私有自定义指令

全局自定义指令


vue 基础入门

1、解读核心关键词:框架

官方给 vue 的定位是 前端框架 ,因为它 提供了构建用户界面的一整套解决方案 (俗称 vue 全家桶):
  •  vue(核心库)
  •  vue-router(路由方案)
  •  vuex(状态管理方案)
  •  vue 组件库(快速搭建页面 UI 效果的方案)
以及 辅助 vue 项目开发 的一系列工具:
  •  vue-cli(npm 全局包:一键生成工程化的 vue 项目 - 基于 webpack、大而全)
  •  vite(npm 全局包:一键生成工程化的 vue 项目 - 小而巧)
  •  vue-devtools(浏览器插件:辅助调试的工具)
  •  vetur(vscode 插件:提供语法高亮和智能提示)

2、vue 的版本

vue3.x 和 vue2.x 版本的对比

vue2.x 中 绝大多数的 API 与特性 ,在 vue3.x 中 同样支持 。同时,vue3.x 中还 新增了 3.x 所特有的功能 、并 废弃了某些 2.x 中的旧功能
新增的功能例如:
组合式 API 、多根节点组件、更好的 TypeScript 支持等
废弃的旧功能如下:
过滤器 、不再支持 $on,$off 和 $once 实例方法等
详细的变更信息,请参考官方文档给出的迁移指南: https://v3.vuejs.org/guide/migration/introduction.html

3、vue 的调试工具

vue 2.x 调试工具:

https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
vue 3.x 调试工具:
https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg

vue 基础入门

vue2组件的基本使用

1. 组件的注册

1.1 注册组件的两种方式

  •  全局注册的组件,可以在全局任何一个组件内使用
  •  局部注册的组件,只能在当前注册的范围内使用

1.2 全局注册组件

mian.js使用 app.component() 方法注册的全局组件, 直接以标签的形式进行使用 即可
  1. app.component('注册标签',导入组件名)
1.3 局部注册组件


通过component节点 为当前组件注册

1.4 组件注册时名称的大小写

在进行组件的注册时,定义组件注册名称的方式有两种:

使用 kebab-case 命名法 俗称 短横线命名法
使用 PascalCase 命名法俗称 帕斯卡命名法 大驼峰命名法

2. 组件之间的样式冲突问题

style 节点的 scoped 属性
vue 为 style 节点 提供了 scoped 属性,从而防止组件之间的样式冲突问题
/deep/ 样式穿透
如果给当前组件的 style 节点添加了 scoped 属性,则 当前组件的样式对其子组件是不生效的 。如果想让某些样 式对子组件生效,可以使用 /deep/ 深度选择器
注意: /deep/ 是 vue2.x 中实现样式穿透的方案。在 vue3.x 中推荐使用 :deep() 替代 /deep/。

3. 组件的 props

props 是 组件的 自定义属性 ,组件的 使用者 可以通过 props 把数据传递到子组件内部 ,供子组件内部进行使 用
  • props 的作用:父组件通过 props 向子组件传递要展示的数据
  • props 的好处:提高了组件的复用性
 在组件中声明 props
在封装 vue 组件时,可以把 动态的数据项 声明为 props 自定义属性。自定义属性可以在当前组件的模板结构 中被直接使用。
动态绑定 props 的值
可以使用 v-bind 属性绑定 的形式,为组件动态绑定 props 的值
props 验证
使用 对象类型 的 props 节点,可以对每个 prop 进行 数据类型的校验
基础的类型检查
多个可能的类型
必填项校验
属性默认值
自定义验证函数
如果某个 prop 属性值的 类型不唯一 ,此时可以通过数组的形式,为其指定多个可能的类型
可以通过 default 来 定义属性的默认值 
可以通过 type 来 定义属性的值类型 。
可以通过 required 选项,将属性设置为 必填项 ,强制用户必须传递属性的值
在封装组件时,可以为 prop 属性指定 自定义的验证函数 ,从而 对 prop 属性的值进行更加精确的控制
 

4. Class 与 Style 绑定

在实际开发中经常会遇到 动态操作元素样式 的需求。因此,vue 允许开发者通过 v-bind 属性绑定指令,为元 素动态绑定 class 属性的值 行内的 style 样式
动态绑定 HTML 的 class
可以通过 三元表达式 动态的为元素绑定 class 的类名
数组语法 绑定 HTML 的 class
如果元素需要动态 绑定多个 class 的类名,此时可以使用 数组的语法格式
对象语法 绑定 HTML 的 class
使用 数组语法 动态绑定 class 会导致 模板结构臃肿 的问题
对象语法 绑定内联的 style
:style 对象语法 十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象

5、计算属性
计算属性 本质上 就是一个 function 函数 ,它可以 实时监听 data 中数据的变化,并 return 一个计算后的新值 ,供组件渲染 DOM 时使用。
计算属性需要以 function 函数 的形式声明到组件的 computed 选项
① 计算属性 必须定义在 computed 节点中
② 计算属性 必须是一个 function 函数
③ 计算属性 必须有返回值
④ 计算属性 必须当做普通属性使用
计算属性 vs 方法
相对于方法来说, 计算属性会缓存计算的结果 ,只有计算属性的 依赖项发生变化 时,才会 重新进行运算

6、自定义事件

在封装组件时,为了让组件的使用者可以监听到组件内状态的变化,此时需要用到组件的自定义事件

自定义事件的 3 个使用步骤
在封装组件时:
  • 声明自定义事件
  • 触发自定义事件
在使用组件时:
  • 监听自定义事件

开发者为自定义组件封装的自定义事件,必须事先在 emits 节点中声明

emits 节点下声明的自定义事件,可以通过 this.$emit('自定义事件的名称') 方法进行触发

在使用自定义的组件时,可以通过 v-on 的形式 监听自定义事件
自定义事件 传参
在调用 this.$emit() 方法触发自定义事件时,可以通过 第 2 个参数 为自定义事件传参

7、组件上的 v-model

v-model 是双向数据绑定指令,当 需要维护组件内外数据的同步 时,可以在组件上使用 v-model 指令
父向子同步数据
① 父组件通过 v-bind: 属性绑定的形式,把数据传递给子组件
<MyComponent :num="count"></MyComponent>
② 子组件中,通过 props 接收父组件传递过来的数据
props :['num']

子向父同步数据
① 在 v-bind: 指令之前添加 v-model 指令
  1. 父组件中
  2. <MyComponent v-model:num="count">
② 在子组件中声明 emits 自定义事件,格式为 update: xxx
  1. emits: ['update:num'],
③ 调用 $emit() 触发自定义事件,更新父组件中的数据
  1. 子组件中
  2. methods : {
  3. add(){
  4. this.$emit( 'update:num',this.num + 1)
  5. }
  6. }

vue2组件高级 (上)

1、watch 侦听器

watch 侦听器 允许开发者监视数据的变化,从而 针对数据的变化做特定的操作
基本语法
开发者需要 在 watch 节点 下,定义自己的侦听器。
  1. // 所有的侦听器,都应该被定义到 watch 节点下
  2. watch: {
  3. // 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
  4. // 新值在前,旧值在后
  5. username(newVal,oldVal) {
  6. console.log(neVal,oldVal)
  7. }
immediate 选项
默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器 立即被调用 ,则需要使 用 immediate 选项  true
deep 选项
watch 侦听的是一个对象 ,如果 对象中的属性值发生了变化 ,则 无法被监听到 。此时需要使用 deep 选项
如果 只想监听对象中单个属性的变化
  1. // 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
  2. 'info.username'(newVal) {
  3. console.log(newVal)
  4. }
计算属性 vs 侦听器
计算属性和侦听器 侧重的应用场景不同
计算属性侧重于监听 多个值 的变化,最终计算并 返回一个新值
侦听器侧重于监听 单个数据 的变化,最终 执行特定的业务处理,不需要有任何返回值

2、组件的生命周期

组件的生命周期指的是:组件从创建 -> 运行(渲染) -> 销毁的整个过程,强调的是一个时间段

vue 框架 为组件 内置了 不同时刻的 生命周期函数 ,生命周期函数会 伴随着 组件的运行而 自动调用 。例如:
① 当组件 在内存中被创建完毕 之后,会自动调用 created 函数
② 当组件被成功的 渲染到页面上 之后,会自动调用 mounted 函数
③ 当组件 被销毁完毕 之后,会自动调用 unmounted 函数
监听 组件的 更新
当组件的 data 数据更新 之后,vue 会 自动重新渲染组件 的 DOM 结构,从而保证 View 视图 展示的数据和 Model 数据源 保持一致。
当组件被 重新渲染完毕 之后,会自动调用 updated 生命周期函数。

完整的 生命周期图示
可以参考 vue 官方文档给出的“ 生命周期图示 ”,进一步理解组件生命周期执行的过程:
https://www.vue3js.cn/docs/zh/guide/instance.html#生命周期图示

3、组件之间的数据共享

1. 组件之间的关系
在项目开发中,组件之间的关系分为如下 3 种:
① 父子关系
② 兄弟关系
③ 后代关系
2. 父子组件之间的数据共享
父子组件之间的数据共享又分为:
父 -> 子 共享数据
  • 父组件通过 v-bind 属性绑定向子组件共享数据。同时,子组件需要使用 props 接收数据。
子 -> 父 共享数据
  • 子组件通过自定义事件的方式向父组件共享数据。
父 <-> 子 双向数据同步
  • 父组件在使用子组件期间,可以使用 v-model 指令维护组件内外数据的双向同步:

3. 兄弟组件之间的数据共享
兄弟组件之间 实现数据共享的方案是 EventBus 。可以借助于第三方的包 mitt 来创建 eventBus 对象 ,从而实 现兄弟组件之间的数据共享。
1、在项目中运行如下的命令,安装 mitt 依赖包:
npm i mitt@2.1.0 -S
2、在项目中创建公共的 eventBus 模块 如下:
  1. import mitt from 'mitt'
  2. const bus = mitt()
  3. export default bus
3、在数据接收方,调用 bus.on ('事件名称', 事件处理函数) 方法 注册一个自定义事件
  1. import bus from './eventBus.js'
  2. data(){return {}count : 0 }
  3. cerated(){
  4. bus.on('countChange',(count) =>{
  5. this.num = count
  6. })
  7. }
4、在数据发送方,调用 bus.emit ('事件名称', 要发送的数据) 方法 触发自定义事件
  1. import bus from './eventBus.js'
  2. data(){return {}count : 0 }
  3. methods: {
  4. add(){
  5. this.count++
  6. bus.emit('countChange' ,this.count)
  7. }
  8. }
4. 后代关系组件之间的数据共享
后代关系组件之间共享数据,指的是 父节点的组件 向其 子孙组件 共享数据。此时组件之间的嵌套关系比较复杂, 可以使用 provide inject 实现后代关系组件之间的数据共享
父节点的组件可以通过 provide 方法 ,对其 子孙组件 共享数据:
  1. data() {return {color: 'red' } },
  2. provide(){ return{color : this.color } }

子孙节点可以使用 inject 数组,接收父级节点向下共享的数据

inject : ['color']
父节点使用 provide 向下共享数据时,可以结合 computed 函数 向下共享 响应式的数据
  1. // 从vue中按需导入 computed 函数
  2. import { computed } from 'vue'
  3. //使用computed 函数 把数据共享包装为响应式
  4. provide(){ return{color : computed( () => this.color ) } }
如果父级节点共享的是 响应式的数据 ,则子孙节点必须以 .value 的形式进行使用
<h1>子孙组件  {{color.value}}</h1>
5. vuex
vuex 是 终极的 组件之间的数据共享方案。在企业级的 vue 项目开发中,vuex 可以让组件之间的数据共享变得 高 效 清晰 、且 易于维护

4、vue 3.x 中全局配置 axios 

main.js 入口文件中,通过 app.config.globalProperties 全局挂载 axios
  1. import axios from 'axios'
  2. axios.defaults.baseURL = '请求根路径'
  3. app.config.globalProperties.$http = axios

get请求:

  1. methods: {
  2. async getInfo() {
  3. const { data: res } = await this.$http.get('/api/get', {
  4. params: {
  5. name: 'ls',
  6. age: 20,
  7. },
  8. })
  9. console.log(res)
  10. },
  11. }

post请求:

  1. methods: {
  2. async postInfo() {
  3. const { data: res } = await this.$http.post('/api/post', { name: 'zs', age: 20 })
  4. console.log(res)
  5. },
  6. }

vue2 组件高级 (下)

1、ref 引用

ref 用来辅助开发者在 不依赖于 jQuery 的情况下 ,获取 DOM 元素或组件的引用。
每个 vue 的组件实例上,都包含一个 $refs 对象 ,里面存储着对应的 DOM 元素或组件的引用。默认情况下,组件的 $refs 指向一个空对象 。

  1. <template>
  2. <button @click="showThis">打印 this</button> 
  3. </template> 
  4. export default {
  5.  methods: {
  6.  showThis() {
  7.       // this 是当前 App 组件的实例对象
  8.       console.log(this)
  9. }
  10. }


使用 ref 引用 DOM 元素

  1. <h1 ref="myh1">App 根组件</h1>   //ref属性  起名字
  2.     <button @click="showThis">打印 this</button>
  3. export default {
  4.  methods: {
  5.  showThis() {
  6.       // this 是当前 App 组件的实例对象
  7.       console.log(this)
  8.  this.$refs.myh1.style.color = 'red'  //这里的myh1与上面名称对应
  9. }

使用 ref 引用组件实例

  1. //子组件
  2. <template>
  3. <div class="left-container">
  4. <h3>Left 组件 --- {{ count }}</h3>
  5. <button @click="count += 1">+1</button>
  6. <button @click="resetCount">重置</button>
  7. </div>
  8. </template>
  9. <script>
  10. export default {
  11. data() {
  12. return {
  13. count: 0
  14. }
  15. },
  16. methods: {
  17. resetCount() {
  18. this.count = 0
  19. }
  20. }
  21. }
  22. </script>

/父组件中  使用ref属性  为组件添加引用名称

通过this.$refs.引用名称  可以引用组件的实力

  1. <button @click="onReset">重置 Left 组件的 count 值为 0</button>
  2.  
  3.  
  4.   <Left ref="comLeft"></Left>
  5.  
  6.   methods: {
  7. onReset() {
  8.       this.$refs.comLeft.resetCount()
  9.       // this.$refs.comLeft.count = 0
  10.     }
  11. }

控制文本框和按钮的按需切换


通过布尔值 inputVisible 来控制组件中的文本框与按钮的按需切换
当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加 ref 引用,并调用原生 DOM 对象的 .focus() 方法  

组件的 $nextTick(cb) 方法,会把 cb 回调 推迟到下一个 DOM 更新周期之后执行 。通俗的理解是:等组件的 DOM 更新完成之后,再执行 cb 回调函数。从而能保证 cb 回调函数可以操作到最新的 DOM 元素。
 

  1. <input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef" />
  2. <button v-else @click="showInput">展示输入框</button>
  3. export default {
  4. data() {
  5. return {
  6. // 控制输入框和按钮的按需切换;
  7. // 默认值为 false,表示默认展示按钮,隐藏输入框
  8. inputVisible: false
  9. }
  10. },
  11. methods: {
  12. // 点击按钮,展示输入框
  13. showInput() {
  14. // 1. 切换布尔值,把文本框展示出来
  15. this.inputVisible = true
  16. // 2. 让展示出来的文本框,自动获取焦点 引用this.$nextTick(cb) 方法
  17. this.$nextTick(() => {
  18. this.$refs.iptRef.focus()
  19. })
  20. },
  21. showButton() {
  22. this.inputVisible = false
  23. }
  24. }

2、动态组件

动态组件指的是 动态切换组件的显示与隐藏 

实现动态组件渲染

vue 提供了一个内置的 <component> 组件, 专门用来实现动态组件的渲染

  1. <!-- 1. component 标签是 vue 内置的,作用:组件的占位符 -->
  2. <!-- 2. is 属性的值,表示要渲染的组件的名字 -->
  3. <!-- 3. is 属性的值,应该是组件在 components 节点下的注册名称 -->
  4. <button @click="comName = 'Left'">展示 Left</button>
  5. <button @click="comName = 'Right'">展示 Right</button>
  6. <component :is="comName"></component>
  7. data() {
  8. return {
  9. // comName 表示要展示的组件的名字
  10. comName: 'Left'
  11. }
  12. },

当is 指向另外一个组件时原本的组件会被销毁

使用 keep-alive 保持状态
默认情况下,切换动态组件时无法保持组件的状态。此时可以使用 vue 内置的 <keep-alive> 组件保持动态组 件的状态。示例代码如下:

<keep-alive><component :is="comName"></component></keep-alive>

 keep-alive 会把内部的组件进行缓存,而不是销毁组件 
 

3、插槽


插槽 ( Slot )是 vue 为 组件的封装者 提供的能力。允许开发者在封装组件时,把 不确定的 、 希望由用户指定的 部分 定义为插槽

  1. 组件中
  2. <!-- 声明一个插槽区域 -->
  3. <!-- vue 官方规定:每一个 slot 插槽,都要有一个 name 名称 -->
  4. <!-- 如果省略了 slot 的 name 属性,则有一个默认名称叫做 default -->
  5. <slot name="default"></slot>
  1. <Left>
  2. <!-- 默认情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽之中 -->
  3. <!-- 1. 如果要把内容填充到指定名称的插槽中,需要使用 v-slot: 这个指令 -->
  4. <!-- 2. v-slot: 后面要跟上插槽的名字 -->
  5. <!-- 3. v-slot: 指令不能直接用在元素身上,必须用在 template 标签上 -->
  6. <!-- 4. template 这个标签,它是一个虚拟的标签,只起到包裹性质的作用,但是,不会被渲染为任何实质性的 html 元素 -->
  7. <!-- 5. v-slot: 指令的简写形式是 # -->
  8. <template #default>
  9. <p>这是在 Left 组件的内容区域,声明的 p 标签</p>
  10. </template>
  11. </Left>

没有预留插槽的内容会被丢弃

  • 如果在封装组件时 没有预留任何 <slot> 插槽 ,则用户提供的任何 自定义内容 都 会被丢弃

后备内容

  • 封装组件时,可以为预留的 <slot> 插槽提供 后备内容 (默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效

具名插槽

  • 如果在封装组件时 需要预留多个插槽节点 ,则需要为每个 <slot> 插槽指定 具体的 name 名称 。这种 带有具体 名称的插槽 叫做“具名插槽”。
     <slot name="title"></slot>

为具名插槽提供内容

  • 在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的 形式提供其名称。
    1. <template #title>
    2. <h3>一首诗</h3>
    3. </template>

作用域插槽

  • 在封装组件的过程中,可以为预留的 <slot> 插槽绑定 props 数据,这种 带有 props 数据的 <slot> 叫做“ 作用 域插槽 ” 
    <slot name="content" msg="hello vue.js"></slot>
     

使用 v-slot: 的形式,接收作用域插槽对外提供的数据
作用域插槽对外提供的数据对象,可以使用 解构赋值 简化数据的接收过程

  1.  <template #content="scope">
  2. //或者
  3. <template #content="{ msg, user }">

在封装 MyTable 组件的过程中,可以通过作用域插槽把表格每一行的数据传递给组件的使用者

在使用 MyTable 组件时,自定义单元格的渲染方式,并接收作用域插槽对外提供的数据 

4、自定义指令

vue 官方提供了 v-text、v-for、v-model、v-if 等常用的指令。除此之外 vue 还允许开发者自定义指令。

自定义指令的分类

  •  私有自定义指令
  •  全局自定义指令

私有自定义指令

在每个 vue 组件中,可以在 directives 节点下声明私有自定义指令。示例代码如下:

在使用自定义指令时,需要加上 v- 前缀

  1. directives: {
  2. // 定义名为 focus 的指令,指向一个配置对象
  3. focus: {
  4. // 当指令第一次被绑定到元素上的时候,会立即触发 mounted 函数
  5. // 形参中的 el 表示当前指令所绑定到的那个 DOM 对象
  6. mounted(el) {
  7. el.focus()
  8. }
  9. }

全局自定义指令

全局共享的自定义指令需要通过“单页面应用程序的实例对象”进行声明

  1. const app = vue.createApp{}
  2. // 定义名为 v-focus 的指令,指向一个配置对象
  3. app.directives: { 'focus', {
  4. // 当指令第一次被绑定到元素上的时候,会立即触发 mounted 函数
  5. // 形参中的 el 表示当前指令所绑定到的那个 DOM 对象
  6. mounted(el) {
  7. el.focus()
  8. }
  9. }
1、updated 函数
mounted 函数 只在元素 第一次插入 DOM 时被调用 ,当 DOM 更新时 mounted 函数不会被触发。 updated 函数 会在 每次 DOM 更新完成后 被调用。
注意:在 vue2 的项目中使用自定义指令时,【 mounted -> bind 】【 updated -> update
2、函数简写
如果 mounted 和updated 函数中的逻辑完全相同, ,则可以简写成如下格式:
  1. app.directives ( 'focus', (el) => {
  2. el.focus()
  3. })
3、指令的参数值
在绑定指令时,可以通过“ 等号 ”的形式为指令绑定 具体的参数值 , 通过  binding  获取指令的参数值
  1. <h1 v-color="color = 'red'">App 根组件</h1>
  2. app.directives ( 'color',(el,binding) => {
  3. el.style.color = binding.value
  4. })

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/76725
推荐阅读
  

闽ICP备14008679号