# learn-vue3 **Repository Path**: codinglin/learn-vue3 ## Basic Information - **Project Name**: learn-vue3 - **Description**: 学习Vue3 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-03-26 - **Last Updated**: 2023-04-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 学习 Vue3 ### Vue 的特性 1. 数据驱动视图 2. 双向数据绑定 MVVM 是 vue 实现数据驱动视图和双向数据绑定的核心原理。在 MVVM 的概念中,View 表示当前页面所渲染的 DOM 结构,Model 表示当前页面渲染时所依赖的数据源,ViewModel 表示 vue 的实例,它是 MVVM 的核心,它把当前页面的数据源和页面结构连接在了一起。 vue2.x 中的绝大多数的 API 与特性,在 vue3.x 中同样支持。同时,vue3.x 中新增了组合式 API、多根节点组件、更好的 TypeScript 支持等,废弃了过滤器,不再支持 $on, $off 和 $once 实例方法等。 详细的变更信息,参考官方文档给出的迁移指南:[https://vuejs.org/guide/introduction.html](https://vuejs.org/guide/introduction.html) ### Vue 指令与过滤器 #### Vue 指令 指令是 vue 为开发者提供的模版语法,用于辅助开发者渲染页面的基本结构。Vue 中的指令按照用途可以分为如下 6 大类: ##### 1. 内容渲染指令 - v-text `v-text` 会覆盖元素内默认的值 - {{}} 相对于 `v-text` 指令,插值表达式在开发中更常用一些,它不会覆盖元素中默认的文本内容 - v-html `v-text` 指令和插值表达式只能渲染纯文本内容,如果要把包含 HTML 标签的字符串渲染为页面的 HTML 元素,则需用到 `v-html` 这个指令 ##### 2. 属性绑定指令 v-bind 如果需要为元素的属性动态绑定属性值,则需要用到 `v-bind` 属性绑定的指令,可以简写为 `:` ##### 3. 事件绑定指令 v-on `v-on` 用来辅助开发人员为 DOM 元素绑定事件监听,可以简写为 `@`,在 `v-on` 指令所绑定的事件处理函数中,同样可以接收到事件对象 event。 `$event` 是 vue 提供的特殊变量,用来表示原生的事件参数对象 `event`。 在事件处理函数中调用 `preventDefault()` 或 `stopPropagation()` 是非常常见的需求。因此 vue 提供了事件修饰符的概念,来辅助开发人员更方便的对事件的触发进行控制。常见的 5 个事件修饰符如下: > - `.prevent` 阻止默认行为(如阻止 a 链接的跳转、阻止表单的提交等) > > - `.stop` 阻止事件冒泡 > > - `.capture` 以捕获模式触发当前的事件处理函数 > > - `.once` 绑定的事件只触发一次 > > - `.self` 只有在 `event.target` 是当前元素自身时触发事件处理函数 ##### 4. 双向绑定指令 v-model 用来辅助开发者在不操作 DOM 的前提下,快速获取表单的数据,`v-model` 指令只能配合表单元素一起使用 为了方便对用户输入的内容进行处理,vue 为 `v-model` 指令提供了 3 个修饰符,分别是: > - `.number` 自动将用户的输入值转为数值类型 > > - `.trim` 自动过滤用户输入的首尾空白字符串 > > - `.lazy` 在 change 时而非 input 时更新 ##### 5. 条件渲染指令 v-if `v-if` 指令会动态地创建或移除 DOM 元素,从而控制元素在页面上的显示与隐藏,`v-if` 有更高的切换开销 v-show `v-show` 指令会动态为元素添加或移除 `style="display:none;"` 样式,从而控制元素的显示与隐藏,`v-show` 有更高的初始渲染开销 ##### 6. 列表渲染指令 v-for `v-for` 指令需要使用 `item in items` 的特殊语法,其中 `items` 是待循环的数组,`item` 是当前的循环项 `key` 的值只能是字符串或数字类型,必须具有唯一性,使用 `index` 作为 `key` 没有任何意义 #### 过滤器 过滤器常用于文本的格式化,可用在插值表达式和 `v-bind` 属性绑定: ```js // 在双花括号中通过管道符调用 capitalize 过滤器,对 message 的值进行格式化

{{ message | capitalize }}

// 在 v-bind 中通过管道符调用 formatId 过滤器,对 rawId 的值进行格式化
``` 在创建 vue 实例期间,可以在 `filters` 节点中定义过滤器,如下: ```js const app = new Vue({ el: #app, data: {...}, filters: { capitalize(str) { // 把首字母转为大写的过滤器 return str.charAt(0).toUpperCase() + str.slice(1) } } }) ``` 在 filters 节点下定义的过滤器,称为**私有过滤器**,如果希望在多个 vue 实例之间共享过滤器,则可以按照如下的格式定义**全局过滤器**: ```js Vue.filter("capitalize", (str) => { return str.chatAt(0).toUpperCase() + str.slice(1); }); ``` 连续调用多个过滤器,示例如下: ```js // 串联调用多个过滤器

{{text | capitalize | maxLength}}

``` 过滤器的本质是 JavaScript 函数,因此可以接收参数,格式如下: ```js

{{message | filterA(arg1, arg2)}}

// 第一个参数是管道符前面待处理的值 // 之后的是调用过滤器传递过来的参数 Vue.filter('filterA', (msg, arg1, arg2) => { ... }) ``` 过滤器仅在 vue2.x 和 1.x 中支持,vue3.x 中删除了过滤器,官方建议使用**计算属性**或**方法**代替过滤器。 ### 单页面应用程序 单页面应用程序(Single Page Application)简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。 特点:单页面应用程序将所有的功能局限于一个 web 页面中,仅在该 web 页面初始化时加载相应的资源。一旦页面加载完成了,SPA 不会因为用户的操作而进行页面的重新加载或跳转,而是利用 JavaScript 动态地变换 HTML 的内容,从而实现页面与用户的交互。 优点: 1. 良好的交互体验 2. 良好的前后端工作分离模式 3. 减轻服务器压力 缺点: 1. 首屏加载慢 可以通过路由懒加载、代码压缩、CDN 加速、网络传输压缩等解决 2. 不利于 SEO 可以通过 SSR 服务端渲染解决 ### 创建 vite 项目 基于 vite 创建 vue3.x 的工程化项目: ``` npm init vite-app 项目名称 cd 项目名称 npm install or yarn npm run dev or yarn dev ``` #### 使用全局注册组件 使用 `app.component()` 方法注册的全局组件,直接以标签的形式使用即可: ```js // main.js import { createApp } from "vue"; import App from "./App.vue"; // 1. 导入 MySwiper 组件 import MySwiper from "./component/MySwiper.vue"; const app = createApp(App); // 2. 调用 app 实例的 component() 方法,全局注册 my-swiper 组件 app.component("my-swiper", MySwiper); app.mount("#app"); ``` ```vue // 在其他组件中,直接以标签的形式使用注册的全局组件 ``` #### style 节点的 scoped 属性 为了提高开发效率和开发体验,vue 为 style 节点提供了 scoped 属性,从而防止组件之间的样式冲突问题。 #### /deep/ 样式穿透 如果给当前组件的 style 节点添加了 scoped 属性,则当前组件的样式对其子组件是不生效的。如果想让某些样式对子组件生效,可以使用 `/deep/` 深度选择器。 ```less /deep/ .title { color: blue; } ``` 注意:`/deep/` 是 vue2.x 中实现样式穿透的方案。在 vue3.x 中推荐使用 `:deep()`。 #### props `props` 是组件的自定义属性,组件的使用者可以通过 `props` 把数据传递到子组件内部,供子组件使用。 `props` 的作用:父组件通过 `props` 向子组件传递要展示的数据 `props` 的好处:提高了组件的复用性 ```vue ``` #### props 验证 使用对象类型的 `props` 节点,可以对每个 `props` 进行数据类型的校验,示例如下: ```js export default { props: { title: String, author: String, }, }; ``` 如果某个 `prop` 属性值类型不唯一,此时可以通过数组的形式为其指定多个可能的类型,示例如下: ```js export default { props: { propA: [String, Number], }, }; ``` 如果组件的某个 `prop` 属性是必填项,必须让组件的使用者为其传递属性的值。示例如下: ```js export default { props: { propB: { type: String, required: true, }, }, }; ``` 在封装组件时,可以为某个 `prop` 属性指定默认值。示例如下: ```js export default { props: { propC: { type: Number, default: 100, }, }, }; ``` 在封装组件时,可以为 `prop` 属性指定自定义的验证函数,从而对 `prop` 属性的值进行更加精确的控制。示例如下: ```js export default { props: { propD: { // 通过 validator 函数,对 propD 属性的值进行校验 validator(value) { // validator 函数返回值为 true 表示验证通过,false 表示验证失败 return ["success", "warning", "danger"].indexOf(value) !== 1; }, }, }, }; ``` ### 计算属性 计算属性本质上就是一个 function 函数,它可以实时监听 data 中的数据变化,并 return 一个计算后的新值,供组件渲染 DOM 时使用。 计算属性的使用注意点: 1. 计算属性必须定义在 computed 节点中 2. 计算属性必须是一个 function 函数 3. 计算属性必须有返回值 4. 计算属性必须当做普通属性使用 相对于方法来说,计算属性会缓存计算的结果,只有计算属性的依赖项发生变化时,才会重新进行计算。 ### 自定义事件 在封装组件时,为了让组件的使用者可以监听到组件内状态的变化,此时需要用到组件的自定义事件 自定义事件的使用步骤: 在封装组件时:1. 声明自定义事件 2. 触发自定义事件 在使用组件时:3. 监听自定义事件 开发者为自定义组件封装的自定义事件,必须事先在 `emits` 节点中声明,示例如下: ```js export default { emits: ["change"], }; ``` 在 emits 节点下声明的自定义事件,可以通过 `this.$emit()` 方法进行触发,示例如下: ```vue ``` 在使用自定义组件时,可以通过 `v-on` 的形式监听自定义事件,示例如下: ```js methods: { getCount() { console.log('监听到了 count 的变化'); } } ``` 在调用 `this.$emit()` 方法触发自定义事件时,可以通过第 2 个参数为自定义事件传参,示例如下: ```vue ```