近几天更新完毕,不定期持续更新,建议关注收藏点赞。
这里主要是了解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 的核心特点
- 像 HTML 但不是 HTML
const name = "ChatGPT";
const element = <h1>Hello, {name}!</h1>;
- 1
- 2
- 标签必须闭合
// 正确
<img src="logo.png" />
- 1
- 2
- 只能有一个根节点
// 错误 ❌
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
- 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时间, 提高开发效率
- 在vue中,不推荐直接手动操作DOM!!!
- 在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!(思想转变)
- MVVM
MVVM,一种软件架构模式,决定了写代码的思想和层次
M: model数据模型 (data里定义)
V: view视图 (html页面)
VM: ViewModel视图模型 (vue.js源码)
MVVM通过数据双向绑定
让数据自动地双向同步 不再需要操作DOM
V(修改视图) -> M(数据自动同步)
M(修改数据) -> V(视图自动同步)
- MVVM
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 的不同点:
- React 是单向数据流
数据从组件的 state/props 向下流动到 UI。
没有像 Vue 那样的“自动双向绑定”。- 没有“真正意义上的 ViewModel”
在 React 中,没有一个专门处理逻辑与数据绑定的“ViewModel”。
组件本身就承担了“视图”和“一部分逻辑”的职责。- 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 通常会与搭配使用。这个 setup attribute 是一个标识,告诉 Vue 需要在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如,