目录
三级联动
网络请求
axios的二次封装
跨域问题
模块化导入导出
vuex状态管理库
state 仓库存储数据的地方
1辅助函数映射为组件的计算属性
2计算属性
3具体的数据名称小胡子语法
mutations mutations修改state中的唯一手段 commit执行
1.直接执行
2辅助函数(也可以是对象自定义事件句柄)
actions 可以手写自己的业务处理异步 dispatch派发
1.直接派发
2辅助函数(也可以是对象自定义事件句柄)
getters 计算属性
1.直接读取
2.计算属性
3辅助函数映射为组件的计算属性
modules 模块化开发
动态添加样式或者类名
动态添加背景颜色
二三级分类的显示和隐藏、
函数的防抖和节流
自定义属性
过度动画
路由参数合并
由于三级联动在Home Search Detail 把三级联动注册为去全局组件
只需要注册一次,就可以在项目任意地方使用
第一个参数为全局组件的名字,第二个为那个组件
Vue.component(TypeNav.name, TypeNav)
TypeNav 为全局组件不需要引入
放置在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是官方提供的插件 状态管理库, 集中式管理项目中的组件共用数据 多个组件依赖同一个值
new Vuex.Store 对象暴露一个store类的一个实例
Vue.use(Vuex) 需要使用插件
vuex 设置值 const state = {count: 1};
数组形式
import { mapState } from "vuex";
computed: {...mapState(["count"])},
对象形式 可以指定键
computed: { ...mapState({ n: "count"}),
函数形式
computed: {
...mapState({
//右侧需要的是一个函数,当使用这个计算属性的时候,右侧函数会立即执行一次
//注入一个state
CategoryList:state=>state.home.CategoryList
}),
computed: {
count() {
return this.$store.state.count;
},
},
{{this.$store.state.count}}
// state 仓库 payload载荷
add(state, payload) {
state.count++
state.count += payload
}
this.$store.commit("add", 1);
import { mapMutations } from "vuex";
methods: {...mapMutations(["add"])},
// content vuex上下文 payload 载荷
addSync(content, payload) {
content.commit('add', payload)
}
this.$store.dispatch("add", 1);
import { mapActions } from "vuex";
methods: {...mapActions(["addSync"])},
vuex
showNum(state) {
return state.arr.filter(item => {
return item > 10
})
}
{{ this.$store.getters.showNum }}
computed: {
arr() {
return this.$store.getters.showNum;
},
},
数组形式
import { mapGetters } from "vuex";
computed: {...mapGetters(["arr"])},
对象形式 可以指定键
computed: { ...mapGetters({ a: "arr"}),
// 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
动态绑定类名 移入元素索引==响应式数据添加样式
: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事件对象
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 指令才可以进行过度动画
使用内置组件
通过样式添加动画
如果既有query参数,右有paramis参数要进行合并避免丢失
goSearch() {
if (this.$route.query) {
let location = {
name: "Search",
params: { keyWord: this.keyWord },
};
location.query = this.$route.query;
this.$router.push(location);
}
},