• Vue3.2基础及Vant的使用


    Vue3文档

    官方文档 https://cn.vuejs.org/

    demo地址
    https://gitee.com/galen.zhang/vue3-demo/tree/master/vue3-base-api

    Vue3常用插件
    Volar、Vue VSCode Snippets、Auto Close Tag、Vue Peek、Vite

    测试模板文件 template.html

    
    
      
        
        
        Vue模板
        
      
      
        

    Vue实例


    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    指令

    v-model 实现数据和表单元素绑定
    v-model 的修饰符:tirmnumber

    	  

    前面{{msg}}后面


    +={{a+b}}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    v-on 绑定事件,可以简写为 @
    修饰符 https://cn.vuejs.org/guide/essentials/event-handling.html#key-modifiers

    v-bind 绑定属性,可以简写成:

    #script // 对象表示样式的时候,属性名表示样式名,属性值为bool值(true表示生效,false表示无效) classP3: { a: true, b: false, c: true, },
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    watch 监听一个数据的改变,数据改变之后执行一个操作

    computed 计算属性,当依赖的数据改变之后会重新计算一个结果
    计算属性具有缓存功能

    计算属性和方法调用的区别:

    1. 计算属性具有缓存功能,依赖的数据不改变不会重新计算
    2. 计算属性可以直接调用,不需要加括号
    3. 方法调用的时候需要加括号
    4. 方法在每一次组件更新的时候都会重新执行
    // 模拟购物中全选、取消选择,计算总价
          
          
    总价:{{sumPrice}}
    // script data() { return { carts: [ { id: 1, name: "外套", chk: false, amount: 2, price: 100, }, { id: 2, name: "裙子", chk: true, amount: 1, price: 50, }, { id: 3, name: "鞋子", chk: false, amount: 3, price: 200, }, ], }; }, computed: { // 直接返回一个结果,相当于只设置了get double() { console.log("计算属性执行了"); return this.num * 2; }, // 另一种写法 // set表示主动设置值 // get表示被动取值 chkAll: { set(v) { // console.log(v); this.carts.forEach((item) => (item.chk = v)); }, get() { return this.carts.every((item) => item.chk); }, }, sumPrice() { return this.carts .filter((item) => item.chk) // 获取选中的 .reduce((pre, cur) => pre + cur.price * cur.amount, 0); // 求和 }, },
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    refs 获取dom元素
    nextTick Vue中dom更新是异步的,数据改变后无法直接获取dom中的最新值。使用这个api可以获取到

          

    当前的num为:{{num}}

    // script data() { return { num: 1 }; }, methods: { clickHandle() { this.num++; // console.log(this.$refs.txt.innerText); // $nextTick 是一个内置的全局api,可以在其回调函数中获取dom的最新值 this.$nextTick(() => { console.log(this.$refs.txt.innerText); }); }, }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    组件

    自定义标签

    1. 局部组件,定义好之后需要先注册再使用
    2. 全局组件,定义好之后可以直接使用

    组件传参

    1. 父传子,使用props属性
    2. 子传父,使用事件派发
    3. 非相关组件,使用provide/inject依赖注入,或者使用vuex各pinia全局状态管理插件
    
    
      
        
        
        Vue 组件
        
      
      
        

    Vue实例


    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    组件生命周期函数

    8个常见的生命周期钩子函数

    1. beforeCreate
    2. created:调用接口获取数据
    3. beforeMount
    4. mounted:获取dom元素
    5. beforeUpdate,重复执行
    6. updated,重复执行,在5和6两个钩子函数中不能修改数据,改了数据之后会引起死循环
    7. beforeUnmount
    8. unmounted

    下面2个需要配合keep-alive使用。keep-alive可以对组件做缓存

    1. activated,激活
    2. deactivated,取消激活

    嵌套组件的生命周期钩子函数

    1. 先执行到父组件的beforeMount之后,开始解析dom
    2. 当遇到子组件时,会执行所有子组件的创建到挂载完成
    3. 当所有的子组件都挂载完成之后,执行父组件的挂载完成

    component 动态组件,通过is属性控制当前显示哪一个组件

          
          
          
          
          
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    创建单页面应用

    2种创建项目的方式

    1. 使用Vite创建项目
    npm init vite@latest
    
    • 1
    1. 使用 npm create vue@latest
    npm init vite@latest
    vue-demo
    
    #文档
    https://cn.vuejs.org/guide/quick-start.html#creating-a-vue-application
    
    cd vue-demo
    npm install
    npm run dev
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    script setup 语法方式

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    安装路由vue-router

    npm i vue-router
    定义路由文件 router/index.js

    import { createRouter, createWebHashHistory } from "vue-router";
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes: [
        {
          path: "/",
          name: "Home",
          component: () => import("../views/Home.vue"),
        },
        {
          path: "/user",
          name: "User",
          component: () => import("../views/User.vue"),
        },
      ],
    });
    
    //路由前置守卫
    router.beforeEach((to, from, next) => {
      console.log("beforeEach");
      next();
    });
    
    export default router;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    main.js 中引入路由

    import { createApp } from 'vue'
    import './style.css'
    import App from './App.vue'
    import router from './router'
    
    createApp(App).use(router).mount('#app')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    测试一下,在 App.vue 中加入路由链接

    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    demo地址
    https://gitee.com/galen.zhang/vue3-demo/tree/master/vue-demo

    处理组件复用不会再次初始化数据
    http://localhost:5173/#/list // 查询所有数据
    http://localhost:5173/#/list?tid=1

    url路由改变了,但组件复用不会重新初始化

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    computed 计算属性
    如果只需要计算出一个值,参数为一个函数,返回计算的结果
    如果需要主动设置值+被动改变,传入一个对象,里面包含set/get函数

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    安装Vant

    #https://vant-contrib.gitee.io/vant/#/zh-CN
    npm i vant
    
    • 1
    • 2

    main.js 中引入样式

    import { createApp } from 'vue'
    import 'vant/lib/index.css'; // 引入vant的样式库
    import './style.css'
    import App from './App.vue'
    import router from './router'
    
    createApp(App).use(router).mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在页面中引入需要使用的vant组件

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    底部Tabbar组件

    App.vue 中增加Tabbar组件

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    调整整个页面布局 style.css

    html,body,#app {
        height: 100%;
    }
    
    #app {
        display: flex;
        flex-direction: column;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    轮播图Swipe + 宫格Grid

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    侧边导航Sidebar

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    列表List

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    动作栏ActionBar

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    是否需要隐藏底部Tabber

    1. 在路由中添加 meta
        {
          path: "/detail",
          name: "Detail",
          component: () => import("../views/Detail.vue"),
          meta: {
            needHideTabber: true, // 需要隐藏底部Tabber
          },
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. App.vue 中监听路由的变化
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    网络请求

    npm i axios
    // 进度条
    npm i nprogress
    
    #测试后台接口数据
    #https://gitee.com/galen.zhang/vue3-demo/tree/master/honey-home-main/honey-home-server
    
    cd honey-home-server
    npm i # 安装依赖项
    node app.js # 启动项目
    
    http://localhost:1337
    http://localhost:1337/api/products
    
    http://localhost:1337/manager
    #管理页面
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    封装axios使用 utils/request.js

    import axios from "axios";
    import NProgress from "nprogress";
    import "nprogress/nprogress.css";
    
    export const serverUrl = "http://localhost:1337";
    
    const service = axios.create({
      baseURL: serverUrl,
      timeout: 5000,
    });
    
    // Add a request interceptor 全局请求拦截
    service.interceptors.request.use(
      function (config) {
        // Do something before request is sent
        NProgress.start(); // 启动进度条
        // 此处还可以设置token
        return config;
      },
      function (error) {
        // Do something with request error
        return Promise.reject(error);
      }
    );
    
    // Add a response interceptor 全局相应拦截
    service.interceptors.response.use(
      function (response) {
        // Any status code that lie within the range of 2xx cause this function to trigger
        // Do something with response data
        NProgress.done();
    
        // 如果是固定的数据返回模式,此处可以做继续完整的封装
        return response.data;
      },
      function (error) {
        // Any status codes that falls outside the range of 2xx cause this function to trigger
        // Do something with response error
        NProgress.done();
    
        // 此处需要对返回的状态码或者异常信息作统一处理
        return Promise.reject(error);
      }
    );
    
    export const get = (url, params) => {
      return service.get(url, {
        params,
      });
    };
    
    export const post = (url, data) => service.post(url, data);
    
    export const put = (url, data) => service.put(url, data);
    
    export const del = (url, data) => service.delete(url);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    使用样例 api/categories.js

    import { get } from '../utils/request';
    
    /**
     * 获取商品分类
     * @returns
     */
    export const loadCategoriesAPI = () => get('/api/v1/product_categories');
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    封装重复代码到hooks

    创建文件 hooks/use-categories.js

    import { ref } from "vue";
    import { loadCategoriesAPI } from "../api/categories";
    
    export const useCategories = () => {
      const categories = ref([]);
      loadCategoriesAPI().then((res) => (categories.value = res.data));
      return {
        categories,
      };
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用方式

    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
  • 相关阅读:
    Java IO中其它字节流简介说明
    计算机组成原理(2)--进位计数制、BCD码,有符号数和无符号数、浮点数
    目标检测YOLO实战应用案例100讲-面向恶劣环境下的多模态 行人识别(续)
    绍兴市越城区人大常委会主任徐荻一行莅临迪捷软件调研指导
    自动推理的逻辑05--谓词演算
    1.8 信息系统服务管理、1.9 信息系统规划
    管理交换空间
    基于Delft3D模型水体流动、污染物对流扩散、质点运移、溢油漂移及地表水环境报告编制丨掌握模型建立、参数校准、模拟运行和结果分析等实际操作
    【Java】泛型的理解与使用,包装类
    Mac 本地部署thinkphp8【配置环境】
  • 原文地址:https://blog.csdn.net/zf14840/article/details/132788412