Vue3学习笔记

Vue3官网:https://v3.cn.vuejs.org/

Vue3 One Piece:https://vue3js.cn/#emits

菜鸟教程:https://www.runoob.com/vue3/vue3-tutorial.html

什么是Vue?

Vue是一套用于构建用户界面的渐进式框架

Vue.js设计的初衷就包括可以被渐进式地采用。这意味着它可以根据需求以多种方式集成到一个项目中。

cnpm(中国 NPM 镜像)

cnpm官网:https://npmmirror.com/

安装cnpm

npm install -g cnpm --registry=https://registry.npmmirror.com

使用cnpm安装模块

cnpm install [name]

Vue CLI

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

解决方案:

  1. 以管理员身份运行PowerShell

  2. 输入

    set-ExecutionPolicy RemoteSigned
    

    选择A

新建一个package.json文件并初始化

npm init -y

Vue项目中运行

vue upgrade --next

创建项目

vue create [app-name]

Vite

下一代前端开发与构建工具

Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。

安装Vite

cnpm install vite

创建项目

npm init @vitejs/app

√ Project name: … vite-test
√ Select a framework: » vue
√ Select a variant: » vue-ts

Scaffolding 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

Element Plus

官方文档: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()],
    }),
  ],
}

HelloWorld

App.vue




Vue语法

插值

文本




原生html




Attribute




JavaScript 表达式

每个绑定都只能包含单个表达式




处理用户输入

事件监听器

v-on 指令添加一个事件监听器




双向绑定

v-model 指令实现表单输入和应用状态之间的双向绑定




条件与循环

条件控制

v-if 指令进行条件控制




v-for 指令可以绑定数组的数据来渲染一个项目列表




计算属性

为了避免在模板中放入太多的逻辑,使模板过重且难以维护,对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性




侦听器

当需要在数据变化时执行异步或开销较大的操作时,watch 选项提供了一个更通用的方法来响应数据的变化。

但是要避免侦听器的滥用!





选项式API

// 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
  }
}

组合式API


组件

定义子组件

src\componentsHelloWorld.vue






src\componentsHelloWorld1.vue






src/App.vue






组件传值

父组件向子组件传值

通过props

Prop类型
  1. 数组形式

    props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
    
  2. 对象形式

    props: {
      title: String,
      likes: Number,
      isPublished: Boolean,
      commentIds: Array,
      author: Object,
      callback: Function,
      contactsPromise: Promise // 或任何其他构造函数
    }
    
静态传值

动态赋值





父子组件传值

父组件






子组件






子组件向父组件传值

通过emit

子组件






父组件






Vue Router

安装

cnpm install vue-router@4

新建Page1.vue






新建Page2.vue






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






修改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

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






官方建议把this.$store.state.XXX最好放在计算属性中,使代码优雅






使用mapState解构






修改器

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






修改Store的值

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






参考文档:https://juejin.cn/post/6928468842377117709

Axios

官方文档: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






防抖和节流

Vue3 没有内置支持防抖和节流,但可以使用 Lodash 等库来实现。

cnpm i --save lodash

修改Child2.vue






注:@click中对应得是防抖封装后的函数名,而不是Method中的函数名!!!

参考文档:https://blog.csdn.net/zheng_jia_jun/article/details/114577857

Cookie

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

localStorage

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

一些错误

import path from ‘path’ 异常

path 模块是 Node.js 的东西,需要安装 Node.js 的声明文件

npm i @types/node -D

views 和 components有什么区别?

  • components 是小组件(可被views 组件复用)
  • containers 是容器级组件(根据项目大小决定是否使用)
  • views 是页面级组件(一般不被复用)

如何为每个界面设置Title

法一

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()
})

法二






你可能感兴趣的:(前端,vue.js,npm,前端)