Vue3快速上手

  • 提供了一套声明式的、组件化的编程模型帮助你高效地开发用户界面

  • 声明式渲染:Vue 基于标准 HTML 拓展了一套模板语法,使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系。

    响应性:Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。

	vue create 项目名
	vue ui

单页 Web 应用(single page web application,SPA)

渐进式 Web 应用(PWA)

PWA(Progressive Web Apps,渐进式 Web 应用)运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。这些应用无处不在、功能丰富,使其具有与原生应用相同的用户体验优势。这组文档和指南告诉您有关 PWA 的所有信息。
来自 https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps

单文件组件SFC

项目结构

src下新建文件夹,除components组件文件夹外,可以文件夹下只有一个index.js,通过ES6语法的export向外暴露提供的对象,然后在main.js中通过import走相对路径获取。

  • store
    • modules目录
      • 各类模块需要的js文件
    • index.js及其他
  • src
    • api 该目录下用axios发请求
    • assets
    • router
    • views 视图组件
    • components 功能型组件(在视图内复用?)
    • store vuex?Pinia用store管理状态(全局数据,基于localstorage等);
      • modules
      • index.js

CSS

在main.js中引入

import '@/assets/styles/index.scss' // global css

组件

生命周期

setup

  • setup属性created定义的函数还需要调用不?

路由

:to=“{ path: tag.path, query: tag.query, fullPath: tag.fullPath }”

在router文件夹下的index.js中import页面并配置路由

引入组件/页面:import,如果组件文件夹有index.vue就可省略具体文件名,写在文件夹级别就可以。

所有路由嵌套都在pages文件夹下的layout页面?

示例中的自定义对象:

  • constantRoutes: 用于配置路由列表
  • router: 用于被其他js文件引用,通过Vue3的createRouter方法
import { createWebHistory, createRouter } from 'vue-router'
import Layout from '@/layout'

/**
 * Note: 路由配置项
 *
 * hidden: true                     // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
 * alwaysShow: true                 // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
 *                                  // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
 *                                  // 若你想不管路由下面的 children 声明的个数都显示你的根路由
 *                                  // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
 * redirect: noRedirect             // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
 * name:'router-name'               // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题。也可以在其他路由路径的redirect中直接使用'router-name' 
 * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
 * meta : {
    noCache: true                   // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
    title: 'title'                  // 设置该路由在侧边栏和面包屑中展示的名字
    icon: 'svg-name'                // 设置该路由的图标,对应路径src/assets/icons/svg
    breadcrumb: false               // 如果设置为false,则不会在breadcrumb面包屑中显示
    activeMenu: '/system/user'      // 当路由设置了该属性,则会高亮相对应的侧边栏。
    name? 用于匹配规则 
    requireAuth?
  }
 */

// 公共路由列表
export const constantRoutes = [
  {
    path: '/redirect',
    component: Layout,
    hidden: true,
    children: [
      {			//路由开头不加/也行
        path: '/redirect/:path(.*)',
        component: () => import('@/views/redirect/index.vue')
      }
    ]
  },
    {
    path: '',
    component: Layout,
    redirect: 'index',
    children: [
      {
        path: 'index',
        component: () => import('@/views/index'),
        name: 'Index',
        meta: { title: '首页', icon: 'dashboard', affix: true }
      }
    ]
  },
  {
    path: '/user',
    component: Layout,
    hidden: true,
    redirect: 'noredirect',
    children: [
      {
        path: 'profile',
        component: () => import('@/views/system/user/profile/index'),
        name: 'Profile',
        meta: { title: '个人中心', icon: 'user' }
      }
    ]
  }
];

// 动态路由,基于用户权限动态去加载
export const dynamicRoutes = [
  {
    path: '/system/user-auth',
    component: Layout,
    hidden: true,
    permissions: ['system:user:edit'],
    children: [
      {
        path: 'role/:userId(\\d+)',
        component: () => import('@/views/system/user/authRole'),
        name: 'AuthRole',
        meta: { title: '分配角色', activeMenu: '/system/user' }
      }
    ]
  },
  {
    path: '/system/role-auth',
    component: Layout,
    hidden: true,
    permissions: ['system:role:edit'],
    children: [
      {
        path: 'user/:roleId(\\d+)',
        component: () => import('@/views/system/role/authUser'),
        name: 'AuthUser',
        meta: { title: '分配用户', activeMenu: '/system/role' }
      }
    ]
  },
   {
    path: "/:pathMatch(.*)*",
    component: () => import('@/views/error/404'),
    hidden: true
  },
  {
    path: '/system/dict-data',
    component: Layout,
    hidden: true,
    permissions: ['system:dict:list'],
    children: [
      {
        path: 'index/:dictId(\\d+)',
        component: () => import('@/views/system/dict/data'),
        name: 'Data',
        meta: { title: '字典数据', activeMenu: '/system/dict' }
      }
    ]
  },
  {
    path: '/monitor/job-log',
    component: Layout,
    hidden: true,
    permissions: ['monitor:job:list'],
    children: [
      {
        path: 'index',
        component: () => import('@/views/monitor/job/log'),
        name: 'JobLog',
        meta: { title: '调度日志', activeMenu: '/monitor/job' }
      }
    ]
  },
  {
    path: '/tool/gen-edit',
    component: Layout,
    hidden: true,
    permissions: ['tool:gen:edit'],
    children: [
      {
        path: 'index/:tableId(\\d+)',
        component: () => import('@/views/tool/gen/editTable'),
        name: 'GenEdit',
        meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
      }
    ]
  }
]

// 防止连续点击多次路由报错
let routerPush = Router.prototype.push;
Router.prototype.push = function push(location) {
  return routerPush.call(this, location).catch(err => err)
}


const router = createRouter({
  history: createWebHistory(),//?
  routes: constantRoutes,
  scrollBehavior(to, from, savedPosition) {//?
    if (savedPosition) {
      return savedPosition
    } else {
      return { top: 0 }
    }
  },
});

export default router;

cloud版本没有permission

外链示例

{
  path: 'http://ruoyi.vip',
  meta: { title: '若依官网', icon : "guide" }
}

引入组件的方式:在开头引入,或者在需要的地方用函数表达式引入

  • 是import方法的返回值?

在组件中用<router-view>定义路由显示的位置。App.vue中就有<router-view>

默认路由为路由列表中的第一个路由。(ruoyi中默认为主页然后没前端检测没token被拦截跳转)

静态路由

代表那些不需要动态判断权限的路由,如登录页、404、等通用页面,在@/router/index.js (opens new window)配置对应的公共路由。

动态路由

代表那些需要根据用户动态判断权限并通过addRoutes动态添加的页面,在@/store/modules/permission.js (opens new window)加载后端接口路由配置。

  • index.vue干嘛的?

可复用 & 组合是什么意思?难道说不是组件而是所有的可复用?框架允许复用的东西?

ref 有三种用法:
  1、ref 加在普通的元素上,用this.$refs.(ref值) 获取到的是dom元素

2、ref 加在子组件上,用this. r e f s . ( r e f 值)获取到的是组件实例,可以使用组件的所有方法。在使用方法的时候直接 t h i s . refs.(ref值) 获取到的是组件实例,可以使用组件的所有方法。在使用方法的时候直接this. refs.ref值)获取到的是组件实例,可以使用组件的所有方法。在使用方法的时候直接this.refs.(ref值).方法() 就可以使用了。
ref值是指html标签中设置属性ref的值。

可以这么理解:vue3中某一对象的$refs属性就是包含所有ref的对象。ref可一试方法、标签等

  • ref方法干什么的?

  • comupted

API

<script setup name="">单文件组件的语法糖

Vuex4.x

都是vue官方提供的功能(路由也是)。

  1. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

曾经组件中数据是单向传递,现在值可以由vuex统一管理。

React:UI = fn(state)

elm:UI = state + effect

主要概念:

状态管理,其实也是本地数据存储(store)管理。需要存储、操作、获取功能

  • state:定义变量一样定义存储的数据
  • mutation:对数据的操作,类似web开发三层架构的dao层,直接操作数据
  • action:调用mutation操作数据,类似service和dao的区别;可以异步

State | Vuex (vuejs.org)

  • SSOT?
  • plain?

用法

  • 项目根目录
    • src
      • store

    • main.js

在index.js中创建并export

在main.js中引入并注册

在 Vue 组件中获得 Vuex 状态

那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是响应式?的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态:

// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。

$store.state.count 

默认的this可以省

Mutation

定义方法,传递其他参数可以写在state添加一个对象(最多传入一个state和另一个参数,多个参数只能以一个对象包装进去)

  mutations: {
    SET_TOKEN: (state, token) => {
      state.token = token
    },
    SET_EXPIRES_IN: (state, time) => {
      state.expires_in = time
    },
    SET_NAME: (state, name) => {
      state.name = name
    }
  }

根据方法名调用

store.commit('increment')

getters

对共享数据计算一次

store

util包中的auth.js

import Cookies from 'js-cookie'

const TokenKey = 'Admin-Token'

const ExpiresInKey = 'Admin-Expires-In'

export function getToken() {
  return Cookies.get(TokenKey)
}

export function setToken(token) {
  return Cookies.set(TokenKey, token)
}

export function removeToken() {
  return Cookies.remove(TokenKey)
}

export function getExpiresIn() {
  return Cookies.get(ExpiresInKey) || -1
}

export function setExpiresIn(time) {
  return Cookies.set(ExpiresInKey, time)
}

export function removeExpiresIn() {
  return Cookies.remove(ExpiresInKey)
}

18 其它个人总结

在vscode中使用vue模板:

vue然后按!

子组件就像吕布一样,先被导入,然后在父组件的子组件中注册自己,然后使用

单页应用:页面的dom结构一直在变化,而传统前后端项目,每次返回一个完整网页

Element UI Plus

布局

el-col不指定span会占据一整行倒是换行。。

interface Tree {
  id: number
  label: string
  children?: Tree[]
}
let id = 1000

const append = (data: Tree) => {
  const newChild = { id: id++, label: 'testtest', children: [] }
  if (!data.children) {
    data.children = []
  }
  data.children.push(newChild)

}
const renderContent = (
  h,
  {
    node,
    data,
    store,
  }: {
    node: Node
    data: Tree
    store: Node['store']
  }
) => {
  return h(
    'span',
    {

    },
    h('span', null, node.label),
    h(
      'span',
      null,
      h(
        'a',
        {
          onClick: () => append(data),
        },
        '禁用'
      )
    )
  )
}

渲染函数

node

提前把这个类写一遍,是单例模式的对象声明?

setup里不能有export

js变量必须用var或者let声明?

Tree组件

slot就是写个template

节点点击事件经常传入两个参数,node和data

node: 节点本身的代理对象

  • level 几级结点
  • isLeaf 是否为叶子结点
  • parent 父节点代理对象
    • id 应该是节点的id
    • data:父节点数据,如果有id则在里面

data:节点的数据

有些属性要带上v-bind才能使用,比如

<el-rate v-model="form.rank" :max="5" show-score allow-half/>

的:max

渲染函数

<h1>{{ blogTitle }}</h1>

或者一个渲染函数里:

render() {
  return h('h1', {}, this.blogTitle)
}

在这两种情况下,Vue 都会自动保持页面的更新。

Vue通过创建虚拟Dom树的结点VNode来追踪和管理dom

最后的子渲染函数,似乎也可以不用数组,直接传入多个参数

  • 和js数组、可变参数的特性有关么

一个嵌套渲染、并渲染图标的例子:

const renderContent = (
  h,
  {
    node,
    data,
    store,
  }: {
    node: Node
    data: Tree
    store: Node['store']
  }
) => {
  return h(
    'span',
    {
      class: 'custom-tree-node',
    },[
        h('span', null, node.label),
        h('svg', {
            class: "svg-icon",
            'aria-hidden': "true"
        }, h(
            'use',
            {
                'xlink:href': "#icon-dict"
            },
            null
        )),
        h(
          'span',
          null,
          h(
            'a',
            {
              // onClick: () => append(data),
            },
            '禁用'
          )
        )
    ]
  )
}

如果这时prop时,对象的key含有’:‘、’-'等字符,可以用单引号将键值对中的键括起来

Vue2主要区别

.native修饰符过时

xxx.sync(注:v-bind和sync) v-model:xxxx:

slot-scope #default=“scope”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值