Vue
Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助高效地开发用户界面。
脚手架
搭建脚手架
首先确保已经安装 Node.js 最新版
输入以下命令
npm create vue@latest
出现一下内容
✔ Project name: … your-project-name ✔ Add TypeScript? … No / Yes ✔ Add JSX Support? … No / Yes ✔ Add Vue Router for Single Page Application development? … No / Yes ✔ Add Pinia for state management? … No / Yes ✔ Add Vitest for Unit testing? … No / Yes ✔ Add an End-to-End Testing Solution? … No / Cypress / Nightwatch / Playwright ✔ Add ESLint for code quality? … No / Yes ✔ Add Prettier for code formatting? … No / Yes ✔ Add Vue DevTools 7 extension for debugging? (experimental) … No / Yes
Scaffolding project in ./your-project-name... Done.
cd your-project-name
npm install
npm run dev
项目结构
以下是使用 Vue CLI 创建的 Vue 项目的默认结构
项目根目录
├── node_modules/ // 依赖模块(自动生成)
├── public/
│ ├── favicon.ico // 网站图标
│ └── index.html // 项目的主页面模板,是Vue应用的HTML基础,其中id="app"的DOM元素是Vue应用的挂载点
├── src/
│ ├── assets/ // 用于存储应用的静态资源,如图片、样式表、字体文件等
│ ├── components/ // 存放Vue组件,提高代码复用性
│ ├── App.vue // Vue应用的根组件,处于UI结构顶层,其他组件会在此基础上进行嵌套和组合
│ └── main.js // 项目的入口文件,在这里创建Vue应用实例,配置全局插件、混入等,并将Vue应用挂载到index.html的指定元素上,启动整个应用
├── .gitignore
├── babel.config.js // 语法转换工具,将最新的JS API降级为低版本浏览器兼容的代码
├── package.json // 项目配置和依赖声明文件,记录了项目的依赖、脚本命令等信息
├── README.md
└── vue.config.js // CLI配置文件,可对项目构建过程进行多种设置,如路径别名、代理服务器、打包优化等
模板语法
文本插值
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
<template>
<span>Message: {{ msg }}</span>
</template>
<script>
export default {
data() {
return {
msg: "你好"
}
}
}
</script>
双大括号标签会被替换为相应组件实例中 msg 属性的值。同时每次 msg 属性更改时它也会同步更新。
v-model 绑定数据(双向绑定)
v-model 指令主要用于表单元素,实现数据的双向绑定。即用户在表单中输入或选择的值会实时反映到 Vue 实例的数据中,而数据的变化也会实时更新到表单中。
<div>
<input type="text" v-model="password">
{{ password }}
</div>
在 Vue 实例的 data 中定义 password 变量,如 data: { password: '' },用户在输入框中输入的内容会同时显示在下方的插值表达式中。
原理:v-model 本质上是语法糖,对于 input 元素,它会在 input 事件触发时更新数据,并在 value 属性上绑定数据。
v-if、v-else、v-else-if
v-if 指令用于根据表达式的值来有条件地渲染元素。如果表达式的值为 true,则元素会被渲染到 DOM 中;如果为 false,则元素不会出现在 DOM 中(包括其所有子元素)。
<div v-if="showElement">这是要显示的元素</div>
v-else 指令必须紧跟在 v-if 或 v-else-if 之后,用于提供另一个条件分支。
<div v-if="isTrue">条件为真时显示</div>
<div v-else>条件为假时显示</div>
v-else-if 用于添加多个条件分支。
<div v-if="score >= 90">优秀</div>
<div v-else-if="score >= 80">良好</div>
<div v-else-if="score >= 60">及格</div>
<div v-else>不及格</div>
注意:v-if 是真正的条件渲染,因为它会确保在切换时销毁或重建元素及其子元素。
v-bind 属性绑定
v-bind 指令用于绑定元素的属性。常见的是用于绑定 href、src、class、style 等属性。
<a v-bind:href="href">搜索一下</a>
在 Vue 实例的 data 中定义 href 变量,如 data: { href: 'https://www.example.com' },则 a 标签的 href 属性会被设置为指定的链接。
v-bind 可以简写为 :,所以上述代码也可以写成:
<a :href="href">搜索一下</a>
v-on: 点击事件
v-on 指令用于绑定 DOM 事件,如 click、mouseenter、keyup 等。当事件触发时,会执行绑定的方法。
<button v-on:click="functionName">关闭</button>
在 Vue 实例的 methods 中定义 functionName 方法,如:
methods: {
functionName() {
// 这里编写按钮点击时要执行的逻辑
console.log('按钮被点击了');
}
}
v-on 可以简写为 @:
<button @click="functionName">关闭</button>
v-for
v-for 指令用于基于一个数组或对象来渲染多个元素。它会迭代数组或对象的属性,并为每个元素渲染一个模板。
基于数组的迭代:
<div v-for="item in students" :key="item">{{ item.name }}</div>
在 Vue 实例的 data 中定义 students 数组,如:
data: {
students: [{name: '张三同学'},{name: '李四同学'},{name: '王五同学'}]
}
上述代码会为 students 数组中的每个对象渲染一个 div 元素,并显示学生的名字。
v-for 还可以同时获取数组元素的索引:
<div v-for="(item, index) in usernames" :key="index">{{index+1 + '==>' + item}}</div>
在 Vue 实例的 data 中定义 usernames 数组,如:
data: {
usernames: ['张三','李四','王五']
}
上述代码会在每个 div 中显示元素的序号和值。
基于对象的迭代:
<div v-for="(value, key) in userInfo">
{{ key }}: {{ value }}
</div>
在 Vue 实例的 data 中定义 userInfo 对象,如:
data: {
userInfo: { name: '小明', age: 20, city: '北京' }
}
上述代码会为 userInfo 对象的每个属性渲染一个 div 元素,显示属性名和属性值。
注意:使用 v-for 时,为每个元素提供一个唯一的 :key 属性是很重要的,它可以帮助 Vue 高效地更新 DOM,提高性能。
路由(Vue Router)
Vue Router 是 Vue.js 官方的路由管理器。以下是一个示例:
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './views/Home.vue';
import About from './views/About.vue';
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
];
const router = new VueRouter({
routes
});
new Vue({
router,
render: h => h(App)
}).$mount('#app');
在模板中使用路由链接:
<router - link to="/">Home</router - link>
<router - link to="/about">About</router - link>
<router - view></router - view>
路由导航守卫
可以使用路由导航守卫来控制路由的访问权限等。例如全局前置守卫:
router.beforeEach((to, from, next) => {
// 检查用户是否登录
const isLoggedIn = localStorage.getItem('isLoggedIn');
if (to.meta.requiresAuth &&!isLoggedIn) {
next('/login');
} else {
next();
}
});
状态管理(Vuex)
核心概念
- state:应用的状态,类似于组件的
data。 - mutations:唯一可以修改
state的地方,必须是同步函数。 - actions:可以包含任意异步操作,通过提交
mutations来修改state。 - getters:类似于计算属性,用于获取
state中的数据。
简单示例
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
}
},
getters: {
getCount(state) {
return state.count;
}
}
});
export default store;
在组件中使用:
export default {
computed: {
count() {
return this.$store.getters.getCount;
}
},
methods: {
increment() {
this.$store.commit('increment');
},
incrementAsync() {
this.$store.dispatch('incrementAsync');
}
}
};
生命周期钩子
Vue 实例有多个生命周期钩子函数,允许特定阶段执行代码。例如:
new Vue({
data() {
return {
message: 'Hello'
};
},
// Vue 实例生命周期的首个钩子函数
// 在实例初始化后,数据观测和 event/watcher 事件配置前执行
beforeCreate() {
console.log('Before create');
},
// 在实例创建完成后调用
created() {
console.log('Instance created');
},
beforeMount() {
console.log('Before mount');
},
mounted() {
console.log('Component mounted');
},
beforeUpdate() {
console.log('Before update');
},
updated() {
console.log('Component updated');
},
beforeDestroy() {
console.log('Before destroy');
},
destroyed() {
console.log('Instance destroyed');
}
});
组件化
组件基础
组件是 Vue 应用中最核心的概念之一,它允许你将页面拆分成多个小的、可复用的部分。例如,创建一个简单的 HelloWorld 组件:
// 定义一个名为 HelloWorld 的组件
const HelloWorld = {
template: '<div>Hello, World!</div>'
};
// 在 Vue 实例中使用该组件
new Vue({
el: '#app',
components: {
HelloWorld
}
});
在模板中使用组件:
<div id="app">
<HelloWorld></HelloWorld>
</div>
组件通信
- props:用于父组件向子组件传递数据。
// 子组件
const ChildComponent = {
props: ['message'],
template: '<div>{{ message }}</div>'
};
// 父组件使用子组件并传递数据
new Vue({
el: '#app',
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from parent'
};
}
});
<div id="app">
<ChildComponent :message="parentMessage"></ChildComponent>
</div>
