目录
Vue 是一套前端框架,免除原生JavaScript中的DOM操作,简化书写
基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定
双向数据绑定
一、vue快速入门
a.vite
vite是构建vue项目的一个工具,特点是快,用到哪个页面就加载哪个 没用到的先不加载。
Vite 依赖现代浏览器的 ES 模块支持,减少了对复杂打包配置的需求,简化了开发环境的配置。简单高效:Vite 适用于对速度有较高要求的项目,如小型项目和现代前端应用
Vue CLI 使用 Webpack 作为构建工具,具有高度的可配置性和扩展性。
1.修改淘宝镜像
# 安装淘宝npm
npm install -g cnpm --registry=https://registry.npm.taobao.org
2.安装vite
npm install vite -g
3.构建
# vite创建vue项目
npm init vite vueshop-app --template vue
# 安装依赖
npm install
# 启动项目
npm run dev
b.vue-router
Vue Router 就是让你的网站或应用可以在不同页面之间跳转,而不需要刷新整个页面。
1.安装
npm install vue-router@4
2.配置
- src/router/index.js
import { createRouter, createWebHashHistory } from 'vue-router'
// 从 vue-router 库中引入创建路由器和创建哈希历史记录的方法
const routes = [
{
path: '/', // 当访问根路径时
name: 'Index', // 该路由的名称为 'Index'
meta: {
showTabBar: true // 自定义元数据,表示是否显示底部标签栏
},
component: () => import('../views/index.vue'),
// 按需加载 'index.vue' 组件,当访问 '/' 时才会加载该组件
},
{
path: '/login', // 当访问 '/login' 路径时
name: 'Login', // 该路由的名称为 'Login'
component: () => import('../views/account/login.vue'),
// 按需加载 'login.vue' 组件,当访问 '/login' 时才会加载该组件
},
// 其他路径和组件的配置...
{
path: '/*', // 匹配所有未定义的路径
redirect: '/', // 重定向到根路径 '/'
},
]
const router = createRouter({
history: createWebHashHistory(), // 使用哈希模式的历史记录
routes // 路由配置数组
})
// 创建并导出一个路由器实例
export default router
- main.js
import router from './router'
// 从 './router' 文件中导入路由配置
createApp(App)
.use(router)
// 使用路由配置,告诉 Vue 应用程序要使用我们定义的路由
...
.mount('#app')
// 将应用程序挂载到 HTML 中 id 为 'app' 的元素上
3.功能介绍
3.1导航链接(Links):
<template>
<div>
<router-link to="/">Home</router-link> <!-- 客厅按钮 -->
<router-link to="/about">About</router-link> <!-- 关于页面按钮 -->
<router-view></router-view> <!-- 显示当前房间内容 -->
</div>
</template>
3.2动态路由:
根据不同的参数进入不同的界面
const routes = [
{ path: '/user/:id', component: User } // 用户房间,可以根据用户 ID 显示不同的内容
];
<template>
<div>
<router-link to="/user/123">User 123</router-link> <!-- 跳转到用户123的房间 -->
<router-link to="/user/456">User 456</router-link> <!-- 跳转到用户456的房间 -->
<router-view></router-view> <!-- 显示当前房间内容 -->
</div>
</template>
3.3导航守卫(Navigation Guards):
有些房间可能有特殊的进入条件,比如你需要一个钥匙(权限)才能进入卧室。类似java里的拦截器。
// src/router/index.js
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
// 全局前置守卫
router.beforeEach((to, from, next) => {
// 检查路由是否需要授权
if (to.matched.some(record => record.meta.requiresAuth)) {
// 需要授权的路由,进行检查
if (!isAuthenticated()) {
// 如果用户未认证,重定向到登录页面
next({ path: '/login' })
} else {
// 继续导航
next()
}
} else {
// 继续导航
next()
}
})
export default router
history:createWebHashHistory()、createWebHistory()解释!
const router = createRouter({ history: createWebHashHistory(), routes, }) const router = createRouter({ history: createWebHistory(), routes, })
createWebHashHistory()
history: createWebHashHistory()
表示我们使用 "Hash 模式" 创建路由历史。Hash 模式的特点是 URL 中会带有#
符号(例如http://example.com/#/about
)- 兼容性好,适用于所有浏览器。
- 浏览器只会把
#
后面的部分发送到服务器,前面的部分会被 Vue Router 用来进行客户端路由控制。
createWebHistory
- 当用户导航到不同的路由时(比如从首页到关于页),浏览器的地址栏会更新。
- 但是页面不会重新加载,用户感觉就像在一个单页应用中浏览一样。
- 用户可以使用浏览器的后退按钮返回之前的页面。
-
createWebHistory
:- 更现代、更简洁的 URL。
- 需要服务器支持处理 URL 路由。
- 使用 HTML5 历史记录 API。
-
createWebHashHistory
:- 简单易用,兼容性好。
- URL 包含
#
符号,不需要服务器配置。 - 使用哈希符号模拟前端路由。
c.axios
Axios 是一个工具,用来帮助你在 JavaScript 代码中发送和接收网络请求。它可以帮你从服务器获取数据(比如获取一个用户列表),也可以把数据发送到服务器(比如提交一个表单)。
为什么要用 Axios?
- 简单易用:用起来很方便,不需要写很多代码。
- 支持 Promise:可以用更现代、更清晰的方式处理异步操作。
- 支持拦截器:可以在请求发送前或者响应收到后做一些自定义处理。
- 自动处理 JSON:会自动把服务器返回的 JSON 数据解析成 JavaScript 对象。
- 支持取消请求:在一些情况下可以取消已经发送的请求。
1.安装
# 使用 npm 安装
npm install axios
# 使用 yarn 安装
yarn add axios
2.主要方法
2.1 GET 请求
import axios from 'axios'; // 引入 axios 库
// 发送 GET 请求到指定 URL
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data); // 如果请求成功,打印返回的数据
})
.catch(error => {
console.error('Error fetching data:', error); // 如果请求失败,打印错误信息
});
2.2 POST 请求
import axios from 'axios'; // 引入 axios 库
const postData = {
name: 'John Doe', // 要发送的数据
age: 30,
};
// 发送 POST 请求到指定 URL,并附带 postData 数据
axios.post('https://api.example.com/user', postData)
.then(response => {
console.log('User created:', response.data); // 如果请求成功,打印返回的数据
})
.catch(error => {
console.error('Error creating user:', error); // 如果请求失败,打印错误信息
});
2.3使用拦截器
import axios from 'axios'; // 引入 axios 库
// 添加请求拦截器
axios.interceptors.request.use(config => {
// 在请求发送前做一些处理,比如添加自定义头信息
console.log('Request sent with config:', config);
return config;
}, error => {
// 请求错误时做一些处理
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(response => {
// 在响应收到后做一些处理,比如记录日志
console.log('Response received:', response);
return response;
}, error => {
// 响应错误时做一些处理
return Promise.reject(error);
});
2.4并发请求
- axios.get(url, config):发送 GET 请求。
- axios.post(url, data, config):发送 POST 请求。
- axios.put(url, data, config):发送 PUT 请求。
- axios.delete(url, config):发送 DELETE 请求。
- axios.all(promises):处理并发请求。
- axios.spread(callback):用于分割并发请求的响应数据
d.Sass
Sass 是一种增强版的 CSS,它让你写样式更方便、更高效。简单来说,Sass 就是让 CSS 更强大、更灵活的一个工具。
为什么要用 Sass?
- 变量:可以定义变量,方便复用,比如颜色、字体大小等。
- 嵌套:可以嵌套写样式,让代码更简洁,更有层次感。
- 混合(Mixins):可以定义一段可复用的样式,然后在多个地方使用。
- 继承:可以让一个选择器继承另一个选择器的样式。
- 运算:可以在样式里进行数学运算。
安装
npm install -g sass
1. 变量
// 定义变量,可以复用颜色和字体
$primary-color: #3498db;
$font-stack: Helvetica, sans-serif;
// 使用变量,简化代码
body {
font: 100% $font-stack;
color: $primary-color;
}
2. 嵌套
// 使用嵌套,让样式层次更清晰
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
display: inline-block;
}
a {
text-decoration: none;
color: $primary-color;
// 使用 &:hover 表示 a:hover
&:hover {
color: darken($primary-color, 10%); // 变暗10%的颜色
}
}
}
3. 混合(Mixins)
// 定义混合,可以复用样式代码
@mixin border-radius($radius) {
// 为不同浏览器添加圆角样式
-webkit-border-radius: $radius; // WebKit 内核浏览器
-moz-border-radius: $radius; // Mozilla 内核浏览器
border-radius: $radius; // 标准 CSS3 属性
}
// 使用混合,简化样式
.button {
// 通过 @include 使用定义的混合,并传入圆角半径 10px
@include border-radius(10px);
}
4.继承
// 定义基础样式
.message {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
// 继承基础样式,减少重复代码
.success {
@extend .message;
border-color: green;
}
.error {
@extend .message;
border-color: red;
}
.warning {
@extend .message;
border-color: yellow;
}
5.运算
// 在样式中进行数学运算
.container {
width: 100%;
margin-left: 10px;
margin-right: 10px;
padding: 5px + 10px; // 计算结果是 15px
}
e.vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
可以把 Vuex 想象成一个大管家,这个管家负责管理你应用中的所有数据和状态。无论你在应用的哪个地方,都可以很方便地从这个管家那里获取数据或修改数据。
Vuex 的核心概念
State(状态):
- 定义:State 是存储应用中需要共享的数据的地方。
- 作用:就像应用的单一数据源,所有组件都可以从这里获取数据。
- 大白话:State 就是我们所有组件共享的“公共数据存储库”。
Mutations(变更):
- 定义:Mutations 是唯一改变 State 的方法,它们必须是同步的。
- 作用:通过提交(commit) mutations,来修改 State。
- 大白话:Mutations 就是我们告诉管家如何改变数据的方法,比如“把我的名字改成张三”。
Actions(动作):
- 定义:Actions 用于处理异步操作,可以包含任意异步操作,比如 API 调用,然后提交 mutations。
- 作用:通过分发(dispatch) actions,来触发异步操作,并最终提交 mutations。
- 大白话:Actions 就是我们告诉管家去做一些事情的方法,比如“去服务器拿数据”。
Getters(获取器):
- 定义:Getters 是 store 的计算属性,可以对 State 进行计算和过滤,返回需要的结果。
- 作用:通过访问 getters 获取处理后的数据。
- 大白话:Getters 就是我们从管家那里获取处理好的数据的方法,比如“管家,给我所有年龄大于 18 岁的用户”。
Modules(模块):
- 定义:当应用变得很大时,可以将 store 拆分成模块,每个模块拥有自己的 state、mutations、actions 和 getters。
- 作用:通过模块化管理,使得 store 更加易于维护和扩展。
- 大白话:Modules 就是我们把管家的工作拆分给多个小管家,每个小管家负责一部分数据和逻辑。
<!-- App.vue -->
<template>
<div>
<p>{{ count }}</p> <!-- 显示 state 中的 count -->
<button @click="increment">Increment</button> <!-- 点击按钮调用 increment 方法 -->
<button @click="incrementAsync">Increment Async</button> <!-- 点击按钮调用 incrementAsync 方法 -->
<p>Double Count: {{ doubleCount }}</p> <!-- 显示 getter 中的 doubleCount -->
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapState(['count']), // 将 Vuex 的 state 映射到组件的计算属性中
...mapGetters(['doubleCount']) // 将 Vuex 的 getters 映射到组件的计算属性中
},
methods: {
...mapActions(['increment', 'incrementAsync']) // 将 Vuex 的 actions 映射到组件的方法中
}
}
</script>
// store.js
import { createStore } from 'vuex'
// 创建一个新的 store 实例
const store = createStore({
// state 是存储应用中需要共享的数据的地方
state() {
return {
count: 0 // 这里存储了一个状态 count,初始值为 0
}
},
// mutations 是唯一可以修改 state 的方法,必须是同步的
mutations: {
// increment 是一个 mutation,用于增加 count 的值
increment(state) {
state.count++ // 修改状态 count
}
},
// actions 用于处理异步操作,可以包含任意异步操作,比如 API 调用,然后提交 mutations
actions: {
// incrementAsync 是一个 action,用于异步增加 count 的值
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment') // 异步操作完成后提交 mutation increment
}, 1000)
}
},
// getters 是 store 的计算属性,可以对 state 进行计算和过滤,返回需要的结果
getters: {
// doubleCount 是一个 getter,返回 count 的两倍值
doubleCount(state) {
return state.count * 2 // 计算后的状态
}
}
})
export default store
//async 关键字用于声明一个异步函数。
//await 关键字用于等待一个 Promise 对象的结果,代码会暂停在这里,直到 Promise 解析完
async function fetchData() {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
console.log('成功响应:', response.data);
} catch (error) {
console.error('请求错误:', error);
}
}
fetchData();
f.配置别名
在 Vue 项目中,引入路径别名可以代码更加清晰和简洁使用路径别名,可以避免使用相对路径(
../../components
),使用更简洁的路径别名(@/components
)。
npm install @types/node --save-dev
import { defineConfig } from 'vite'; // 从 Vite 中导入 defineConfig 函数,用于定义配置
import vue from '@vitejs/plugin-vue'; // 从 @vitejs/plugin-vue 中导入 vue 插件,用于支持 Vue 单文件组件
import path from 'path'; // 从 Node.js 中导入 path 模块,用于处理和转换文件路径
// 配置 Vite 项目
export default defineConfig({
plugins: [vue()], // 使用 vue 插件,支持 Vue 单文件组件
resolve: {
alias: {
'@': path.resolve(__dirname, './src') // 配置路径别名 '@' 指向项目的 'src' 目录
}
}
});
//main.js中
import { createApp } from 'vue';
import App from './App.vue';
import MyComponent from '@/components/MyComponent.vue'; // 使用路径别名
import store from '@/store'; // 使用路径别名
createApp(App)
.use(store)
.component('my-component', MyComponent)
.mount('#app');
1. 新建 HTML 页面,引入 Vue.js文件
<script src="js/vue.js"></script>
2. 在JS代码区域,创建Vue核心对象,进行数据绑定
new Vue({
el:"#app",
data(){
return {username:""}
}
})
3. 编写视图 在HTML里面
<div id="app">
<input name="username" v-model="username" >
{{username}}</div>
4.完整代码 (简单入门小例子)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
134156456
<div id="app">
<input v-model="username">
{{username}}
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
data(){
return {username:""}//没有return 界面不显示这个
}
}) ;
</script>
</body>
</html>
二、常用指令
1.v-bind:
<a v-bind:href="url">百度一下</a>
<!-- v-bind 可以省略-->
<a :href="url">百度一下</a>
2.v-model: 双向数据绑定
<input name="username" v-model="username">
3.v-on: 事件响应
<a v-on:click="show()">被点击了1</a><!-- 2.绑定事件-->
<a @click="show()">被点击了2</a><br>
4.v-if v-else-if v-show
<div v-if="count == 3">div1</div>
<div v-else-if="count == 4">div2</div>
<div v-else>div3</div>
<hr>
<div v-show="count == 3">div v-show</div>
<br>
<input v-model="count">
5.v-for
<div v-for="a in addrs">{{a}}</div> <!-- 带坐标-->
<div v-for="(a,i) in addrs">{{i+1}}0000{{a}}</div><!--不带坐标-->
完整演示代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
134156456
<div id="app">
<input v-model="username"><br>
{{username}}<br>
<a v-bind:href="url">点击一下1</a><!-- 1.绑定网页-->
<a :href="url">点击一下2</a><br>
<a v-on:click="show()">被点击了1</a><!-- 2.绑定事件-->
<a @click="show()">被点击了2</a><br>
<!-- 3.if 判断-->
<br>
<div v-if="count == 1">div1</div>
<div v-else-if="count == 2">div2</div>
<div v-else>div4</div>
<hr>
<div v-show="count == 3">div v-show</div><!-- 都加载完了 不用再加载啦 只是藏起来啦 占很大内存-->
<br>
<input v-model="count"><br>
<div v-for="a in addrs">{{a}}</div> <!-- 带坐标-->
<div v-for="(a,i) in addrs">{{i+1}}0000{{a}}</div><!--不带坐标-->
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
data(){
return {username:"",
url:"http://www.baidu.com",
count:1,
addrs:["北京","上海","西安"]
}//没有return 界面不显示这个
},
methods:{
show(){alert("被点击啦")}
}
}) ;
</script>
</body>
</html>
三、Vue生命周期
mounted 加载完成自动会调用(跟methods同级)
mounted(){
alert("加载完成...")
}