likes
comments
collection
share

(笔记)首个vue2项目笔记

作者站长头像
站长
· 阅读数 51

后台管理系统总结

页面:https://gitee.com/my-little-mars/vue2-manage.git
后台:https://gitee.com/my-little-mars/vue_manage_flask.git
  1. 项目说明:首页为app.vue,挂载一个<router-view></router-view>,用于将主页以及后续跳转的页面进行匹配,在路由中,绑定 / 路径定向到HomeView.vue页面,再重定向到 /main 页面(MainView.vue),其余所有页面均在home页面下面操作。
  2. 页面简介:home页面中使用了了elementUI中的container布局,将页面分成Aside、Header和Main三部分,Head和Aside部分基本不用变,因此固定成为组件,main页面主要为左侧菜单栏目进行点击跳转变化的页面,上方有一个elementUI的面包屑组件,也被封装成为组件,固定在header下面。

Main页面:使用Layout布局,将页面分为一行两列,第一列分为两个el-card 一个用来盛放基本信息,一个用来放table的统计内容,有意思的点在于,渲染table表头的时候,使用tablelabel储存表头信息,进行v-for渲染,缩减了代码量。第二列,分为三个el-card,用于放标签图和两个echart图。

User页面:用户的增删改查,用了elementUI的table组件,进行table的增删改查,table进行二次封装,数据与组件绑定,此处父子组件传值,从而实现双向修改的效果。

Login页面:用户登录页面,主要使用了路由守卫,将该ip下面的所有页面跳转前验证本地是否有cookie,有的话验证通过,没有的话,跳转到login页面进行登录验证,使用了elementUI中的table组件。

一、vue记录

  1. 子父组件传值

1.1父组件向子组件传值,子组件中定义props,父组件当做参数传递回去。 1.2子组件向父组件传值,在子组件中某个事件中绑定methods使用 this.$emit("change", params) change是父组件中接受数据的函数,params是参数,子组件中可以使用 $event传递事件,父组件中使用 @change='receive' 接受消息。 1.3其次可以使用$parent$children this.$parent.fatherdata = this.childdata 直接将子组件中的值赋给父组件中的参数。 this.$children[index].childdata = this.fatherdata 将父组件中的值赋给子组件,index是第几个引用的子组件,一个子组件也需要填写。

  1. promise

2.1promise本身是一个构造函数,自己身上有all、reject、resolve几个方法,原型上有then和catch。该对象只有三种状态:pending、fullfilled、rejected。 2.2promise之接受两个函数作为参数,一个是resolve函数,一个是reject函数,当promise的状态变成resolve的时候,将执行resolve(params),然后将参数传递给then的第一个回调函数,变成reject的时候将执行reject(params)里的参数传递给catch或者then里的第二个回调函数。其中then本质上返回了一个新的promise对象,继续执行里面的函数。 2.3promise的其他函数: Promise.prototype.finally() finally 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。

Promise.all(iterable) 在 iterable 参数内所有的 promise 都 resolved 或参数中不包含 promise 时回调完成(resolve)Promise.all 返回的 promise 的完成状态的结果是一个数组,它包含所有的传入迭代参数对象的值(也包括非 promise 值) 如果参数中 promise 只要有一个 rejected,此实例回调失败( reject )。而不管其它 promise 是否完成,调用第失败的原因,进入catch()。 例子:

Promise.all([
    getJson('/posts.json'),
    getJson('/post/1.json')
    ])
  .then(values => {
    // posts.json 和 post/1.json 都请求回来后,进入到这里
    // 请求回来的数据存储在 values 里面,
    // 顺序跟请求的一样 [ posts.json的结果, post/1.json的结果 ]
        console.log(values)
        }).catch(err => {
                console.error(err)
                })

Promise.race(iterable) 一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝,也就是返回第一个返回值的内容。

  1. Axios

Axios是一个基于promise的http库,可以在vue中的main.js中定义到vue的原型中Vue.prototype.$axios = axios。也可以自己封装一份axios的实例,在实例中定义baseurl => 定义HttpRequest类(请求拦截、响应拦截,request实例) => 导出对象 => 使用对象传入参数 => 请求

  1. 插槽

4.1插槽内容,在使用组件的时候一般<component></component>中间不加任何内容,但是想在这个中间加入内容,例如button,则在子组件中定义一组<slot></slot>,使用组件的时候在component中间添加内容 4.2具名插槽,在使用插槽的时候,希望使用多个插槽,例如header、main、footer,三个地方都想使用slot填充内容,我们给slot添加一个name属性<slot name="footer"></slot>,之后再父组件中使用template中的v-slot属性定义name。

  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

4.3作用域插槽,有时候让插槽能访问到子组件中的变量是很有用的,所以我们在定义插槽时,给定<slot v-bind:params='params'>这样在父级元素可以在具名插槽的基础上定义值,这里的slotProps即是自定义的name,用别的也可以。

<template v-slot:default="slotProps">
   {{ slotProps.user.firstName }}
</template>

4.4缩写,最复杂的情况是slot既需要名字又需要绑定变量, 子组件中的写法是: <slot name='default' v-bind:user='user'></slot> 简写:<slot name='default' :user='user'></slot> 父组件中的写法是: <template v-slot:default='slotProps'> 简写:<template #default='slotProps'>

二、vuex基础

  1. state

state用于存放vuex中的状态数据,可以通过this.$store.state.count获得,也可以通过辅助函数,在需要使用state的页面。

import { mapState } from 'vuex'
  computed:{
  ...mapState({
      tags: (state) => state.tags,
          })}
  1. mutation

mutation是更改vuex的唯一方法,接受state为第一个参数,该函数内必须是同步操作。

  const store = createStore({
  state: {
      count: 1
  },
  mutations: {
      increment (state,n) {
      // 变更状态
      state.count += n
      }
  }
  })

调用方法:this.$store.commit('increment',10),也可以使用辅助函数:

methods: {
  ...mapMutations({
    increase: "increment",// 将this.increse() 映射为 this.$store.commit('increment')
  })
}
  1. moudles

模块化的操作,将store分割成模块,每个模块拥有自己的state、mutation、getter、action。

const moduleA = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... },
      getters: { ... }
      }

模块化后的调用:this.$store.state.a

  1. cookie

cookie本身不是vuex的内容,但是本代码中,使用vuex+cookie实现持久化的用户登录,所以放在一起写,在vuex定义中使用import Cookies from "js-cookie"引入cookie,cookie将在用户本地储存,主要用到的函数是Cookie.get Cookie.set Cookie.remove

三、vue-router基础

  1. 调用方法

<router-link to="/">Go to Home</router-link> 类似于<a>标签,但是这样可以不刷新页面更改url,并且将匹配到的路由组件渲染在router-view里面。 <router-view></router-view>将显示与url相对应的组件。 router.push(...)绑定在事件中,本质和router-link一致 创建方法:定义路由组件 => 定义路由(routes) => 创建实例并传递routes配置(router) => 挂载到app中

  1. 嵌套路由

当url之间存在父子关系时,例如/user和/user/cs,cs在user下面,并且匹配user页面下的组件,这种情况可以使用路由嵌套的规则,此时在app.vue中挂在了一个<router-view>,当router-view指向/user的时候,user页面中还有<router-view>,此时将user下面的路由放在user的children属性里即可,例如:

const routes = [
{
  path: '/user/:id',
  component: User,
  children: [
    {
      path: 'profile',
      component: UserProfile,
    },
    {
      path: 'posts',
      component: UserPosts,
    },
  ],},]
  1. 传值

一共有三种传值方法,其中动态路由需要在route里设置动态参数,params和query两种方法不需要在route里设置动态参数。需要注意path和params不能一起用,最好path+query,name+params。 3.1 动态路由拼接传值

// 在url中传参则在routes里面首先定义
  const routes = [  { path: '/users/:id', component: User }]
// 跳转方法:均跳转到-> /user/eduardo
router.push(`/user/${username}`) 
router.push({ path: `/user/${username}` }) 
// 调用方式
this.$route.params.id

3.2 params传值

// 不需要在routes里面定义动态变量
router.push({ name: 'user', params: {username:this.username} })
// 调用方式
this.$route.params.username

3.3 query传值

// path和params不能一起用,最好path+query,name+params
router.push({ path: '/user', query:{username:this.username}})
// 调用方式
this.$route.query.username
  1. 路由守卫

4.1 全局前置路由守卫:router.beforeEach,需要三个参数,to、from、next,to是即将去往的路径,from是即将离开的路径,next是是否放行,to和from可以获得routes里的参数例如name。如果不加next参数,可以直接用return {name: xxx}或者return false

router.beforeEach(async (to, from) => {
    if (
      !isAuthenticated && to.name !== 'Login'
    ) {
      // 将用户重定向到登录页面
      return { name: 'Login' }
    }
})

4.2 路由独享的守卫:在进入固定路由之前定义的。

const routes = [
{
  path: '/users/:id',
  component: UserDetails,
  beforeEnter: (to, from) => {
    return false
  },
},]

4.3 组件路由守卫:beforeRouteEnterbeforeRouteLeave,在script里面定义

 beforeRouteEnter(to, from) {
  // 在渲染该组件的对应路由被验证前调用
  // 不能获取组件实例 `this` !
  // 因为当守卫执行时,组件实例还没被创建!
},
beforeRouteLeave(to, from) {
  // 在导航离开渲染该组件的对应路由时调用
  // 它可以访问组件实例 `this`
  // 验证数据是否输入完成
},

四、其他

  1. echarts基础逻辑

其本质是定义一个echarts的dom元素,在script里面获取该dom,然后初始化echarts实例,配置option,最后将配置和数据显示到图表。

<!-- 定义一个echarts的容器 -->
<div style="height: 280px" ref="echarts"></div>
const U = echarts.init(this.$refs.echarts) // 获得echarts元素
U.setOption(useroption) // 将配置和数据放到echarts元素中去

不同的图需要配置不同的option,option里面公共的都有:title、tooltip、legend、color、series或者source、xAxis、yAxis,其中tooltip、legend、yAxis可以不写。

  1. elementUI注意点

elementUI有很多有用的组件,主要用到的有:layout、container布局、icon图标、button、form表单系列,table表格,pagination分页,notice系列,navmenu导航菜单,breadcrumb面包屑,dialog对话框,card卡片,carousel走马灯,有意的是,可以多个渲染的例如form和table,都会有一个item<el-form-item> <el-table-column>,然后绑定model或者data,做渲染的时候,可以定义一个tableLabel,渲染表头,数据从数据库拿出来。面包屑制作的时候,其实是从vuex从拿出一个tablist,整体渲染上去,每次点击一个页面的时候,在vuex的tablist中追加一个路由栈。

转载自:https://juejin.cn/post/7221413753731301435
评论
请登录