目录
mutations mutations修改state中的唯一手段 commit执行
actions 可以手写自己的业务处理异步 dispatch派发
三级联动
由于三级联动在Home Search Detail 把三级联动注册为去全局组件
只需要注册一次,就可以在项目任意地方使用
第一个参数为全局组件的名字,第二个为那个组件
Vue.component(TypeNav.name, TypeNav)
TypeNav 为全局组件不需要引入
网络请求
axios的二次封装
放置在api文件夹中 接口统一处理 挂载到原型Vue.prototype.$api = axios
请求拦截器 requests.interceptors.request.use:可以在发请求之前处理一些业务
响应拦截器 requests.interceptors.response.use:当服务器返回数据之后处理业务
baseURL: '/api' 基础路径,发送请求的时候路径中会出现api
timeout: '5000', 请求超时时间 5s
// 对axios二次封装
import axios from 'axios'
// 利用axios对象方法的created,创建一个axios实例
const requests = axios.create({
//配置对象
// 基础路径,发送请求的时候路径中会出现api
baseURL: '/api',
//请求超时时间 5s
timeout: '5000',
})
//请求拦截器
requests.interceptors.request.use((config) => {
// config配置对象 header请求头
return config
})
//响应拦截器
requests.interceptors.response.use((res) => {
//成功的回调函数
return res.data
}, (error) => {
//响应失败的回调函数
return Promise.reject(new Error('false'))
})
export default requests
跨域问题
协议 域名 端口号 不一致称为跨域
jsonp ,cros, 代理
浏览器跟服务器之间才有跨域问题,服务器跟服务器之间没有
在vue.config.js中配置webpack配置项
//代理跨域
devServer: {
proxy: {
"/api": {
target: "http://gmall-h5-api.atguigu.cn",
pathRewrite: { "^/api": "" }
}
}
}
模块化导入导出
export default{} 导出对象 导入使用 import axios from 'axios'
export const a 导出变量 导入某个变量解构赋值
export const a 导出变量 import * as axios from 'axios' 导入全部变量
vuex状态管理库
vuex是官方提供的插件 状态管理库, 集中式管理项目中的组件共用数据 多个组件依赖同一个值
new Vuex.Store 对象暴露一个store类的一个实例
Vue.use(Vuex) 需要使用插件
state 仓库存储数据的地方
vuex 设置值 const state = {count: 1};
1辅助函数映射为组件的计算属性
数组形式
import { mapState } from "vuex";
computed: {...mapState(["count"])},
对象形式 可以指定键
computed: { ...mapState({ n: "count"}),
函数形式
computed: {
...mapState({
//右侧需要的是一个函数,当使用这个计算属性的时候,右侧函数会立即执行一次
//注入一个state
CategoryList:state=>state.home.CategoryList
}),
2计算属性
computed: {
count() {
return this.$store.state.count;
},
},
3具体的数据名称小胡子语法
{{this.$store.state.count}}
mutations mutations修改state中的唯一手段 commit执行
// state 仓库 payload载荷
add(state, payload) {
state.count++
state.count += payload
}
1.直接执行
this.$store.commit("add", 1);
2辅助函数(也可以是对象自定义事件句柄)
import { mapMutations } from "vuex";
methods: {...mapMutations(["add"])},
<button @click="add(1)">点我加一</button>
actions 可以手写自己的业务处理异步 dispatch派发
// content vuex上下文 payload 载荷
addSync(content, payload) {
content.commit('add', payload)
}
1.直接派发
this.$store.dispatch("add", 1);
2辅助函数(也可以是对象自定义事件句柄)
import { mapActions } from "vuex";
methods: {...mapActions(["addSync"])},
<button @click="addSync(1)">点我加一</button>
getters 计算属性
vuex
showNum(state) {
return state.arr.filter(item => {
return item > 10
})
}
1.直接读取
{{ this.$store.getters.showNum }}
2.计算属性
computed: {
arr() {
return this.$store.getters.showNum;
},
},
3辅助函数映射为组件的计算属性
数组形式
import { mapGetters } from "vuex";
computed: {...mapGetters(["arr"])},
对象形式 可以指定键
computed: { ...mapGetters({ a: "arr"}),
modules 模块化开发
// search 组件的小仓库
const state = {}
const mutations = {}
const actions = {}
const getters = {}
export default {
state,
mutations,
actions,
getters
}
vuex
import Vue from 'vue'
import Vuex from 'vuex'
import home from './home'
import search from './search'
//需要使用插件
Vue.use(Vuex)
// 对象暴露一个store类的一个实例
export default new Vuex.Store({
modules: {
home,
search
}
})
动态添加样式或者类名
动态添加背景颜色
第一种css :hover 伪类选择器 选择器用于选择鼠标指针浮动在上面的元素。
.item:hover {
background: blue;
}
第二种:js
<h3 @mouseenter="changeIndex(index)" @mouseleave="leaveIndex"> </h3>
动态绑定类名 移入元素索引==响应式数据添加样式
:class="{ cur: currentIndex == index }"
data() {
return {
currentIndex: -1,
};
},
methods: {
//鼠标移入改变响应式数据
changeIndex(index) {
//index鼠标移入的索引值
this.currentIndex = index;
},
//鼠标移除的事件
leaveIndex() {
this.currentIndex = -1;
},
},
二三级分类的显示和隐藏、
css display: none; 鼠标滑过display:block
js :style="{ display: currentIndex == index ? 'block' : 'none' }"
函数的防抖和节流
//index鼠标移入的索引值
/正确情况下每一个都会触发鼠标移入事件
// 如果很快只触发部分,由于用户操作行为过快,导致浏览器解析不过来出现卡顿
防抖:前面的所有的触发都取消,最后执行一次 在规定的时间之后才会触发,多次点击只会执行一次
节流:在规定的时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发
防抖:用户操作很频繁但 只执行一次 节流 用户操作很频繁 降低触发频率
lodash插件里面封装了函数防抖与节流【闭包+延迟器】
lodash函数库对外暴露了函数
防抖
input.oninput=_.debounce(function(){
console.log('ajax请求')
},1000)
节流
button.onclick=_.throttle(function(){
//:节流目前这个回调函数5s执行一次,给浏览器解析时间
count++
},5000)
项目应用
// 全部引入
import _ from "lodash";
changeIndex: _.throttle(function (index) {
console.log(index);
this.currentIndex = index;
}, 50),
自定义属性
router-link为vue内部组件如果循环组件会出现延迟
三级联动 最好的解决方案:编程时导航+事件委托
通过自定义属性 :data-categoryName 区分a标签
取自定义属性值:event.target.dataset.自定义属性 对象、浏览器自动把自定义属性转为小写
event事件对象
- 1.自定义属性 :data-自定义属性
- 2.获取自定义属性值:event.target.dataset.自定义属性
goSearch(event) {
// event事件对象
//最好的解决方案:编程时导航+事件委托
// 通过自定义属性 :data-categoryName 区分a标签
//获取自定义属性值:event.target.dataset.自定义属性 对象、浏览器自动把自定义属性转为小写
let element = event.target;
let { categoryname, category1id, category2id, category3id } =
element.dataset;
//如果有自定义属性 categoryname 一定是a标签
if (categoryname) {
let location = {
name: "Search",
};
let query = { categoryName: categoryname };
// 一级二级三级分类的a标签
if (category1id) {
query.category1Id = category1id;
} else if (category2id) {
query.category2Id = category2id;
} else {
query.category3Id = category3id;
}
//整理完整参数
location.query = query;
// 路由跳转
this.$router.push(location);
}
},
过度动画
前提:组件,元素比需要有v-if|v-show 指令才可以进行过度动画
使用内置组件 <transition name="sort"></transition> 要有name
通过样式添加动画
- .sort-enter //开始状态(进入)
- .sort-enter-to //结束状态(移除)
- .sort-enter-active {transition: all 0.5s linear; } //定义动画的时间 速率
路由参数合并
如果既有query参数,右有paramis参数要进行合并避免丢失
goSearch() {
if (this.$route.query) {
let location = {
name: "Search",
params: { keyWord: this.keyWord },
};
location.query = this.$route.query;
this.$router.push(location);
}
},