[TOC]

注:使用vite+vue3.0搭建项目

常见问题解决

core-js@2.6.12: core-js@<3.4

因为vue cli 升级至v4后,将内部的core-js依赖升级到v3,所以需要我们给core-js做一个升级 npm install -g core-js@3.1.1也可以npm install core-js -g(v3以上的都行,目前发布到3.6.5),或者改一下 nuxt.config.js 中的配置 。为什么升级呢?因为vue cli中nuxt.js默认依赖的是core-js 2。
原文链接:https://blog.csdn.net/weixin_45527702/article/details/108105646

vue路由mode模式:history与hash的区别

前端工程化与 webpack

webpack 的基本使用

  1. 什么是 webpack
    概念:webpack 是前端项目工程化的具体解决方案。
    主要功能:它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览器端 JavaScript 的兼容性、性
    能优化等强大的功能。
    好处:让程序员把工作的重心放到具体功能的实现上,提高了前端开发效率和项目的可维护性。
    注意:目前 Vue,React 等前端项目,基本上都是基于 webpack 进行工程化开发的。

    Vue

    推荐大家安装的 VScode 中的 Vue 插件

  2. Vue 3 Snippets https://marketplace.visualstudio.com/items?itemName=hollowtree.vue-snippets

  3. Vetur https://marketplace.visualstudio.com/items?itemName=octref.vetur
  4. vue插件
  5. Vue VSCode Snippets // 快速构建组件

    Vetur // 识别单文件组件高亮
    Vue // 先下着把….
    Path Intellisense // 路径提示
    Prettier - Code formatter // 代码格式化
    ESLint // 代码风格检查
    创建 .prettierrc 文件

{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none"
}
    底部的 Eslin 要启用  选择  Allow anywhere<br />        右键选择格式化的方式,默认是 Vetur,选择 Prettier<br />        修改 .eslintrc.js 文件<br />        如果你不需要它报一些错就直接复制那个错误的提示,设置值为0即可
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
     // 把报错的信息复制过来赋值为0
    'no-unused-vars': 0
  }

什么是 vue

  1. 构建用户界面
    • 用 vue 往 html 页面中填充数据,非常的方便
  2. 框架

    • 框架是一套现成的解决方案,程序员只能遵守框架的规范,去编写自己的业务功能!
    • 要学习 vue,就是在学习 vue 框架中规定的用法!
    • vue 的指令、组件(是对 UI 结构的复用)、路由、Vuex、vue 组件库
    • 只有把上面老师罗列的内容掌握以后,才有开发 vue 项目的能力!

      vue 的两个特性

  3. 数据驱动视图:

    • 数据的变化会驱动视图自动更新
    • 好处:程序员只管把数据维护好,那么页面结构会被 vue 自动渲染出来!
  4. 双向数据绑定:

    在网页中,form 表单负责采集数据,Ajax 负责提交数据

    • js 数据的变化,会被自动渲染到页面上
    • 页面上表单采集的数据发生变化的时候,会被 vue 自动获取到,并更新到 js 数据中

      注意:数据驱动视图和双向数据绑定的底层原理是 MVVM(Mode 数据源、View 视图、ViewModel 就是 vue 的实例)

vue 指令

image.png

1. 内容渲染指令

  1. v-text 指令的缺点:会覆盖元素内部原有的内容!
  2. {{ }} 插值表达式:在实际开发中用的最多,只是内容的占位符,不会覆盖原有的内容!
  3. v-html 指令的作用:可以把带有标签的字符串,渲染成真正的 HTML 内容! ```html <!DOCTYPE html>

性别:


姓名:{{ username }}

性别:{{ gender }}


{{ info }}

<a name="x0NOB"></a>
### 2. 属性绑定 v-bind 简写 :
> 注意:插值表达式只能用在元素的**内容节点**中,不能用在元素的**属性节点**中!

-  在 vue 中,可以使用 `v-bind:` 指令,为元素的属性动态绑定值; 
-  简写是英文的 `:` 
-  在使用 v-bind 属性绑定期间,如果绑定内容需要进行动态拼接,则字符串的外面应该包裹单引号,例如:  
```xml
<div :title="'box' + index">这是一个 div</div>

3. 事件绑定 v-on 简写 @

<button @click="add"></button>

methods: {
   add() {
            // 如果在方法中要修改 data 中的数据,可以通过 this 访问到
            this.count += 1
   }
}

事件对象$event

$event 的应用场景:如果默认的事件对象 e 被覆盖了,则可以手动传递一个 $event。例如:

<button @click="add(3, $event)"></button>

methods: {
   add(n, e) {
            // 如果在方法中要修改 data 中的数据,可以通过 this 访问到
            this.count += 1
   }
}

事件修饰符

  • .prevent 阻止默认行为(例如:阻止 a连接的跳转、阻止表单的提交等)

    <a @click.prevent="xxx">链接</a>
    
  • .stop 阻止事件冒泡

    <button @click.stop="xxx">按钮</button>
    

    | 事件修饰符 | 说明 | | —- | —- | | .prevent | 阻止默认行为(例如:阻止 a连接的跳转、阻止表单的提交等) | | .stop | 阻止事件冒泡 | | .capture | 以捕获模式触发当前的事件处理函数 | | .once | 绑定的事件只触发1次 | | .self | 只有在 event.target是当前元素自身时触发事件处理函数 |

按键修饰符

在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符,例如:

<!-- 只有在'key'是 'Enter'时调用函数'vm.submit()' -->
<input @keyup.enter="submit">

<!-- 只有在'key'是'Esc'时调用函数'vm.clearInput()' -->
<input @keyup.esc="clearInpt">

4. v-model 双向数据绑定

<!DOCTYPE html>
<html lang="en">
<body>
  <!-- 希望 Vue 能够控制下面的这个 div,帮我们在把数据填充到 div 内部 -->
  <div id="app">
    <select v-model="city">
      <option value="">请选择城市</option>
      <option value="1">北京</option>
      <option value="2">上海</option>
      <option value="3">广州</option>
    </select>
  </div>

  <script src="./lib/vue-2.6.12.js"></script>
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        city: '2'
      }
    })
  </script>
</body>
</html>

v-model指令的修饰符

修饰符 作用 示例
.number 自动将用户的输入值转为数值类型
.trim 自动过滤用户输入的首尾空白字符
.lazy 在“change”时而非“input”时更新

5. 条件渲染指令

  1. v-show 的原理是:动态为元素添加或移除 display: none 样式,来实现元素的显示和隐藏
    • 如果要频繁的切换元素的显示状态,用 v-show 性能会更好
  2. v-if 的原理是:每次动态创建或移除元素,实现元素的显示和隐藏
    • 如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时 v-if 性能更好

      在实际开发中,绝大多数情况,不用考虑性能问题,直接使用 v-if 就好了!!!

v-if 指令在使用的时候,有两种方式:

  1. 直接给定一个布尔值 true 或 false

    <p v-if="true">被 v-if 控制的元素</p>
    
  2. 给 v-if 提供一个判断条件,根据判断的结果是 true 或 false,来控制元素的显示和隐藏

    <p v-if="type === 'A'">良好</p>
    

    注意:v-else指令必须配合 v-if指令一起使用,否则它将不会被识别!

    应用案例

    ```html <!DOCTYPE html>

这是被 v-if 控制的元素

这是被 v-show 控制的元素


优秀
良好
一般
<a name="tuaIL"></a> ### 6.列表渲染指令 `v-for` 1. 建议使用 v-for指令时一定要指定 key的值(既提升性能、又防止列表状态紊乱) 1. key的值只能是**字符串**或**数字**类型 1. key的值必须具有唯一性(即:key的值不能重复) 1. 建议把数据项 **id属性**的值作为 key的值(因为 id属性的值具有唯一性) 1. 使用 index的值当作 key的值没有任何意义(因为 index的值不具有唯一性) 1. <!-- key 的值是**不能重复的**,否则会终端报错:Duplicate keys detected -->html
索引 Id 姓名
{{ index }} {{ item.id }} {{ item.name }}
<a name="u25fz"></a> #### Label的for属性 增强用户使用体验html
<a name="Oa2N7"></a> ## 过滤器 (vue3不再支持) <a name="DPWLZ"></a> ### 1.基本使用 过滤器(Filters)是 vue为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式<br />和 v-bind属性绑定。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21728297/1643991578522-f2d006ec-4640-4bce-b56e-340bed1e32a5.png#clientId=u0fd0488c-2954-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=112&id=u43845436&margin=%5Bobject%20Object%5D&name=image.png&originHeight=140&originWidth=674&originalType=binary&ratio=1&rotation=0&showTitle=false&size=49333&status=done&style=none&taskId=u3ba70a01-7a4e-42da-afd0-54d8be0bd30&title=&width=539.2)<br />连续调用<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21728297/1643991676761-38492944-e349-4890-ba33-fe60e981a5fc.png#clientId=u0fd0488c-2954-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=97&id=u782b14f9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=121&originWidth=486&originalType=binary&ratio=1&rotation=0&showTitle=false&size=39722&status=done&style=none&taskId=u3a0844f5-6f5b-4545-a027-79864501beb&title=&width=388.8)html

message 的值是:{{ message | capi }}

<a name="CQfNz"></a> ### 2.私有过滤器和全局过滤器 在 filters节点下定义的过滤器,称为“私有过滤器”,因为它只能在当前 vm实例所控制的 el区域内使用。<br />如果希望在多个 vue实例之间共享过滤器,则可以按照如下的格式定义全局过滤器:html <!DOCTYPE html>

message 的值是:{{ message | capi }}

message 的值是:{{ message | capi }}

<a name="KYbd4"></a>
### 3.过滤器传参
过滤器的本质是 JavaScript函数,因此可以接收参数,格式如下:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21728297/1643992150564-b0535fbc-9ee7-4c64-9f39-8e2904c73b38.png#clientId=uf965739d-0c6d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=243&id=ue1423a5a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=304&originWidth=647&originalType=binary&ratio=1&rotation=0&showTitle=false&size=86743&status=done&style=none&taskId=u4709d304-2e07-45a4-8808-a741e9a4e45&title=&width=517.6)![image.png](https://cdn.nlark.com/yuque/0/2022/png/21728297/1643992182751-f14f88b7-ed14-4607-b7d9-f76417a96bc2.png#clientId=uf965739d-0c6d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=341&id=u222c96a4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=426&originWidth=629&originalType=binary&ratio=1&rotation=0&showTitle=false&size=80656&status=done&style=none&taskId=u1174dcc2-5460-4145-b485-4fe5b35a911&title=&width=503.2)
<a name="Q6oqk"></a>
## 侦听器
watch侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21728297/1643992418974-dcc5fb24-0bfc-48a5-91ed-6e9b8fb33fa8.png#clientId=uf965739d-0c6d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=298&id=u44870ef2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=373&originWidth=698&originalType=binary&ratio=1&rotation=0&showTitle=false&size=57912&status=done&style=none&taskId=u784b1ae6-43d7-479b-9b9b-a03ead14519&title=&width=558.4)<br />监听 username值的变化,并使用 axios发起 Ajax请求,检测当前输入的用户名是否可用:
```html
watch: {
    //监听 username值的变化
    async username(newVal) {
        if (newVal === '') return
        //使用 axios发起请求,判断用户名是否可用
        const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal)
        console.log(res)
    }
}

immediate选项

image.png

deep选项

如果 watch侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用 deep选
项,代码示例如下:

<body>
  <div id="app">
    <input type="text" v-model="info.username">
    <input type="text" v-model="info.address.city">
  </div>

  <script src="./lib/vue-2.6.12.js"></script>
  <script src="./lib/jquery-v3.6.0.js"></script>

  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        // 用户的信息对象
        info: {
          username: 'admin',
          address: {
            city: '北京'
          }
        }
      },
      // 所有的侦听器,都应该被定义到 watch 节点下
      watch: {
        /* info: {
          handler(newVal) {
            console.log(newVal)
          },
          // 开启深度监听,只要对象中任何一个属性变化了,都会触发“对象的侦听器”
          deep: true
        } */
        // 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
        'info.username'(newVal) {
          console.log(newVal)
        }
      }
    })
  </script>
</body>

计算属性

计算属性指的是通过一系列运算之后,最终得到一个属性值。
这个动态计算出来的属性值可以被模板结构或 methods方法使用。示例代码如下:
image.png
计算属性的特点
① 虽然计算属性在声明的时候被定义为方法,但是计算属性的本质是一个属性
② 计算属性会缓存计算的结果,只有计算属性依赖的数据变化时,才会重新进行运算

使用axios代替ajax发送请求

vue-cli

vue-cli是 Vue.js开发的标准工具。它简化了程序员基于 webpack创建工程化的 Vue项目的过程。
引用自 vue-cli官网上的一句话:
程序员可以专注在撰写应用上,而不必花好几天去纠结 webpack配置的问题。
中文官网:https://cli.vuejs.org/zh/

安装和使用

vue-cli是 npm上的一个全局包,使用 npm install命令,即可方便的把它安装到自己的电脑上:
npm install -g @vue/cli
版本查看vue -V , vue --version

基于 vue-cli快速生成工程化的 Vue项目:
vue create 项目的名称
image.png
参考连接
vue-cli项目的目录结构
image.png
index.html单一页面 <div id="app"></div>
babel.config.jsimage.png
assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源
components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下
main.js 是项目的入口文件。整个项目的运行,要先执行 main.js
App.vue 是项目的根组件。

vue项目的运行流程

在工程化的项目中,vue要做的事情很单纯:通过 main.js把 App.vue渲染到 index.html的指定区域中。
其中:
① App.vue用来编写待渲染的模板结构
② index.html中需要预留一个 el区域
③ main.js把 App.vue渲染到了 index.html所预留的区域中

vue组件的三个组成部分
每个 .vue组件都由 3部分构成,分别是:
 template ->组件的模板结构
 script ->组件的 JavaScript行为
 style ->组件的样式
其中,每个组件中必须包含 template模板结构,而 script行为和 style样式是可选的组成部分。

main.js引入.vue

// 导入vue包到vue
import Vue from 'vue'

// 导入App.vue到APP
import Test from './Test.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(Test),
}).$mount('#app')  // .$mount('#app') == el: '#app',

// new Vue({
//   el: '#app',
//   render: h => h(Test),
// })

组件模板

<template>
  <div class="test-container">
    <h3 id="myh3">Test.vue 组件 --- {{ books.length }} 本图书</h3>
    <p id="pppp">message 的值是:{{ message }}</p>
    <button @click="message += '~'">修改 message 的值</button>
  </div>
</template>

<script>
  //固定写法
export default {
  props: ['info'],
  //组件中的data 必须是一个函数
  data() {
    return {
      message: 'hello vue.js',
      // 定义 books 数组,存储的是所有图书的列表数据。默认为空数组!
      books: []
    }
}
</script>

    //引入 less
<style lang="less" scoped>
.test-container {
  background-color: pink;
  height: 200px;
}
</style>

组件的注册

image.png

注册全局组件

image.png

组件的 props

props 是只读的
image.png
使用自定义属性

props 的

在声明自定义属性时,可以通过 default 来定义属性的默认值 。
在声明自定义属性时,可以通过 type 来定义属性的值类型。
在声明自定义属性时,可以通过 required 选项,将属性设置为必填项,强制用户必须传递属性的值
require: true(加在type: number 下面)
image.png

scoped 防止组件间的样式冲突