首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【前端】Vue2一本通 & ESLint & JSX

  • 25-04-24 15:01
  • 3739
  • 9313
blog.csdn.net

近几天更新完毕,不定期持续更新,建议关注收藏点赞。


目录

  • 工具推荐
    • vscode插件
    • vue-devtools
    • ESLint
  • JSX语法扩展
  • 简介
    • 设计模式
    • 快速入门
  • @vue/cli脚手架
  • 使用
    • vue指令

这里主要是了解vue2,会提到vue3与其对比,但不一定很全,想了解vue3的全部请访问另一个笔记。点击跳转

工具推荐

工欲善其事,必先利其器。

vscode插件

Vetur:vue代码高亮插件
VueHelper:代码提示插件

vue-devtools

vue-devtools 是一个专门为 Vue.js 开发者打造的 浏览器开发者工具插件,可以用来 调试、查看和修改 Vue 应用的内部状态。
简单来说,它就像给 Vue 应用装了个“透视眼”,让你能轻松看到组件之间是怎么工作的。

  • vue-devtools 能干嘛?【5点】
    查看组件结构:类似一棵树,展示你的应用是由哪些组件组成的,谁嵌套谁。你可以直接点进每个组件,看到它的名字、props、data、computed 等。
    实时查看和修改数据:能看到组件当前的数据(data、props、computed)。修改数据还能立刻看到页面更新,适合调试。
    事件追踪:查看哪个组件发出了哪个自定义事件($emit)。可以看到事件的名字、参数、传播链等。
    Vuex 调试(如果你用了 Vuex):查看 Vuex 的 state、getters、mutations、actions。
    时间旅行调试(Time Travel Debugging):可以前进后退查看状态变化。
    性能检测(性能分析标签页):查看组件的更新频率、渲染开销,找出性能瓶颈。
  • 安装
    Chrome 插件商店搜索 vue-devtools 安装。或者在 Firefox 也可以装。
    如果是开发桌面应用或在本地调试,Vue 官方还提供了独立版(Electron 应用)。
  • 使用
    确保你的 Vue 应用在开发模式Vue 在生产模式下默认关闭调试信息,vue-devtools 可能检测不到。所以开发时要确保没有 Vue.config.productionTip = false 或类似压缩优化设置。

ESLint

它是一个代码检查工具,用于JavaScript 和 TypeScript 的静态代码分析工具,主要功能是识别并修复代码中的问题,比如语法错误、不一致的风格、潜在的 bug 等。

npm install eslint --save-dev
npx eslint --init #初始化配置
#这个命令会引导你选择项目的风格、使用的框架(React、Vue等)、
#是否使用 TypeScript 等,并生成一个配置文件(.eslintrc.js、.eslintrc.json 等)。
npx eslint yourfile.js #检查这个文件
npx eslint yourfile.js --fix #自动修复代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

比如:如果在main.js 声明个变量而不使用,则终端和网页都会报错,因为不严谨。

  • 解决方式
    方式1: 手动解决掉错误, 以后项目中会讲如何自动解决
    方式2: 暂时关闭eslint检查, 在vue.config.js中配置后重启服务
module.exports={
	//其他配置略
	lintOnSave:false//关闭eslint检查
}
  • 1
  • 2
  • 3
  • 4
  • 常配合使用的插件/配置
    eslint-config-airbnb: Airbnb 代码规范
    eslint-plugin-react: 检查 React 项目
    eslint-plugin-import: 管理模块导入
    eslint-config-prettier: 配合 Prettier,关闭 ESLint 中和 Prettier 冲突的规则

JSX语法扩展

JSX(JavaScript XML)是一种 JavaScript 的语法扩展,主要用于Vue/ React。它让你可以在 JavaScript 中写出类似 HTML 的代码,描述界面的结构。
Vue 本身没有默认使用 JSX,默认用的是模板语法(.vue 文件里的 < template>),但支持 JSX 语法扩展,但JSX比Vue模版的性能差,因为没有模版同级别的编译时优化。

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Alice" />;
  • 1
  • 2
  • 3
  • 4
  • 5
  • JSX 的核心特点
  1. 像 HTML 但不是 HTML
const name = "ChatGPT";
const element = <h1>Hello, {name}!</h1>;
  • 1
  • 2
  1. 标签必须闭合
// 正确
<img src="logo.png" />
  • 1
  • 2
  1. 只能有一个根节点
// 错误 ❌
return (
  <h1>Title</h1>
  <p>Description</p>
);

// 正确 ✅
return (
  <div>
    <h1>Title</h1>
    <p>Description</p>
  </div>
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  1. class 改为 className
    因为 class 是 JavaScript 的关键字,所以在 JSX 中写样式类时要用 className
<div className="container">Hello</div>
  • 1
  • JSX 配合 ESLint
    为了让 ESLint 正确识别 JSX,你需要使用对应的插件和解析器:
#react
npm install eslint-plugin-react eslint-plugin-react-hooks --save-dev

#vue
npm install --save-dev eslint eslint-plugin-vue @vue/eslint-config-standard babel-eslint eslint-plugin-babel eslint-plugin-import eslint-plugin-node eslint-plugin-promise

#vue3还需要
npm install @vitejs/plugin-vue-jsx @vue/babel-plugin-jsx --save-dev
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
//配置 .eslintrc.js 示例
//react
module.exports = {
  parser: 'babel-eslint',
  extends: [
    'eslint:recommended',
    'plugin:react/recommended'
  ],
  plugins: ['react'],
  rules: {
    'react/prop-types': 'off'
  },
  settings: {
    react: {
      version: 'detect'
    }
  }
};

//vue
module.exports = {
  root: true,
  env: {
    node: true,
  },
  parserOptions: {
    parser: 'babel-eslint',
    ecmaVersion: 2020,
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true, // 开启 JSX 支持
    },
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-recommended', // Vue 3 推荐配置
    'plugin:import/recommended',
    'plugin:promise/recommended',
  ],
  plugins: ['vue', 'babel'],
  rules: {
    // 自定义规则,例如关闭 console 警告
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    // Vue 特有规则
    'vue/no-multiple-template-root': 'off', // Vue 3 不再强制单根节点
  },
};

//babel.config.js
module.exports = {
  presets: ['@vue/cli-plugin-babel/preset'],
  plugins: ['@vue/babel-plugin-jsx'],
};

//Vue 组件中使用 JSX
<script setup>
import { defineComponent } from 'vue';

export default defineComponent({
  setup() {
    return () => <div class="hello">Hello from JSX!</div>;
  },
});
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

简介

vue的底层还是原生js。开发更加的效率和简洁, 易于维护, 现在很多项目都是用vue开发的。
渐进式声明式组件化的javacript框架,官网地址: https://cn.vuejs.org/ 。
渐进式: 逐渐进步, 想用什么就用什么, 不必全都使用

  • vue的特点:
    • 渐进式
    • 声明式渲染:基于标准 HTML 拓展了一套模板语法,使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系。
    • 数据驱动视图 (响应式):Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。
    • 极少的去写DOM操作相关代码
    • 双向绑定
    • 组件系统
    • 不兼容IE8及以下浏览器(因为vue的响应式原理是基于es5的Object.defineProperty(),而这个方法不支持ie8及以下)
  • 库 v.s. 框架
    库: 封装的属性或方法 (例jquery.js),还是那个规则、语法、元素。
    框架: 拥有自己的规则和元素, 比库强大的多 (例vue.js)
  • 工程化开发方式:在webpack环境中开发vue,这是最推荐的企业常用方式
  • 目前Vue2已停止维护,之后所有Vue3的变化都用高亮显示
    最简单的实例
<div id="app">
  <button @click="count++">
    Count is: {{ count }}
  button>
div>
  • 1
  • 2
  • 3
  • 4
  • 5
import { createApp, ref } from 'vue'

createApp({
  setup() {
    return {
      count: ref(0)
    }
  }
}).mount('#app')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

设计模式

  • vue是MVVM设计模式
    vue源码内采用MVVM设计模式思想, 大大减少了DOM操作, 提高开发效率
    用数据驱动视图改变, 操作dom的事,由vue源码内部来做。vue是数据变化视图自动更新, 减少操作DOM时间, 提高开发效率
  1. 在vue中,不推荐直接手动操作DOM!!!
  2. 在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!(思想转变)
    • MVVM
      MVVM,一种软件架构模式,决定了写代码的思想和层次
      M: model数据模型 (data里定义)
      V: view视图 (html页面)
      VM: ViewModel视图模型 (vue.js源码)
      在这里插入图片描述
      在这里插入图片描述
      MVVM通过数据双向绑定让数据自动地双向同步 不再需要操作DOM
      V(修改视图) -> M(数据自动同步)
      M(修改数据) -> V(视图自动同步)

M层和V层可以互相改变
在devtool工具可以改变M层的变量, 观察V层(视图的自动同步);(devtool工具就是chrome浏览器检查工具(开发者模式)里多出来的vue工具)

  • 对比MVC设计模式
    • 组件化:模块独立,复用性强,适用于所有现代前端项目,如React, Vue
    • Flux/Redux:单向数据流,适合大型状态管理,见于react
    • MVC: 也是一种设计模式, 组织代码的结构, 是model数据模型, view视图, Controller控制器, 在控制器这层里编写js代码, 来控制数据和视图关联
      应用于早期小项目
    • MVVM: 即Model-View-ViewModel的简写。即模型-视图-视图模型, VM是这个设计模式的核心, 连接v和m的桥梁, 内部会监听DOM事件, 监听数据对象变化来影响对方. 我们称之为数据绑定
      应用于Vue, Angular 等现代框架,响应式数据双向绑定

React 并不严格是 MVVM,为什么很多人还是说 React 属于 MVVM?因为它也有:Model(state、props)、View(JSX)、某种“中间层逻辑”(用 Hook、useEffect 实现的)但这些功能都融合在组件中,不像 Vue 的 ViewModel 那么清晰分层。
React 是一种以组件为中心、函数式编程风格、支持单向数据流的前端库。它既不像传统 MVC,也不是典型 MVVM,而是一种组件驱动的 UI 架构。
React 的不同点:

  1. React 是单向数据流
    数据从组件的 state/props 向下流动到 UI。
    没有像 Vue 那样的“自动双向绑定”。
  2. 没有“真正意义上的 ViewModel”
    在 React 中,没有一个专门处理逻辑与数据绑定的“ViewModel”。
    组件本身就承担了“视图”和“一部分逻辑”的职责。
  3. React 强调函数式思想
    使用 Hook 来组合逻辑,而不是 ViewModel。
    倾向于将 UI 表现为“状态的纯函数”。

快速入门

  • 单文件组件
    使用一种类似 HTML 格式的文件来书写 Vue 组件,它被称为单文件组件 (也被称为 *.vue 文件,英文 Single-File Components,缩写为 SFC)。顾名思义,Vue 的单文件组件会将一个组件的逻辑 (JavaScript),模板 (HTML) 和样式 (CSS) 封装在同一个文件里。
//app.vue
<script setup>
import { ref } from 'vue'
// “ref”是用来存储值的响应式数据源。
const count = ref(0)
</script>

<template>
  <button @click="count++">Count is: {{ count }}</button>
</template>

<style scoped>
button {
  font-weight: bold;
}
</style>

//更复杂的例子
<!--
这个示例展示了如何通过 v-on 指令处理用户输入。
-->

<script setup>
import { ref } from 'vue'

const message = ref('Hello World!')

function reverseMessage() {
  // 通过其 .value 属性
  // 访问/修改一个 ref 的值。
  message.value = message.value.split('').reverse().join('')
}

function notify() {
  alert('navigation was prevented.')
}
</script>

<template>
  <!--
    注意我们不需要在模板中写 .value,
    因为在模板中 ref 会自动“解包”。
  -->
  <h1>{{ message }}</h1>

  <!--
    绑定到一个方法/函数。
    这个 @click 语法是 v-on:click 的简写。
  -->
  <button @click="reverseMessage">Reverse Message</button>

  <!-- 也可以写成一个内联表达式语句 -->
  <button @click="message += '!'">Append "!"</button>

  <!--
    Vue 也为一些像 e.preventDefault() 和 e.stopPropagation()
    这样的常见任务提供了修饰符。
  -->
  <a href="https://vuejs.org" @click.prevent="notify">
    A link with e.preventDefault()
  </a>
</template>

<style>
button, a {
  display: block;
  margin-bottom: 1em;
}
</style>

//attribute绑定
<!--
现在我们将元素的 attribute / property 响应式地绑定到状态上。
这个 :title 语法是 v-bind:title 的简写。
-->

<script setup>
import { ref } from 'vue'

const message = ref('Hello World!')
const isRed = ref(true)
const color = ref('green')

function toggleRed() {
  isRed.value = !isRed.value
}

function toggleColor() {
  color.value = color.value === 'green' ? 'blue' : 'green'
}
</script>

<template>
  <p>
    <span :title="message">
      Hover your mouse over me for a few seconds to see my dynamically bound title!
    </span>
  </p>

  <!--
  除了普通字符串之外,
  class 绑定还特别支持了对象和数组
  -->
  <p :class="{ red: isRed }" @click="toggleRed">
    This should be red... but click me to toggle it.
  </p>

  <!-- 样式绑定也支持对象和数组 -->
  <p :style="{ color }" @click="toggleColor">
    This should be green, and should toggle between green and blue on click.
  </p>
</template>

<style>
.red {
  color: red;
}
</style>

//条件&循环
<!--
我们可以通过 v-if 和 v-for 指令条件性地或循环地渲染内容。
-->

<script setup>
import { ref } from 'vue'

const show = ref(true)
const list = ref([1, 2, 3])
</script>

<template>
  <button @click="show = !show">Toggle List</button>
  <button @click="list.push(list.length + 1)">Push Number</button>
  <button @click="list.pop()">Pop Number</button>
  <button @click="list.reverse()">Reverse List</button>

  <ul v-if="show && list.length">
    <li v-for="item of list">{{ item }}</li>
  </ul>
  <p v-else-if="list.length">List is not empty, but hidden.</p>
  <p v-else>List is empty.</p>
</template>

//表单绑定
<!--
我们可以使用 v-model 指令在状态和表单输入之间创建双向绑定。
-->

<script setup>
import { ref } from 'vue'

const text = ref('Edit me')
const checked = ref(true)
const checkedNames = ref(['Jack'])
const picked = ref('One')
const selected = ref('A')
const multiSelected = ref(['A'])
</script>

<template>
  <h2>Text Input</h2>
  <input v-model="text">
  <p>{{ text }}</p>

  <h2>Checkbox</h2>
  <input type="checkbox" id="checkbox" v-model="checked">
  <label for="checkbox">Checked: {{ checked }}</label>

  <!--
    多个复选框可以绑定到
    相同的 v-model 数组
  -->
  <h2>Multi Checkbox</h2>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <p>Checked names: {{ checkedNames }}</p>

  <h2>Radio</h2>
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <p>Picked: {{ picked }}</p>

  <h2>Select</h2>
  <select v-model="selected">
    <option disabled value="">Please select one</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <p>Selected: {{ selected }}</p>

  <h2>Multi Select</h2>
  <select v-model="multiSelected" multiple style="width:100px">
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <p>Selected: {{ multiSelected }}</p>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • vue组件风格:两种不同的风格书写:选项式 API 和组合式 API。
    在生产项目中:当你不需要使用构建工具,或者打算主要在低复杂度的场景中使用 Vue,例如渐进增强的应用场景,推荐采用选项式 API。
    当你打算用 Vue 构建完整的单页应用,推荐采用组合式 API + 单文件组件。
  • 组合式 API (Composition API)
    通过组合式 API,我们可以使用导入的 API 函数来描述组件逻辑。在单文件组件中,组合式 API 通常会与