Vue-状态管理
Vue-cli 存在的意义就是让开发人员把精力放在业务的代码上 , 因此其他的准备的工作交给vue-cli去做即可
API:https://cli.vuejs.org/zh/guide/ (opens new window)
# 安装
全局脚手架
npm i -g @vue/cli
验证安装(查看版本
# 后面的 V 一定要大写
vue -V
# 创建项目
PS:项目名当中不能含有英文大写
# 4.0下创建 heroes项目
$ vue create heroes
# 切换到 项目根目录
$ cd heroes
# 在开发模式下 启动运行项目
$ npm run serve
....
# 打包项目
$ npm run build
以上指令在 ==package.json==文件 看到相关配置
项目配置
根目录下的 ==vue.config.js==文件
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: true, // 在保存代码的时候开启eslint代码检查机制
devServer: { // 实时保存、编译的配置段
open: true, // 自动开启浏览器
port: 12306 // 服务运行端口
}
})
项目目录
以下的Vue-Cli生成的项目结构解读
Vue-Cli不同版本的项目结构也会不同:
- ==2.x==版本 的项目结构中有 buiild文件夹和config文件夹 这两个文件夹存储了webpack相关的配置 , 当中可以根据项目需求修改webpack配置
- ==3+==版本 以后的版本项目结构中 已经隐藏了这两个文件夹 (主要目的是为了让初学者更关心怎么去用Vue , 并非是 webpack配置相关的
.
|-- node_modules // 项目需要的依赖包
|-- public // 静态资源存储目录
| |-- index.html // 项目主容器文件
| |-- favicon.ico // 项目默认索引图片
|-- src
| |-- assets // 静态资源文件夹
| |-- components // 公共组件目录
| |-- views // 业务组件目录
| |-- App.vue // 顶层根基路由组件
| |-- main.js // 主入口文件
| |-- router.js // 路由配置文件
|-- .editorconfig // 代码规范配置文件
|-- .eslintrc.js // eslint代码规范检查配置文件
|-- .gitignore // git上传需要忽略的文件格式
|-- babel.config.js // babel配置文件
|-- package-lock.json // 依赖包版本锁定文件
|-- package.json // 项目基本信息配置文件
|-- postcss.config.js // css预处理器配置文件
|-- vue.config.js // webpack 配置文件
# 项目开发
开发主要应用有:Vuex、Router
在开发的时候编写代码主要围绕着 src
/public
这两个文件夹 , 他们分别作用已经在上面叙述有 . 开发当中可能会受到不同版本的影响 , 因此专门分为 版本2 和 版本3+ 进行写开发应用示例
默认情况下生成 Vue-Cli脚手架 是官方已经配置好的 , 因此建议手动配置一次保存为好
手动配置安装选项:
dart-sass
、babel
、router
、vuex
、eslint
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, CSS Pre-processors, Linter
? Choose a version of Vue.js that you want to start the project with 3.x
? Use history mode for router? (Requires proper server setup for index fallback in production) y
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass)
? Pick a linter / formatter config: Standard
? Pick additional lint features: Lint on save, Lint and fix on commit
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? (y/N) n
# 版本2开发
由于版本3 较为简洁说明用版本2
main.js
// 导入 库
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 创建实例
new Vue({
router,
store,
// 渲染组件
render: h => h(App)
}).$mount('#app')
App.vue
// 组件模板
<template>
</template>
// 组件脚本
<script>
export default {}
</script>
// 样式
<style lang="scss">
</style>
Vuex
./router/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vue)
const store = new Vuex.Store({
state: {
name: '柏竹'
}
})
// 暴露出去 给 App.vue 引用
export default store
Router
./store/index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
routes: [...]
})
export default router
# 版本3+开发
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App).use(store).use(router).mount('#app')
App.vue
<template>
</template>
<script>
export default {}
</script>
<style lang="scss">
</style>
Vuex
./router/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
name: '柏竹'
}
})
Router
./store/index.js
import { createRouter, createWebHistory } from 'vue-router'
// 假设引入的 One组件/Two组件
import One from '../components/One'
import Two from '../components/Two'
const routes = [
{ path: '/one', name: 'one', component: One },
{ path: '/two', name: 'two', component: Two }
]
const router = createRouter({
// 使路由切换产生web页面历史记录
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
# 版本3应用示例
示例应用应用前把
src
/public
文件夹的子文件清空(并非清空文件夹)
./public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webapp</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
./src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'
import router from './router/index'
createApp(App)
.use(store)
.use(router)
.mount('#app')
./src/App.vue
<template>
<div>
<h2>Vuex应用测试</h2>
<p>我是App组件{{ msg }}</p>
<button @click="say">sayLog</button>
<br>
<button @click="getName">App=>getName</button>
<h2>路由组件展示</h2>
<router-link to="/one">Go to One</router-link>
<br>
<router-link to="/two">Go to Two</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
msg: '12'
}
},
methods: {
say () {
console.log('App组件:我太难了')
},
getName () {
console.log(this.$store)
console.log(this.$store.state.name)
}
}
}
</script>
<style scoped>
p {
color: red;
}
</style>
./src/store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
name: '柏竹'
}
})
模板
./src/components/One.vue
<template>
<div>
<p>我是One组件</p>
<button @click="getName">One=>getName</button>
</div>
</template>
<script>
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'One',
methods: {
getName () {
console.log(this.$store.state.name)
}
}
}
</script>
<style scoped>
p{
background: red;
}
</style>
./src/components/Two.vue
<template>
<div>
<p>我是Two组件</p>
</div>
</template>
<script>
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'Two'
}
</script>
<style scoped>
p{
background: blue;
}
</style>
./src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import One from '../components/One'
import Two from '../components/Two'
const routes = [
{ path: '/one', name: 'one', component: One },
{ path: '/two', name: 'two', component: Two }
]
const router = createRouter({
// 使路由切换产生web页面历史记录
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
呈现方式自行测试
# Axios通信
npm安装/应用
# npm安装
npm i axios
# 引入应用
import axios from "axios";
async/await 异步请求
无需回调响应...
async function getUser(){
const res = await axios.get('/user/12');
console.log(res);
}
请求方式 Vue通信一致
根路径配置
在main.js进行配置
import axios from 'axios';
# 请求路径
axios.defaults.baseURL = 'http://localhost:9000'
# 组件可访问
# Vue2
Vue.prototype.$http = axios
# Vue3
let app = createApp(App)
app.config.globalProperties.$http = axios
app.mount('#app')
应用方式
// 更改为 $http变量进行发送请求
async getUserAll() {
let res = await this.$http.get("/user/findall");
this.table = res.data;
}
# Router路由
Router路由 基本操作方式 点击跳转
仓库代码 : vue-router (opens new window)
# 版本&安装
vue-router 目前有 3.x / 4.x 的版本 . 其中 :
- 3.x 只能结合 vue2 进行使用
- 4.x 只能结合 vue3 进行使用
注意 : 安装时 , 未定义版本会默认最高版本
npm安装
- 版本3 ==npm install vue-router@3==
- 版本4 ==npm install vue-router@4==
# 应用
大致步骤 :
- 在项目中安装 vue-router
- 定义路由组件
- 声明路由链接和占位符
- 创建路由模块
- 导入并挂载路由模块
示例 :
定义路由组件 view/.. 发现音乐(Discover)|我的音乐(My)|关注(Friends)
<template> <h1>关注</h1> </template>
声明路由链接和占位符 App.vue
<template> <div> <h1>APP组件</h1> <!-- 声明路由链接 --> <router-link to="/discover">发现音乐</router-link> <router-link to="/my">我的音乐</router-link> <router-link to="/friend">关注</router-link> <!-- 声明路由占位标签 --> <router-view></router-view> </div> </template>
创建路由模块 router/index.js
import VueRouter from 'vue-router' import Vue from 'vue' import Discover from '@/components/Discover.vue' //将VueRouter设置为Vue的插件 Vue.use(VueRouter) const router = new VueRouter({ // 指定hash属性与组件的对应关系 routes: [ { path: '/discover', component: Discover }, { path: '/friends', component: () => import('@/components/Friends.vue') }, { path: '/my', component: () => import('@/components/My') }, ] }) export default router
导入并挂载路由模块 main.js 2版本
import Vue from 'vue' import App from './App.vue' import router from './router' Vue.config.productionTip = false new Vue({ render: h => h(App), router:router }).$mount('#app')
3版本
import { createApp } from 'vue' import App from './App.vue' import router from './router' createApp(App).use(router).mount('#app')
# Vuex应用
介绍 : 点击跳转
仓库代码 : vue-x (opens new window)
状态管理 : State
/Getter
/Mutation
/Action
/Module
这些状态在官网走一遍练习即可 : 点击跳转 (opens new window)
- State : 维护所有应用层的状态 , 确保应用唯一的数据源
- Getter : 维护由State派生状态(计算属性) , 会随着State状态变化而变化
- Mutations : 提供修改 State状态的方法 , 不支持异步操作
- Action : 不能修改State , 能操作mutation进行修改State , 支持异步操作(async/await)
安装 :
- 版本2 ==npm i vuex@2== ==npm i vuex@3==
- 版本3 ==npm i vuex@3== ==npm i vuex@4==
# Mockjs
Mock.js是一款前端开发中拦截Ajax请求再生成随机数据响应的工具 , 可以用来模拟服务器响应 , 优点是非常简单方便 , 无侵入性 , 基本覆盖常用的接口数据类型 支持生成随机的 文本/数字/布尔值/日期/邮箱/链接/图片/颜色/...
官网 : http://mockjs.com/
GitHub : https://github.com/nuysoft/Mock
生成规范 :
- https://github.com/nuysoft/Mock/wiki/Syntax-Specification
- http://mockjs.com/examples.html
安装 : ==npm i mockjs==
核心方法 : ==Mock.mock(rurl?, rtype?, template | function(options))==
- rurl : 拦截的url (支持正则)
- rtype : 拦截的请求类型
- template : 数据模板 , 对象/字符串/...
- function : 产生数据的函数
- 设置延时请求的数据
# 应用
仓库 : 点击跳转 (opens new window) 大致步骤 :
- npm安装 mock/axios
- 创建生成的JS文件并引入
- 发出请求测试
创建 mock/index.js
import Mock from 'mockjs'
// 使用模拟数据
Mock.mock('/product/search', {
"ret": 0,
"data": {
"mtime": "@datetime",
"score|1-800": 1,
"rank|1-100": 1,
"stars|1-5": 1,
"nickname": "@cname",
"img": "@image('200x100', '#ffcc33', '#FFF', 'png', 'Fast Mock')"
}
});
引入 main.js
import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios'
// 引入mock
import './mock'
let app = createApp(App)
// 设置全局
app.config.globalProperties.$http = axios
app.mount('#app')
请求 App.vue (仅展示核心部分
export default {
name: 'App',
components: {
HelloWorld
},
mounted: async function () {
let res = await this.$http.get("/product/search");
console.log(res)
}
}
/* 打印结果
{
"mtime": "1992-01-06 04:31:58",
"score": 719,
"rank": 9,
"stars": 2,
"nickname": "贾磊",
"img": "http://dummyimage.com/200x100/ffcc33/FFF.png&text=Fast Mock"
}
*/
# 部署
大致步骤 :
- 打包项目 , 上传
- 安装 nginx , 并更改配置
- 刷新生效配置
Vue项目打包
# 打包后会得到 dist项目文件夹
npm run build
不公项目执行的打包指令不一致 , 观察 package.json 文件打包指令
nginx安装
# 安装
yum install epel-release
yum update
yum -y install nginx
# nginx服务 开启/停止/重启
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
nginx配置
路径 ==/etc/nginx/conf.d== 目录 , 创建vue.conf文件
server {
listen 80;
server_name locahost;
location / {
root /usr/app/dist;
index index.html;
}
}
注意 : 我这里上传的路径 dist项目文件夹 的路径
刷新生效配置
nginx -s reload
# 问题
- 项目编辑验证不规范异常问题
**解决方案 : **手动配置 , 在IDEA配置 搜索
ESLint
, 执行以下操作项
- 选中 自动ESLint配置
- 打钩 运行时 ==eslint --fix== 并配置 保存时操作 ==自动ESLint配置==
项目首次 ==new Vue({})== 指定无效问题 (有两种解决方案)
**解决方案 : **(Vue-Cli3版本以下可解决 为代码添加以下注解 跳过检查
import Vue from 'vue' import App from './App.vue' /* eslint-disable no-new */ new Vue({ el: '#app', render: h => h(App) })
3以上的版本 , 因为 new实例的组件未使用因此报错 不允许在赋值/比较之外使用 new实例操作
解决方案:(Vue-Cli3版本以上的 指定创建组件应用
import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app')