1、关闭eslint校验工具
//创建vue.config.js文件:需要对外暴露
module.exports = {
lintOnSave:false,
}
2、v-show与v-if区别?
v-show:通过样式display控制
v-if:通过元素上树与下树进行操作
3、路由传参
params参数:路由需要占位,程序就崩了,属于URL当中一部分
:keyword 就是占位
:keyword? 问号是可以选择传也可以选择不传
path不可以和params参数一起使用,程序会崩掉
示例: {
path: '/Search/:keyword?',
name: 'Search',
meta:{show:true},
component: () => import('@/views/Search/index.vue')
},
用法:this.router.push({
name:'Search',
params:{
keyword : 1
}
})
query参数:路由不需要占位
4、axios二次封装
//引入axios
import axios from 'axios'
//引入进度条 请求时出现的进度
import nprogress from 'nprogress';
//引入相关进度条的样式
import "nprogress/nprogress.css";
//引入store vuex仓库
import store from '@/store/index.js';
//创建一个axios实例
const requests = axios.create({
//basUrl地址
basUrl:'http://gmall-h5-api.atguigu.cn',
//请求超时时间
timeout:5000,
})
//请求拦截
requests.interceptors.request.use((config) =>{
//store.state.shopcart.USER_ID vuex里的shopcart里面的数据
//判断在请求头加uid
if(store.state.shopcart.USER_ID){
config.headers.userTempId = store.state.shopcart.USER_ID
}
//判断在请求头加token
if(store.state.user.token){
config.headers.token = store.state.user.token
}
//进度条开始
nprogress.start();
return config
})
//响应拦截
requests.interceptors.response.use((res)=>{
//成功的回调
nprogress.done(); //进度条结束
return res.data // 成功后返回的数据
},(error)=>{
//失败的回调
return Promise.reject(new Error('faile')) // 失败后返回的数据
});
//暴露出去
export default requests
5、api统一管理
//统一管理项目前部的接口
import requests from "@/api/request.js";
// 默认暴露变量 searchList
// params 接收的参数
// url: '/api/list', 接口
// method: 'post', 请求方式
//data:params 传给服务区的参数
export const searchList = (params) => {
return requests({
url: '/api/list',
method: 'post',
data:params
});
}
6、将api里的接口暴露出去
//在main.js引入
//将项目全部请求函数引入进来[分别暴露]
import * as http from '@/api/index.js';
<b>6、将api引入的 http 挂载到原型上</b>
new Vue({
router,
store,
render: h => h(App),
beforeCreate() {
//通过Vue.prototype原型对象,将全部请求函数挂载到原型对象身上[VC:就可以使用请求函数]
Vue.prototype.$http = http
},
}).$mount('#app')
8、vuex
Vuex核心概念:state、actions、mutations、getters、modules
state 存放数据的地方
mutations 修改 state里面数据的地方
actions 用方法的地方
getters 把state数据简化的地方
页面中使用vuex
1 、 直接使用 this.$store.state.home.bannerList 意思是vuex里的state里home下的bannerList
2、 计算属性调用
2.1 引入import {mapState} from 'vuex'
2.2 取 computed:{
...mapState({
bannerList:(state)=>{
console.log(state.home.bannerList);
return state.home.bannerList
},
})
},
3、调用vuex里的actions里的方法 派发categoryList 方法
this.$store.dispatch('categoryList')
9、组件实例的一个方法:$nextTick
this.$nextTick(()=>{
})
nextTick官网解释:
在下次DOM更新, 循环结束之后,执行延迟回调。在 修改数据之后 立即使用这个方法,获取更新后的DOM。
注意:组件实例的$nextTick方法,在工作当中经常使用,经常结合第三方插件使用,获取更新后的DOM节点
10、合并参数
let locations = {
name: "Search",
params: {
keyword: this.keyword || undefined
},
};
//确定路径当中有query参数
if (this.$route.query.categoryName) {
//如果有的话 在locations对象里追加一个query字符
locations.query = this.$route.query;
}
this.$router.push(locations);
11、 watch监听事件
当值发生改变的时候调用
watch: {
a: {
//newName 改变前的值
// oldName 改变后的值
handler(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
},
// 代表在wacth里声明了a这个方法之后立即先去执行handler方法,如果设置了false,那么效果和上边例子一样
immediate: true // 进入组件的时候,第一次并不会执行watch,只有值发生改变才会执行 , 是因为immediate 默认 false
deep: true // 深度监听
}
}
12、组件传参
父传子
父
<Hot :list="date"></Hot>
子
popst:["list"]
子传父
子
this.$emit('getPageNo',1)
父
<Hot @getPageNo="getPageNo" ></Hot>
在方法里写
getPageNo(index) {
console.log(index);
},
13、自定义分页
观察components下的Pagination
props: ['pageNo', 'pageSize', 'total', 'pagerCount'],
pageNo子组件传过来的当前第几页
pageSize 一页几条
total 总页数
pagerCount 中间的几个按钮挨一块
14、push与replace区别?
编程式导航:push 与 replace
能不能记录历史记录:push(能记住历史记录) replace(不能记住历史记录)
目前项目当中:进行路由跳转(编程式导航)基础都是push
push与replace是有区别的
15、导航守卫
三大守卫: 全局守卫 、路由独享守卫 、 组件内守卫
全局守卫:
项目当中任何路由变化都可以检测到,通过条件判断可不可以进行路由跳转。
前置守卫:路由跳转之前可以做一些事情。
后置守卫:路由跳转已经完成在执行。
示例 router 是路由那个数组
router.beforeEach(async (to, from, next) => {
//to:去的那个路由的信息
//from:从那个路由而来的信息
//next:放行函数!!!!!!
//第一种:next(),放行函数,放行到它想去的路由!!!
//第二种:next(path),守卫指定放行到那个路由去?
//用户是否登录:取决于仓库里面是否有token!!!
//每一次路由跳转之前需要用有用户信息在跳转,没有发请求获取用户信息在跳转!!!!
//获取token
let token = store.state.user.token;
//用户信息
let name = store.state.user.userInfo.name;
if(token){
//登录了去登录页
if(to.path == '/Login'){
//不让去,让直接去首页
next('/')
}else{
//登录了去其他页
if(name){
next()
}else{
// 派发获取用户信息
store.dispatch('getUserInfo').then(res=>{
//成功获取的情况下放行
if(res){
next()
}else{
//token 失效了(过期了)
//调退出登录接口
//退出登录有清除token等方法
store.dispatch('logout').then(res=>{
next('/Login')
})
}
})
}
}
}else{
//用户未登录||目前的判断都是放行.将来这里会'回手掏'增加一些判断
//用户未登录:不能进入/trade、/pay、/paysuccess、/center、/center/myorder /center/teamorder
let toPath = to.path;
if (toPath.indexOf('/Trade') != -1 || toPath.indexOf('/Pay') != -1 || toPath.indexOf('/Center') != -1) {
alert('请先登录')
next('/login?redirect='+toPath);
} else {
next();
}
}
});
路由独享守卫:
{
path: '/Trade',
name: 'Trade',
meta:{show:true},
component: () => import('@/views/Trade/index.vue'),
//路由独享守卫
beforeEnter: (to,from,next) =>{
//to:去的那个路由的信息
//from:从那个路由而来的信息
//next:放行函数!!!!!!
console.log(to)
if(to.query.page){
if(from.path == '/shopCart'){
next()
}
}else{
next(from.path);
}
}
},
16、element-ui官方UI组件库(插件)?
官网地址:https://element.eleme.cn/#/zh-CN
第二步:在入口文件引入elementUI组件库
第一种:全部引入【不采用:因为项目中只是用到一个组件,没必要全都引入进来】
第二种:按需引入【按照开发需求引入相应的组件,并非全部组件引入】
第三步:按需引入,安装相应的插件
install babel-plugin-component -D
文档中说的.babelrc文件,即为babel.config.js文件
修改完babel.config.js配置文件以后,项目重启
第四部:按照需求引入相应的组件即可
Vue.component();
Vue.prototype.$xxx = xxx;
17、二级路由
{
path: '/Center',
name: 'Center',
meta:{show:true},
component: () => import('@/views/Center/index.vue'),
children:[
{
path:'/center',
redirect:'/center/myorder'
// redirect 从定义向
},
{
path: 'myorder',
meta:{show:true},
component: () => import('@/views/Center/myOrder/index.vue'),
}, {
path: 'groupOrder',
meta:{show:true},
component: () => import('@/views/Center/groupOrder/index.vue'),
}
]
}
18、组件的通讯方式
1、props/$emit 父组件向子组件传值 子组件向父组件传值
2、$bus main.js写
new Vue({
router,
store,
render:h => h(App),
beforeCreate() {
//全局事件总线$bus配置
Vue.prototype.$bus = this;
},
}).$mount('#app')
使用
// clear 事件名
this.$bus.$on("clear", () => {
})
3、vuex
4、$attrs/$listeners
//可以获取父组件传递过来的数据
$attrs只代表的是那些没有被声明为props的属性,如果某个prop被子组件中声明了(就是这个属性已经在子组件的props中了),在子组件中的$attr会把声明的prop剔除。
console.log(this.$attrs)
打印{
size: "min",
type: "success"
}
父组件 <butt type="success" size="min"></butt>
子组件里的代码 <el-button v-bind="$attrs" ></el-button> 子组件不能用:冒号要用v-ban
$listeners
父组件 <butt type="success" size="min" @click=header></butt>
子组件里的代码 <el-button v-bind="$attrs" v-on="$listeners" ></el-button>
header(){
console.log(666)
}
$listeners 他可以获取打到父组件给子组件传递的自定义事件
5、$parent / $children与 ref
ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
$parent / $children:访问父 / 子实例
19、混入mixin
将组件的公共逻辑或者配置提取出来,哪个组件需要用到时,直接将提取的这部分混入到组件内部即可
用法
引入 import { mixins } from '@/views/mixin/index.js' //混入
mixins: [mixins], // data 同等级
mixin/index.js 代码
export const mixins = {
data() {
return {
msg: "我是小猪课堂",
};
},
computed: {},
created() {
console.log("我是mixin中的created生命周期函数");
},
mounted() {
console.log("我是mixin中的mounted生命周期函数");
},
methods: {
clickMe() {
console.log("我是mixin中的点击事件");
},
},
};