(笔记)首个vue2项目笔记
后台管理系统总结
页面:https://gitee.com/my-little-mars/vue2-manage.git
后台:https://gitee.com/my-little-mars/vue_manage_flask.git
- 项目说明:首页为app.vue,挂载一个
<router-view></router-view>
,用于将主页以及后续跳转的页面进行匹配,在路由中,绑定 / 路径定向到HomeView.vue页面,再重定向到 /main 页面(MainView.vue),其余所有页面均在home页面下面操作。 - 页面简介: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父组件向子组件传值,子组件中定义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是第几个引用的子组件,一个子组件也需要填写。
- 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 就会解决或拒绝,也就是返回第一个返回值的内容。
- Axios
Axios是一个基于promise的http库,可以在vue中的main.js中定义到vue的原型中
Vue.prototype.$axios = axios
。也可以自己封装一份axios的实例,在实例中定义baseurl => 定义HttpRequest类(请求拦截、响应拦截,request实例) => 导出对象 => 使用对象传入参数 => 请求
- 插槽
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基础
- state
state用于存放vuex中的状态数据,可以通过
this.$store.state.count
获得,也可以通过辅助函数,在需要使用state的页面。
import { mapState } from 'vuex'
computed:{
...mapState({
tags: (state) => state.tags,
})}
- 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')
})
}
- moudles
模块化的操作,将store分割成模块,每个模块拥有自己的state、mutation、getter、action。
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
模块化后的调用:
this.$store.state.a
- cookie
cookie本身不是vuex的内容,但是本代码中,使用vuex+cookie实现持久化的用户登录,所以放在一起写,在vuex定义中使用
import Cookies from "js-cookie"
引入cookie,cookie将在用户本地储存,主要用到的函数是Cookie.get Cookie.set Cookie.remove
三、vue-router基础
- 调用方法
<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中
- 嵌套路由
当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,
},
],},]
- 传值
一共有三种传值方法,其中动态路由需要在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
- 路由守卫
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 组件路由守卫:
beforeRouteEnter
、beforeRouteLeave
,在script里面定义
beforeRouteEnter(to, from) {
// 在渲染该组件的对应路由被验证前调用
// 不能获取组件实例 `this` !
// 因为当守卫执行时,组件实例还没被创建!
},
beforeRouteLeave(to, from) {
// 在导航离开渲染该组件的对应路由时调用
// 它可以访问组件实例 `this`
// 验证数据是否输入完成
},
四、其他
- 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可以不写。
- 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