Vue3
官网:https://v3.cn.vuejs.org/
Vue3 One Piece:https://vue3js.cn/#emits
菜鸟教程:https://www.runoob.com/vue3/vue3-tutorial.html
Vue
是一套用于构建用户界面的渐进式框架。
Vue.js
设计的初衷就包括可以被渐进式地采用。这意味着它可以根据需求以多种方式集成到一个项目中。
cnpm
官网:https://npmmirror.com/
安装cnpm
npm install -g cnpm --registry=https://registry.npmmirror.com
使用cnpm
安装模块
cnpm install [name]
Vue CLI
旨在成为Vue
生态系统的标准工具基准。它可确保各种构建工具与合理的默认值一起顺利运行,因此您可以专注于编写应用程序,而不是花费数天时间与配置进行争论。同时,它仍然提供了调整每个工具配置的灵活性,而无需弹出。
安装新程序包
cnpm install -g @vue/cli
cnpm install -g vue-cli cnpm : 无法加载文件 C:\Users\Xiaoyu.Zhang\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Executio n_Policies。 所在位置 行:1 字符: 1 + cnpm install -g vue-cli + ~~~~ + CategoryInfo : SecurityError: (:) [],PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess
解决方案:
以管理员身份运行
PowerShell
输入
set-ExecutionPolicy RemoteSigned
选择
A
新建一个package.json
文件并初始化
npm init -y
在Vue
项目中运行
vue upgrade --next
创建项目
vue create [app-name]
下一代前端开发与构建工具
Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。
安装Vite
cnpm install vite
创建项目
npm init @vitejs/app
√ Project name: … vite-test
√ Select a framework: » vue
√ Select a variant: » vue-tsScaffolding project in D:\BSIT_Project\vue-vite-start\vite-project\vite-test…
Done. Now run:
cd vite-test
npm install
npm run dev
安装依赖
cd 项目名
npm i
运行项目
npm run dev
打开网页
http://localhost:3000/
目录 / 文件 | 说明 |
---|---|
dist | 使用 npm run build 命令打包后会生成该目录。 |
node_modules | npm 加载的项目依赖模块 |
public | 公共资源目录。 |
src | 这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件: assets: 放置一些图片,如logo等。 components: 目录里面放了一个组件文件,可以不用。 App.vue: 项目入口文件,我们也可以直接将组件写这里,而不使用 components 目录。 main.js: 项目的核心文件。 index.css: 样式文件。 |
index.html | 首页入口文件,你可以添加一些 meta 信息或统计代码啥的。 |
package.json | 项目配置文件。 |
README.md | 项目的说明文档,markdown 格式 |
tsconfig.json | |
vite.config.ts |
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
// @ts-ignore
import path from 'path';
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import {ElementPlusResolver} from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
// 在生产中服务时的基本公共路径。类似publicPath,'./'避免打包访问后空白页面,要加上,不然线上也访问不了
base: "./",
resolve: {
// 目录别名
alias: {
"@": path.resolve(__dirname, "src"),
"@assets": path.resolve(__dirname, "src/assets"),
"@components": path.resolve(__dirname, "src/components"),
"@img": path.resolve(__dirname, "src/assets/img"),
"@views": path.resolve(__dirname, "src/views"),
"@store": path.resolve(__dirname, "src/store"),
},
},
// 打包配置
build: {
outDir: "dist", // 指定输出路径
assetsDir: "assets", // 指定静态资源存放路径
sourcemap: false, // 是否构建source map 文件
minify: 'terser', // 混淆器,terser构建后文件体积更小
terserOptions: {
// 生产环境移除console
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
// 本地运行配置,及反向代理配置
server: {
cors: true, // 默认启用并允许任何源
https: false, // 是否开启 https
open: true, // 是否自动在浏览器打开
port: 2048, // 端口号
host: "0.0.0.0",
proxy: {
"/api": {
target: "", // 后台接口(代理接口)
changeOrigin: true,
secure: false, // 如果是https接口,需要配置这个参数
// ws: true, //websocket支持
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
// 引入第三方的配置
optimizeDeps: {
include: ["axios",],
},
})
安装vue-tsc
cnpm install vue-tsc
构建
npm run build
官方文档:https://element-plus.gitee.io/zh-CN/
安装
cnpm install element-plus --save
安装插件
cnpm install -D unplugin-vue-components unplugin-auto-import
在vite.config.ts
中添加
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default {
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}
App.vue
{{ msg }}
{{ data.data }}
{{ msg }}
Using v-html directive:
Hello World
每个绑定都只能包含单个表达式
{{ number + 1 }}
v-on
指令添加一个事件监听器
{{ message }}
v-model
指令实现表单输入和应用状态之间的双向绑定
{{ message }}
v-if
指令进行条件控制
现在你看到我了
v-for
指令可以绑定数组的数据来渲染一个项目列表
-
{{ todo.text }}
为了避免在模板中放入太多的逻辑,使模板过重且难以维护,对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性。
Has published books:
{{ publishedBooksMessage }}
当需要在数据变化时执行异步或开销较大的操作时,watch
选项提供了一个更通用的方法来响应数据的变化。
但是要避免侦听器的滥用!
Ask a yes/no question:
{{ answer }}
// src/components/UserRepositories.vue
export default {
components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
props: {
user: {
type: String,
required: true
}
},
data () {
return {
repositories: [], // 1
filters: { ... }, // 3
searchQuery: '' // 2
}
},
computed: {
filteredRepositories () { ... }, // 3
repositoriesMatchingSearchQuery () { ... }, // 2
},
watch: {
user: 'getUserRepositories' // 1
},
methods: {
getUserRepositories () {
// 使用 `this.user` 获取用户仓库
}, // 1
updateFilters () { ... }, // 3
},
mounted () {
this.getUserRepositories() // 1
}
}
定义子组件
src\componentsHelloWorld.vue
{{ msg }}
src\componentsHelloWorld1.vue
{{ msg }}
src/App.vue
组件测试
通过props
数组形式
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
对象形式
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // 或任何其他构造函数
}
父组件
父组件
子组件
子组件1
通过emit
子组件
子组件2
父组件
传值测试
{{name}}
安装
cnpm install vue-router@4
新建Page1.vue
Page1
{{ msg }}
新建Page2.vue
Page2
{{ msg }}
在src
文件夹下新建router/index.ts
import {createRouter, createWebHashHistory} from "vue-router";
import page1 from '../components/Page1.vue';
import page2 from '../components/Page2.vue';
import Parent from "../components/Parent.vue";
// 定义routes路由的集合,数组类型
const routes = [
// 单个路由均为对象类型,path代表的是路径,component代表组件
{
path: '/',
redirect: '/index'
},
{
path: '/index',
name: 'index',
component: Parent
},
{
path: '/user/:name',
name: 'user',
component: Parent
},
{
path: '/page1',
name: 'page1',
component: page1
},
{
path: '/page2',
name: 'page2',
component: page2
},
]
// 实例化VueRouter并将routes添加进去
const router = createRouter({
history: createWebHashHistory(),
routes
})
// 抛出这个这个实例对象方便外部读取以及访问
export default router
修改App.vue
组件测试
Page1
Page2
Param传参
Query传参
修改main.ts
import {createApp} from "vue";
import App from "./App.vue";
import router from "./router/index";
const app = createApp(App)
// 一定要注入到vue的实例对象上
app.use(router)
app.mount('#app')
export default app
Vuex 是 Vue .js 应用程序的状态管理模式 + 库。它充当应用程序中所有组件的集中存储,其规则确保状态只能以可预测的方式发生变异。
安装
cnpm install vuex@next --save
在src
文件夹下新建stroe/index.ts
import Vuex from 'vuex';
const store = new Vuex.Store({
state: {
// 定义一个name,以供全局使用
name: '张三',
// 定义一个number,以供全局使用
number: 0,
// 定义一个list,以供全局使用
list: [
{id: 1, name: '111'},
{id: 2, name: '222'},
{id: 3, name: '333'},
]
},
});
export default store;
修改main.ts
import {createApp} from "vue";
import App from "./App.vue";
import router from "./router/index";
import store from "./store/index";
const app = createApp(App)
// 一定要注入到vue的实例对象上
app.use(router)
app.use(store)
app.mount('#app')
export default app
修改Page1.vue
Page1
{{ msg }}
官方建议把this.$store.state.XXX
最好放在计算属性中,使代码优雅
Page1
{{ msg }}
使用mapState
解构
Page1
{{ msg }}
import Vuex from 'vuex';
const store = new Vuex.Store({
state: {
// 定义一个name,以供全局使用
name: '张三',
// 定义一个number,以供全局使用
number: 0,
// 定义一个list,以供全局使用
list: [
{id: 1, name: '111'},
{id: 2, name: '222'},
{id: 3, name: '333'},
]
},
// 在store对象中增加getters属性
getters: {
getName(state) { // 获取修饰后的name,第一个参数state为必要参数,必须写在形参上
return `hello${state.name}`;
}
},
});
export default store;
Page1.vue
Page1
{{ msg }}
import Vuex from 'vuex';
const store = new Vuex.Store({
state: {
// 定义一个name,以供全局使用
name: '张三',
// 定义一个number,以供全局使用
number: 0,
// 定义一个list,以供全局使用
list: [
{id: 1, name: '111'},
{id: 2, name: '222'},
{id: 3, name: '333'},
]
},
// 在store对象中增加getters属性
getters: {
getName(state) { // 获取修饰后的name,第一个参数state为必要参数,必须写在形参上
return `hello${state.name}`;
}
},
mutations: {
setNumber(state) {
state.number = 5;
},
setNumberIsWhat(state, number) { // 增加一个带参数的mutations方法
state.number = number;
},
},
});
export default store;
Mutations里面的函数必须是同步操作,不能包含异步操作!
Page1.vue
Page1
{{ msg }}
参考文档:https://juejin.cn/post/6928468842377117709
官方文档:https://axios-http.com/zh/docs/intro
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
安装
cnpm install axios
这里以调用https://api.4gml.com/NeteaseMusic
接口获取网易云热评为例
在src
目录下新建utils/request.ts
import axios from 'axios'
// 让请求在浏览器中允许跨域携带cookie
axios.defaults.withCredentials = true;
// 使用自定义配置新建一个实例
const instance = axios.create({
// url = base url + request url
baseURL: 'https://api.4gml.com',
// 设置超时时间 5s
timeout: 5000,
headers: {'X-Custom-Header': 'foobar'}
});
// 请求拦截器
instance.interceptors.request.use(
config => {
// 在发送请求之前做些什么
return config;
}, error => {
// 对请求错误做些什么
return Promise.reject(error);
}
)
// 响应拦截器
instance.interceptors.response.use(
response => {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
},
error => {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
}
)
export default instance
在src
目录下新建api
目录,在api
目录下新建music.ts
import request from "../utils/request.ts";
export const getMusicReview = () => {
return request({
url: '/NeteaseMusic',
method: 'get',
})
}
修改Page2.vue
Page2
{{ msg }}
Vue3
没有内置支持防抖和节流,但可以使用 Lodash
等库来实现。
cnpm i --save lodash
修改Child2.vue
子组件2
注:@click中对应得是防抖封装后的函数名,而不是Method中的函数名!!!
参考文档:https://blog.csdn.net/zheng_jia_jun/article/details/114577857
cnpm i js-cookie
//创建简单的cookie
Cookies.set('name', 'value');
//创建有效期为7天的cookie
Cookies.set('name', 'value', { expires: 7 });
//为当前页创建有效期7天的cookie
Cookies.set('name', 'value', { expires: 7, path: '' });
Cookies.get('name'); // => 'value'
Cookies.get('nothing'); // => undefined
//获取所有cookie
Cookies.get(); // => { name: 'value' }
Cookies.remove('name');
//如果值设置了路径,那么不能用简单的delete方法删除值,需要在delete时指定路径
Cookies.set('name', 'value', { path: '' });
Cookies.remove('name'); // 删除失败
Cookies.remove('name', { path: '' }); // 删除成功
//注意,删除不存在的cookie不会报错也不会有返回
参考文档:https://www.npmjs.com/package/js-cookie
Vue
中使用localStorage
作为本地存储,解决了 cookie
存储空间不足的问题(cookie中每条cookie的存储空间为4k,localStorage中一般浏览器支持的是5M大小)。
localStorage.setItem('userName', '张三');
localStorage.password = '123456';
localStorage.getItem('userName');
localStorage.password
localStorage.removeItem('userName')
参考文档:https://blog.csdn.net/zhanduo0118/article/details/110060623
cnpm install vue3-lazy -S
主要.js:
import { createApp } from 'vue'
import App from './app'
import lazyPlugin from 'vue3-lazy'
const app = createApp(App)
lazyPlugin.install(app, {
loading: 'loading.png',
error: 'error.png'
})
app.mount('#app')
模板:
-
钥匙 | 描述 | 违约 | 选项 |
---|---|---|---|
error |
加载失败时图像的 src | 'data-src' |
String |
loading |
加载时图像的 src | 'data-src' |
String |
参考文档:https://www.npmjs.com/package/vue3-lazy
path 模块是 Node.js 的东西,需要安装 Node.js 的声明文件
npm i @types/node -D
components
是小组件(可被views
组件复用)containers
是容器级组件(根据项目大小决定是否使用)views
是页面级组件(一般不被复用)const routes = [
{
path: '/index',
name: 'index',
component: Index,
meta: {
title:"这是动态title",
keepAlive: true, // 需要被缓存
content: 'disable',
}
},
]
router.beforeEach((to,from,next) => {
// 路由发生变化修改页面title
if (to.meta.title) {
document.title = to.meta.title;
}
next()
})
主页