vue学习笔记
2021-01-19
- 传递本地路径的问题
在父子组件通信中,子组件需要图片地址,父组件传递图片地址时,图片地址是本地图片,使用别名@以及相对路径…/都会导致图片路径出错.
解决方法:使用require引入
<feature-view :imageUrl="featureImageUrl"></feature-view>
data() {
return {
featureImageUrl: require("@/assets/img/home/recommend_bg.jpg"),
};
2021-01-25
- 封装scroll组件
设置scroll组件的margin-top,设置home div高为100vh,结果出现home的高为100vh+scroll的margin-top.原因是因为父元素的高度塌陷,scroll组件和home的顶部重合到了一起,scroll的margin-top成了home的margin-top导致高度不对, 以后多注意高度塌陷的问题!!!
2021-01-27
-
bus总线
在封装scroll组件的时候,使用了better-scroll出现bs可滚动高度不对的问题。出现的问题在于bs对象初始化时,会计算出一个高度,等到异步图片加载完成高度会变高,但是bs对象没有调用refresh()方法,导致可滚动高度不对.
由此学习到了bus方法总线机制.如果图片加载完成调用upload方法回调派发事件 ,需要多次派发事件才能到达home组件然后调用scroll组件的refresh()方法.由此 bus总线可以派发事件,而在任何一个组件进行监听. -
Vue父子组件的加载顺序
1: 父 beforeCreate
2 父 created
3 父 beforeMount
4 子 beforeCreate
5 子 created
6 子 beforeMount
7 子 mounted
8 父 mounted -
防抖函数和节流函数
// 防抖函数 核心原理:有人调用就取消定时器,重新设置定时器过一会调用
function debounce(fn,delay){
let timer = null;
return function(...args){
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(this,...args);
},delay)
}
}
//节流函数 核心:执行完一个函数后,设置一个定时器,定时器内函数不能执行
function throttle(fn, delay) {
let timer = null;
return function (...args) {
if (timer) return;
fn.apply(this,args);
timer = setTimeout(() => {
timer = null;
}, delay)
}
}
2021-01-28
- 关于粘性布局的问题
因为使用了better-scroll进行滚动管理,所以导致sticky布局无法正确获取滚动的距离,导致css原生的sticky布局会失效.
于是想要使用js来控制.监听bs的滚动,滚动到某个距离时,把元素设置为fixed布局,但是又出现了两个问题,
1: 把元素设置成为fixed会导致元素脱标,表现为元素的高度瞬间消失,下面的元素顶了上去,出现了元素的跳跃效果.
2:设置成为fixed布局之后,需要设置top属性来确定位置,但是由于元素在bs管理所元素的内部,而bs所管理的元素是利用transform来实现滚动,这会导致top是根据bs所管理元素的最上方计算top,就会出现设置为fixed的元素消失,出现在距离滚动元素最上方top距离的位置.
解决方法:设置一个与要设置为粘性布局一模一样的组件(属性/事件全部一样,调用的方法都是公用的),将新设置的组件放到滚动元素的外面并默认隐藏,并设置好粘性布局的样式. 当滚动到某个距离之时,将新设置的组件显示出来,就实现了看起来与粘性布局一模一样的样式. - 保留离开页面时的位置
要实现离开页面再回来时显示的位置和原来是一致的,首先保证页面页面离开不会被销毁,所以在
< router-view >加上<keep-allive>保证页面不被销毁.
其次要离开的时候记录滚动位置,回来的时候在滚动到离开时的滚动位置. 使用两个钩子函数,
activated和deactivated 注意:有一个小bug,active在对一次页面创建也会调用一次,这时其他组件都还没创建导致元素获取为null,注意下就可以.
2021-01-29
- 封装类class
在遇到发送请求获取数据的情形时,经常会出现这种情形: 从服务器返回的数据太过复杂和杂乱,将数据传递给子组件时单个属性传递太过繁琐,整体对象传过去无用信息太多,太过杂乱. 所以可以用es6的class机制,将需要传递的数据封装为一个类,实例化为类的对象进行传递,这样数据格式有用且不会出错.
2021-01-30
- 一个bug
在Detail.vue这个组件中,我们使用了GoodsListItem.vue这个组件,这个组件图片加载完成会通过事件总线派发事件,Detail.vue中监听到事件后,刷新better-scroll的高度,保证滑动不出现问题.但问题在于因为home组件设置keep-alive导致home组件并没有被销毁,而home组件还在监听事件总线的同样的时间,导致Detail.vue中图片加载完成,home的detail都会进行scroll的刷新
解决方法:离开home组件时就不应该再监听事件总线的方法,在钩子函数deactived中取消事件监听.
2021-01-31
- mixin
学习到了mixin混入,mixin是一种技术,他可以把多个组件用到的公用的组件内容抽取到一个对象当中,并在用到的组件中引入,这样能降低代码的重复程度.例子如下:
在下面的组件当中,将data和mounted的一部分抽取到了mixin当中,引入组件后,data和mounted中的内容会和原本组件中的data/mounted合并到一起,从而增加代码的复用程度,减少冗余.
import { debounce } from "@/common/utils.js";
export const goodsListItemUploadMixin = {
data(){
return {
goodsListItemUploadHandler: null, //图片加载完成的回调事件
}
},
mounted() {
// 防抖
let refresh = debounce(this.$refs.scroll.refresh, 500);
// 事件总线
this.goodsListItemUploadHandler = () => {
// this.$refs.scroll.refresh();
refresh();
};
this.$bus.$on("goodsListItemUpload", this.goodsListItemUploadHandler);
}
}
- 高度bug
在获取高度时会有各种各样的问题,都是因为dom加载,图片加载未完成所产生的的问题.mounted钩子中,因为数据是异步加载所以可能导致没有dom,高度不对. 使用nexttick可以保证dom渲染. 但是dom渲染完成后,如果有图片的话图片尚未加载完成,也会导致高度不对.
2021-02-01
- vuex mutations原则
vuex的mutations尽量一个方法只做一件事情,便于vue的插件进行追踪,比如今天的购物车添加商品,我在mutations的方法中做了两件事情,一是判断是否存在存在商品,二是设置数量添加进购物车. 这样最好将逻辑放入到action中进行,把上述的两个方法抽到mutations中形成两个单一操作.
2021-02-02
-
vuex可返回promise进行 异步操作
做项目遇到一个需求,当点击添加进购物车时,将商品添加到购物车,添加进购物车后进行弹窗提示添加成功. 这个需求有两个点: 一是:修改vuex中的数据,需要使用vuex的actions. 二是: actions中添加到购物车的操作是一个 异步操作.
所以不能调用添加进购物车的方法后直接进行弹窗,因为 异步操作需要时间.所以 使用异步操作返回promise来解决. -
vuex的映射
在vuex中,getters和mutations以及actions都是可以映射的.getters是计算属性,所以可以通过 …mapGetters映射到组件的computed计算属性中, mutations和actions都是方法,所以可以通过**…mapMutations和…mapActions映射到methods方法中. -
通过插件的方式来封装组件(important)
- 正常封装一个toast组件
- Vue.use(xxx)的时候会调用xxx的install方法 所以可以在install方法让Vue.prototype.$toast= Toast
//main.js中
import toast from '@/components/common/toast'
Vue.use(toast);
- 具体代码
let obj = {};
obj.install = function (Vue) {
let toastConstructor = Vue.extend(Toast);
//通过组件构造器新建一个组件对象
let toast = new toastConstructor();
//将组件对象挂载到一个dom元素上
toast.$mount(document.createElement('div'));
//t.$el就是div 将组件放到body中
document.body.appendChild(toast.$el);
Vue.prototype.$toast = toast;
}
export default obj;
- 然后就可以通过下面方式调用
this.$toast.show('123',2000);
- Toast组件代码
<template>
<div class="toast" @click.prevent="hiddenToast" v-if="isShow">
<div class="content">
{{ message }}
</div>
</div>
</template>
<script>
export default {
name: "Toast",
data() {
return {
isShow: fasle,
message: "",
};
},
methods: {
hiddenToast() {
this.isShow = fasle;
},
show(message = "默认文字", duration = 2000) {
this.isShow = ture;
this.message = message;
setTimeout(() => {
this.isShow = fasle;
}, duration);
},
},
};
</script>
2021-02-03
- fastclick解决移动端300ms延迟问题
- vue中图片的懒加载 使用vue-lazyload
- 样式大小的调整,可以使用px2vw 和 px2rem自动将px转换单位,适配不同屏幕.
Vue响应式原理的两个核心点
-
Object.defineProperty
Vue第一个核心问题就是如何监听数据的变化. 在js中属性有get 和 set 两个方法.设置属性的值时 会调用set方法,意思就是 更改属性的值是会调用属性的set方法. 而我们想要监听属性的变化,所以, 所以我们在set中就可以监听到属性的变化,做一些事情. 这就实现了监听数据变化.
因为要监听Vue中每一个data的变化,所以new Vue()的时候要劫持每一个属性.设置get和set
new Vue({
el: 'app',
data:{
name: 'zhangsan',
age: 18
}
})
因为data中那个每一个属性都需要监听,每一个属性变化的时候都要做一些事,所以获取到data的每一个属性
let data = {};
Object.defineProperty(data,name,{
get(){
//做一些事情,获取数据会调用get,在这里做一些事情就监听到了获取数据
return name;
},
set(value){
//做一些事情,更改数据会调用set,在这里做一些事情就监听到了更改数据
name = value;
}
})
-
发布订阅者
上面已经讲了第一个核心的问题,就是怎么监听到数据的变化.下一个核心问题就是,我怎么知道谁 引用了data中的属性,也就是data变化时,我怎么知道谁要跟着变.这里使用了发辫订阅者模式.也就 是说我每一个属性都建立一个Dep(Dependency,发布者)对象,发布者对象有一个订阅者属性,是一 数组,每一个调用属性的人都是订阅者,因为属性变化了,调用者也要变,所以调用者都是订阅者,为 订阅者建立一个Wacther对象.
Class Dep{
constructer(){
this.subscribe = []; //每个发布者都有订阅者
},
notify(){
//当发布者发生变化的时候,调用notity方法,通知每一个订阅者,调用订阅者的update方法.
this.subscribe.foreach(item => item.update());
}
}
Class Watcher{ //订阅者
constructer(){
this.value = ''; //每个订阅者都有value
},
update(){
//当发布者更新的时候,update就会被调用,在这里做一些事情
更新视图(也就是view)
}
}
图解
2021-04-08
- NProgress的使用
- 有关router路由添加原信息
- 一个路由对应一个页面
- 所以可以在router中添加meta原信息,代表路由页面的信息,比如页面的标题和页面的权限
- 动态路由权限
在一个系统中,总会涉及到用户的权限, 在前端根本的解决途径就是不给多余的路由, 也就是只给他可以访问的路由.
所以可以采用动态路由表.采用router.addRoute api
示例: 动态路由表示例 https://blog.csdn.net/qq_42778001/article/details/105047242