VUE3---->基础入门

目录

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 基础入门

参考之前笔记
vue 基础入门icon-default.png?t=N6B9https://blog.csdn.net/ClearloveYt/article/details/131478972?spm=1001.2014.3001.5502#t0

 vite 的基本使用

1. 创建 vite 的项目

按照顺序执行如下的命令,即可基于 vite 创建 vue 3.x 的工程化项目:
npm init vite-app 项目名称

> cd 项目名称
> npm install
> npm run dev

2. 梳理项目的结构

  •  node_modules 目录用来存放第三方依赖包
  •  public 是公共的静态资源目录
  •  src 是项目的源代码目录(程序员写的所有代码都要放在此目录下)
  •  .gitignore 是 Git 的忽略文件
  •  index.html 是 SPA 单页面应用程序中唯一的 HTML 页面
  •  package.json 是项目的包管理配置文件
  •  assets 目录用来存放项目中所有的静态资源文件(css、fonts等)
  •  components 目录用来存放项目中所有的自定义组件
  •  App.vue 是项目的根组件
  •  index.css 是项目的全局样式表文件
  •  main.js 是整个项目的打包入口文件

3. vite 项目的运行流程

在工程化的项目中,vue 要做的事情很单纯:通过 main.js App.vue 渲染到 index.html 的指定区域中。 其中:
  1.  App.vue 用来编写待渲染的模板结构
  2.  index.html 中需要预留一个 el 区域
  3.  main.js 把 App.vue 渲染到了 index.html 所预留的区域中
    // 1. 按需导入 createApp 函数
    import { createApp } from 'vue'
    
    // 2. 导入待渲染的 App.vue 组件
    import App from './App.vue'
    
    / 3. 调用 createApp 函数,创建 SPA 应用的实例
    const app = createApp(App)
    
    // 4. 调用 mount() 把 App 组件的模板结构,渲染到指定的 el 区域中
    app.mount('#app')
    

组件的基本使用

1. 组件的注册

1.1 注册组件的两种方式

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

1.2 全局注册组件

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

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: 属性绑定的形式,把数据传递给子组件
② 子组件中,通过 props 接收父组件传递过来的数据
props :['num']

子向父同步数据
① 在 v-bind: 指令之前添加 v-model 指令
父组件中

② 在子组件中声明 emits 自定义事件,格式为 update: xxx
 
emits: ['update:num'],
③ 调用 $emit() 触发自定义事件,更新父组件中的数据
子组件中
methods : {
add(){
this.$emit( 'update:num',this.num + 1)
}
}

组件高级 (上)

1、watch 侦听器

watch 侦听器 允许开发者监视数据的变化,从而 针对数据的变化做特定的操作
基本语法
开发者需要 在 watch 节点 下,定义自己的侦听器。
// 所有的侦听器,都应该被定义到 watch 节点下
      watch: {
        // 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
        // 新值在前,旧值在后
        username(newVal,oldVal) {
         console.log(neVal,oldVal)
         
        }
immediate 选项
默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器 立即被调用 ,则需要使 用 immediate 选项  true
deep 选项
watch 侦听的是一个对象 ,如果 对象中的属性值发生了变化 ,则 无法被监听到 。此时需要使用 deep 选项
如果 只想监听对象中单个属性的变化
// 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
        'info.username'(newVal) {
          console.log(newVal)
        }
计算属性 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 [email protected] -S
2、在项目中创建公共的 eventBus 模块 如下:
import mitt from 'mitt'

const bus = mitt()

export default bus
3、在数据接收方,调用 bus.on ('事件名称', 事件处理函数) 方法 注册一个自定义事件
import bus from './eventBus.js'

data(){return {}count : 0 }
cerated(){
   bus.on('countChange',(count) =>{
   this.num = count
})
}
4、在数据发送方,调用 bus.emit ('事件名称', 要发送的数据) 方法 触发自定义事件
import bus from './eventBus.js'

data(){return {}count : 0 }

methods: {
   add(){
this.count++ 
bus.emit('countChange' ,this.count)
}
}
4. 后代关系组件之间的数据共享
后代关系组件之间共享数据,指的是 父节点的组件 向其 子孙组件 共享数据。此时组件之间的嵌套关系比较复杂, 可以使用 provide inject 实现后代关系组件之间的数据共享
父节点的组件可以通过 provide 方法 ,对其 子孙组件 共享数据:
data() {return {color: 'red' } },
provide(){ return{color : this.color } }

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

inject : ['color']
父节点使用 provide 向下共享数据时,可以结合 computed 函数 向下共享 响应式的数据
// 从vue中按需导入 computed 函数
import { computed } from 'vue'
//使用computed 函数 把数据共享包装为响应式
provide(){ return{color : computed( () => this.color ) } }
如果父级节点共享的是 响应式的数据 ,则子孙节点必须以 .value 的形式进行使用

子孙组件 {{color.value}}

5. vuex
vuex 是 终极的 组件之间的数据共享方案。在企业级的 vue 项目开发中,vuex 可以让组件之间的数据共享变得 高 效 清晰 、且 易于维护

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

main.js 入口文件中,通过 app.config.globalProperties 全局挂载 axios
import axios from 'axios'


axios.defaults.baseURL = '请求根路径'

app.config.globalProperties.$http = axios

get请求:

  methods: {
    async getInfo() {
      const { data: res } = await this.$http.get('/api/get', {
        params: {
          name: 'ls',
          age: 20,
        },
      })

      console.log(res)
    },
  }

post请求:

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

组件高级 (下)

1、ref 引用

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

 
export default {
 methods: {
 showThis() {
      // this 是当前 App 组件的实例对象
      console.log(this)
   }
}


使用 ref 引用 DOM 元素

App 根组件

  //加ref属性  起名字     export default {  methods: {  showThis() {       // this 是当前 App 组件的实例对象       console.log(this)  this.$refs.myh1.style.color = 'red'  //这里的myh1与上面名称对应 }  }

使用 ref 引用组件实例

//子组件
 

 

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

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


 
 
  
 
  methods: {
onReset() {
      this.$refs.comLeft.resetCount()
      // this.$refs.comLeft.count = 0
    }
}

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


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

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

 
    
    
export default {
  data() {
    return {
      // 控制输入框和按钮的按需切换;
      // 默认值为 false,表示默认展示按钮,隐藏输入框
      inputVisible: false
    }
  },
 methods: {
    // 点击按钮,展示输入框
    showInput() {
      // 1. 切换布尔值,把文本框展示出来
      this.inputVisible = true
      // 2. 让展示出来的文本框,自动获取焦点 引用this.$nextTick(cb) 方法
      this.$nextTick(() => {
        this.$refs.iptRef.focus()
      })
    },
showButton() {
      this.inputVisible = false
    }
}

2、动态组件

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

实现动态组件渲染

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

 
 
 
 
 
 
data() {
    return {
      // comName 表示要展示的组件的名字
      comName: 'Left'
    }
  },

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

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

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

3、插槽


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

组件中

    
    

 
        
        
        
        
        


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

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

后备内容

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

具名插槽

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

为具名插槽提供内容

  • 在向具名插槽提供内容的时候,我们可以在一个