vue心得

VUE

vue组件的三个API:prop、event、slot
prop 定义了这个组件有哪些可配置的属性,组件的核心功能也都是它来确定的。
组件里定义的prop都是单向数据流,只能通过父级组件对齐进行修改,组件本身不能修改props的值,只能修改定义在data里的数据,非要修改,也是通过后面介绍的自定义事件通知父级,由父级来修改;

在子组件定义prop是,使用了camelCase的命名法,由于html特性不区分大小写。camelCase的prop用于特性时,会转为短横线隔开(比如availableValue)

因为数组或对象是地址引用,vue不会检测到props发生改变
但官方不建议在子组件内改变父组件的值,因为这违反了vue中props单向绑定的思想。

solt(插槽)

这里的节点就是指定的一个插槽的位置,这样在组件内部就可以扩展内容了; 这样,父级内定义的内容,就会出现在组件对应的 slot 里,没有写名字的,就是默认的 slot; event(事件) this.$emit('on-click', event); 在组件中可以通过$emit触发自定义事件on-click,在父组件通过@on-click来监听 组件之间的通信方式 父组件向子组件的通信方式可以通过props传递, 子组件向父组件传递数据则可以通过event传递: 非父子组件之间的通信方式:eventBus 我是使用的通过在根组件,也就是#app组件上定义了一个所有组件都可以访问到的组件,具体使用方式如下; 使用eventBus传递数据,我们一共需要做3件事情 1.给app组件添加Bus属性 (这样所有组件都可以通过this.$root.Bus访问到它,而且不需要引入任何文件); 2.在组件1里,this. emit触发事件; 3.在组件2里,this. on监听事件; this.$nextTick: 在某个动作有可能改变DOM元素结构的时候,对DOM一系列的js操作都要放进Vue.nextTick()的回调函数中 Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。 $nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 。 因为数据在页面的加载是有延迟,而$nextTick是在下次DOM更新时执行,$nextTick正好符合我们的要求。 vue中本身是不支持ajax的,要想进行异步请求,则需要通过axios来进行操作。但是再使用Echarts的时候,则需要获取所有的数据后,在进行更新图标数据。 这是可以通过async/ await来处理异步/同步请求:

给对象赋值

由1可以引申出,地址引用类型的数据,例如对象obj ={a:1},如果想要修改obj中的a属性,通过obj.a = 2这样赋值,页面不会更新,需使用vue.set方法更改才会起作用, Vue.set(this,obj,a,2) 或者 this. s e t ( o b j , ′ a ′ , 2 ) ; 或 者 t h i s , set(obj,'a',2);或者this, set(obj,a,2);this,forceupdate()
Vue 实例的数据都保存在 data 对象中,Vue 将会递归将 data 的属性转换为 getter/setter,
从而让 data 的属性能够响应数据变化。
在这里插入图片描述
同样,如果要给obj增加一个新属性,如果该属性未在data中声明,页面也不会刷新。也就是vue文档中声明的“Vue 不能检测到对象属性的添加或删除”,同样需要使用vue.set 或者this.$set方法进行赋值才好使。
深拷贝/浅拷贝
先来看一个简单的例子:
let obj = {name:‘fiona-SUN’};
let copyObj = obj;
copyObj.name = ‘fiona’;
console.log(copyObj.name); // ‘fiona’
console.log(obj.name); // ‘fiona’
在js中也有栈(stack)和堆(heap)的概念:
栈:自动分配的内存空间,大小确定会自动释放。存放变量/局部变量/形参等。在js中存放简单数据段(五种基本数据类型:Number、String、Boolean、Null、Undefined),他们是按值存放的,可以直接访问。
堆:动态分配的内存,大小不定并且不会自动释放。存放在堆内存中的对象,栈中的变量实际保存的是一个指针,这个指针指向堆中的某一个位置。
所以上述例子中,属于浅拷贝,当我们声明一个对象,由于他不属于五种基本数据类型(即非简单数据段),栈中会存放一个我们声明的obj变量,它指向了堆中实际的这个对象的地址。当我们把这个引用地址赋值给了copyObj,实际它获得的是一个与obj一致的指向堆中的地址。当copyOjb改变了指向的对象地址的实际的值的时候,obj拿到的值也就自然而然变化了。看图理解⬇
在这里插入图片描述
es6之展开Object.assign(拷贝obj的内容到一个新的堆内存,copyObj存储新内存的引用)
复制一个对象
const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

深拷贝问题

针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。
let obj1 = { a: 0 , b: { c: 0}};
let obj2 = Object.assign({}, obj1);
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}

obj1.a = 1;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}

obj2.a = 2;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}

obj2.b.c = 3;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}

Vue生命周期中的钩子函数

在这里插入图片描述

1). 初始化显示(只执行一次)
* beforeCreate()el 和 data 并未初始化

* created()  完成了 data 数据的初始化,el没有

* beforeMount()完成了 el 和 data 初始化

* mounted()完成挂载,获取到DOM节点

2). 更新状态(可执行多次)
* beforeUpdate()
* updated():我们单击页面中的“更新数据”按钮,将数据更新。下面就能看到data里的值被修改后,将会触发update的操作

3). 销毁vue实例: vm.KaTeX parse error: Expected '}', got 'EOF' at end of input: …mounted(){this.nextTick(() => { /* code */ })}
在这里插入图片描述

ref

ref 被用来给元素或子组件注册引用信息的静态节点,引用信息将会注册在父组件的 r e f s 对 象 上 。     如 果 在 普 通 的 D O M 元 素 上 使 用 , 引 用 指 向 的 就 是 D O M 元 素 ; 如 果 用 在 子 组 件 上 , 引 用 就 指 向 组 件 , r e f 和 refs 对象上。   如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件,ref和 refs  DOM使DOM,refrefs其实就是用来获取/操作DOM元素的;类似于jquey中的 ( " . x x x " ) ; 缓 存 问 题 r e f 需 要 在 d o m 渲 染 完 成 后 才 会 有 , 在 使 用 的 时 候 确 保 d o m 已 经 渲 染 完 成 。 比 如 在 生 命 周 期 m o u n t e d ( ) 钩 子 中 调 用 , 或 者 在 t h i s . (".xxx"); 缓存问题 ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this. (".xxx")refdom使dommounted()this.nextTick(()=>{}) 中调用。
vue中过滤器filters的使用
组件内写法
filters:{
filter:function(data,arg1,arg2){
return …
}
}
1.在html中使用
{{ msg | filter(‘arg1’,‘arg2’) }}
2.methods中使用,并传参
methods:{
fn(){
let filter = this.$options.filters[‘filter’]
let data = filter(this.msg,arg1,arg2)
}
}
3.在v-html中使用filters

自定义指令

组件:一般是指一个独立实体,组件之间的关系通常都是树状。
Vue指令:用以改写某个组件的默认行为,或者增强使其获得额外功能,一般来说可以在同一个组件上叠加若干个指令,使其获得多种功能。比如 v-if,它可以安装或者卸载组件。
Vue 指令生命周期
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
生命周期函数中的参数
el: 指令所绑定的元素,可以用来直接操作 DOM,就是放置指令的那个元素。
binding: 一个对象,里面包含了几个属性
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。

vnode:Vue 编译生成的虚拟节点。
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用
在这里插入图片描述

自定义指令

provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
在这里插入图片描述
这样,任何页面或组件,只要通过 inject 注入 app 后,就可以直接访问 userInfo 的数据了,比如:
在这里插入图片描述

mixins基础概况

vue中的解释是这样的,如果觉得语言枯燥的可以自行跳过嘿~
混入 (mixins): 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。
在这里插入图片描述
在这里插入图片描述
总结
vuex:用来做状态管理的,里面定义的变量在每个组件中均可以使用和修改,在任一组件中修改此变量的值之后,其他组件中此变量的值也会随之修改。
Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。
与公共组件的区别
组件:在父组件中引入组件,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props来传值,但本质上两者是相对独立的。
Mixins:则是在引入组件之后与组件中的对象和方法进行合并,相当于扩展了父组件的对象与方法,可以理解为形成了一个新的组件。

利用本地化缓存机制
这种通信比较简单,缺点是数据和状态比较混乱,不太容易维护;
通过window.localStorage.getItem(key) 获取数据; 通过window.localStorage.setItem(key,value) 存储数据;
注意用JSON.parse() / JSON.stringify() 做数据格式转换;

修饰符

vue中的修饰符主要分为两类:
1.事件修饰符:
.stop 阻止单机事件冒泡
.prevent 阻止默认行为(比如 @submit.prevent 会阻止提交后刷新页面)(类似a标签javascript:void(0))
.capture 添加事件侦听器时使用捕获模式
.self 只有事件在元素本身(而不是子元素)触发时触发回调
.once 只触发一次(组件也适用)
.key 触发事件的按键
修饰符可以串联

.native
现在在组件上使用 v-on 只会监听自定义事件 (组件用 $emit 触发的事件)。如果要监听根元素的原生事件,可以使用 .native 修饰符
就是在父组件中给子组件绑定一个原生的事件,就将子组件变成了普通的HTML标签,不加’. native’事件是无法触 发的。
@keyup.enter.native

2.v-model 修饰符:

.lazy
在各种情况下,v-model在input事件中同步输入框的值与数据,但你可以添加一个修饰符lazy,从而转变为在change事件中同步:

插槽

除非子组件模板包含至少一个插口,否则父组件的内容将被替换。当子组件模板只有一个没有属性的slot时,父组件整个内容片段将插入到slot所在的DOM位置,并替换掉slot标签本身。
最初在标签中的任何内容都被替换为内容。备用内容在子组件的作用域内编译,并且仅在容纳元素为空,且没有要插入的内容时才显示备用内容。
假定my-component组件有下面模板:

我是子组件的标题

只有在没有要分发的内容时才会显示。
父组件模版:

我是父组件的标题

这是一些初始内容

这是更多的初始内容

渲染结果:

我是父组件的标题

我是子组件的标题

这是一些初始内容

这是更多的初始内容

具名插槽

可以元素用一个特殊的属性name来配置如何配给物内容。多个槽可以有不同的名字。具名时隙匹配将内容片段中有对应slot特性的元素。
仍然可以有一个匿名slot,它是替换slot,作为找回匹配的内容片段的备用插槽。如果没有替换的slot,这些发现匹配的内容片段将被抛弃。
例如,我们假定一个有app-layout组件,它的模板为:

父组件模版:

这里可能是一个页面标题

主要内容的一个段落。

另一个主要段落。

这里有一些联系信息

渲染结果为:

这里可能是一个页面标题

主要内容的一个段落。

另一个主要段落。

这里有一些联系信息

在组合组件时,内容分发API是非常有用的机制。

作用域插槽

2.1.0补充
作用域插槽是一种特殊类型的插槽,利用使用一个(能够传递数据到)可重用模板替换已渲染元素。
在子组件中,只需将数据传递到插槽,就像你将prop传递给组件一样:

在父级中,具有特殊属性scope的元素,表示它是作用域插槽的模板。scope的值对应一个临时变量名,此变量接收从子组件中传递的prop对象:
hello from parent {{ props.text }} s
如果我们渲染以上结果,得到的输出会是:
hello from parent hello from child
作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表每一项:
  • {{ props.text }}
  • 列表组件的模板:
    • 4
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值