vue2知识点实战
来源:互联网 发布:ios应用网络设置 编辑:程序博客网 时间:2024/06/09 01:08
记录一些小技巧和踩过的坑
由于本篇文章内容太多,导致SF编辑器有点卡,所以新开辟了一篇 vue2实践(二),后续再这里更新。
1. props 带不带冒号的区别
<child1 ref="child1" msg="{name:'bill'}"></child1> <child1 ref="child1" :msg="{name:'bill'}"></child1>
首先冒号是v-bind的缩写,不带冒号后面是字符串,带了冒号就是数据绑定,引号里面的内容是变量或者表达式,
组件内不能修改props的值,同时修改的值也不会同步到组件外层,即调用组件方不知道组件内部当前的状态是什么
vue 组件props传递时,为什么有时候需要加冒号,有时候不需要?
如何在Vue2中实现组件props双向绑定
2. computed属性,可以set,但是设置的是data返回的数据,不能设置自身。
如果计算属性是对象的话,可以设置他的属性。
3. 组件的生命周期函数是在template标签里的数据发生变化时候触发update
数据可能更新了,但是没有绑定到dom上面的话,不会调用update钩子函数。
4. 给变data的第二季属性的值,data不会更新,导致组件不会更新
所以在这个时候应该用Object.assign()重新生成新的对象。第一级属性值更新的话,data是更新的!
5. 动态绑定style的话,后面的样式值不能加分号
style = { color: "rgb(66, 180, 232)" }; //下面渲染不出来 style = { color: "rgb(66, 180, 232)"; };
6. filter 过滤器
vue2.0 的时候把过滤器移除了,现在2.10又加了上去,
定义filter过滤器:
写在实例Vue内部的是局部过滤器,
new Vue({ filters:{ formatMoney: function (value){ return "$"+value.toFixed(2); } }})
写在外部的是全局过滤器
Vue.filter("money", function (vaule, type) { return "¥" + vaule.toFixed(2) + type;})
组件内调用:
<span v-text="message | wrap 'before' 'after'"></span>//1.x的写法,2直接wrap('before','after')调用Vue.filter('wrap', function (value, begin, end) { return begin + value + end})
补充下:一个竖线 | 在js中是二进制运算
想问一下这个用竖线分隔开是什么意思
7. watch监测对象或者数组,不是替换对象或者数组,newVal和oldVal是同一个值。
注意:在变异(不是替换)对象或数组时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变异之前值的副本。
vm.$watch
8. 为组件绑定原生事件
有时候,你可能想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on 。例如:
<my-component v-on:click.native="doTheThing"></my-component>
9. 2.1.6computed在beforeMount前面执行的,vue2.2.1刚好相反
10. v-for和v-if在同一个标签使用的话,v-for的优先级高于v-if
如果在同一标签使用,v-if就是用来过滤v-for里面的数据的,先走if的话用template套在外面
今天并列使用的时候遇到的巨坑:
<topic v-for="(topic,idx) in topics" :model="topic" :showIdx="false" :clickHandler="handleTopicClick" v-if="mode==0"/><school-topic v-for="t in topics" :model="t" :style="showStyle(t)" :clickHandler="handleTopicClick" v-else />
结果topics只有三条数据,但是渲染出9条数据,官网说的很清楚:v-for with v-if
11.keep-alive
缓存组件在内存中,再次进入该页面不会重新渲染,用于保存页面的原始状态
<template> <div id="app"> <keep-alive include="SelectTopics"> <router-view></router-view> </keep-alive> </div></template>
即使设置了keep-alive
组件的beforeUpdate
和updated
钩子函数还是会调用的。
activated和unactivated钩子是在keep-alive组件里面被调用的,不是第一次进入keep-alive组件的话,调用顺序是:beforeEach
->beforeRouteEnter
->activated
->beforeUpdate
->beforeRouteEnter
的next
函数
也可以在离开页面的时候手动销毁改组件:
beforeRouteLeave(to, from, next) { if (to.path === "/examcentre") { this.$destroy(); } next(); }//或者 deactivated: function () { console.log(4) this.$destroy(); },
有时候根据需求(比如该组件是复用的)需要在再次进入该页面的时候重新从后台获取数据,那么可以在activated
钩子函数中请求数据来update页面。
vue.js 能否设置某个组件不被keep-alive?
vue2.0 keep-alive最佳实践
Vue如何做到前进刷新数据,后退不刷新数据呢?
<keep-alive>组件缓存问题
Vue路由开启keep-alive时的注意点
vue.js+vue-router+webpack keep-alive用法
浏览器的前进回退并不会走dom绑定的前进后退的事件
所以要想清除vuex state里面的数据的话,可以放在beforeRouteLeave
里面做处理。
this.$store.commit("SET_PAPERATTRIBUTE", {});
弹窗组件
mint-ui 中的Toast MessageBox Indicator 调用的方式是Toast('提示信息');
或者在全局引入mint-ui然后再组件里this.$toast("提示信息")
,这种方式和我们普通的引入组件的方式都不同,通常我们是在模板里直接将组件放到模板里面,这就意味着父组件在render的时候,子组件也被render到了dom里面:
<template> <div class="my-set-attr-wrap"> <set-attribute ref="setMyAttr" :style="setAttrStyle" :model="attributeModel" /> </div></template>
this.$toast("提示信息")
这种是在函数中调用,肯定也是要render到dom里面的,改咋办呢?查看了mint-ui的实现方式:document.body.appendChild(instance.$el);
目录:
TopicDetailPopup.vue文件就是普通的vue写法,
index.js:
这里考虑到每次弹出层不能都去创建新的组件,我们只需要将组件内的数据更新就可以了,dom也不需要删除,然后再创建,就用到了单例模式,这边的instance是在父组件没销毁之前都是存在的,每次只是更新了组件的数据,为啥没被销毁呢,这边形成了一个闭包:
调用:
import TopicDetailPopup from '../topicDetailPopup/index.js'TopicDetailPopup.open({ detail: res.data });
但是这个地方出现个问题this.$store
现在为undefined
,应该是因为这个组件是直接new实例化的,而不是通过根组件嵌套的,
main.js
new Vue({ router: router, store, render: h => h(App)}).$mount("#app");
store注册在根组件里面,而弹窗组件没有和根组件关联,所以拿不到store。
要是能将弹窗组件插入其他组件问题就能解决了,貌似现在API没有提供这样的接口,vue2动态添加组件的话可以用render函数,可以我现在的弹窗组件是模板的形式,也可以动态插入到父组件,<component :is="componentId"></component>
且需要在components里面引用,这样又回到了模板语法了。
弹窗的弊端:
vue-devtools 没法检测到组件,也没法检测到vuex,对于webapp来说返回键没法使用,关闭不了当前的弹窗,造成上面的问题都是由于没用使用router。
对于安卓手机返回键没法使用可以采用曲线救国的方式,禁用返回键,js没法直接操作安卓返回键,但是可以使用beforeRouteLeave
,使得返回键没有效果,
beforeRouteLeave(to, from, next) { if (this.popupVisible) {//弹窗显示的话,路由没法跳转 next(false); } else { next(true); } }
弹窗的好处:
在当前页面直接弹出,这样可以保存当前页面的数据和滚动条的位置,还有就是组件复用的话,直接关闭弹窗,不需要根据不同的页面去回退或者前进到特定的页面。
使用的是vue2.0,如何动态添加组件。例如实现点击A按钮添加aTest组件,点击B按钮添加bTest组件。
:model和v-model的区别
v-model通常用于input的双向数据绑定 <input v-model="parentMsg">
,也可以实现子组件到父组件数据的双向数据绑定:
首先说说v-model的用法:
model.vue
<template> <div> 父: <input type="text" v-model="msg"> <child v-model="msg"></child> </div></template><script>import child from './modelChild.vue'export default { name: "model", props: { }, components: { child }, data() { return { msg: "ppp" } }, methods: { }}</script><style lang="less"></style>
modelChild.vue
<template> <div> 子: <input type="text" @input="handleInput" class="text" :value="value"> </div></template><script>export default { name: "modelChild", props: ["value"], methods: { handleInput(e) { this.$emit("input", e.target.value) } }}</script><style lang="less">.text { height: 20px; width: 200px;}</style>
无论改变父组件还是子组件的输入框,value和msg的值都会改变,两个输入框的值也就同时改变了。
:model和v-model的区别
:model是v-bind:model的缩写,<child :model="msg"></child>
这种只是将父组件的数据传递到了子组件,并没有实现子组件和父组件数据的双向绑定。当然引用类型除外,子组件改变引用类型的数据的话,父组件也会改变的。
Vue.component注册全局组件
查看vue-router源码的时候发现install.js里面两句:
Vue.component('router-view', View)Vue.component('router-link', Link)
这两句就是全局注册了这两个组件,
import Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter)
这三步后,在组件里直接使用 <router-view></router-view>
而不用先import再使用。
在mint-ui里也是相同的做法:
src/index.js
const install = function(Vue) { if (install.installed) return; Vue.component(Header.name, Header);//注册全局组件 Vue.component(Button.name, Button); Vue.use(InfiniteScroll);//使用指令插件 Vue.use(Lazyload, { loading: require('./assets/loading-spin.svg'), try: 3 });//使用指令插件或lazy-component Vue.$messagebox = Vue.prototype.$messagebox = MessageBox; Vue.$toast = Vue.prototype.$toast = Toast; Vue.$indicator = Vue.prototype.$indicator = Indicator;};
后面的Vue.$toast = Vue.prototype.$toast = Toast;
使得我们可以在组件中直接调用this.$toast("提示信息")
组件上写class
之前在写react的时候是不可以这么做的,今天查看了popup.vue的时候发现vue是可以这么干的,直接渲染到了组件的根元素上面。用在组件上
Boolean类型的props可以直接定义:
props: { fixed: Boolean, value: {} }
数据更新页面没刷新
今天在concat两个数组的时候发现数据更新了,页面并没有刷新,debug看了下数据,concat的数据没有get set属性访问器,导致后来push的数据也没有属性访问器。之前没有细看文档。搜了下原来push是变异方法,concat不是。
解决办法有二:
使用变异方法
使用vue component的$set函数
看一些小伙伴的回答是data的$set方法,至少vue2是没有的。具体可查看文档列表渲染
我的解决办法是:
Array.prototype.push.apply(arr, item);
render函数和模板语法只能二选一
今天在模板.vue文件里加入render函数发现并不会执行render函数,原来是vue-loader
会将template
转成render函数,所以只能二选一。.vue文件如何使用render函数渲染组件
控制input只能输入数字
<input type="number">
在pc和手机端都可以实现只能输入数字,可是手机端弹出的软键盘里面没有完成或者搜索按钮,搜了下,现在的HTML5 number的情况下并没有支持搜索按钮,type='text'是有的。所以曲线救国,控制表单只能输入数字。
起初的想法是先把在
<input type='text' @input="handleInput" :value="val"/>handleInput(e){this.val=e.target.value.replace(/[^\d]/g,'');}
但是这种并不会实时刷新表单的数据,下面就会起作用
e.target.value=e.target.value.replace(/[^\d]/g,'');
优雅点的写法,用自定义指令:
//<input type="text" v-number-only /> directives: { numberOnly: { bind: function(el) { el.handler = function() { el.value = el.value.replace(/\D+/, '') } el.addEventListener('input', el.handler) }, unbind: function(el) { el.removeEventListener('input', el.handler) } } },
vue的input中,如何限制只能输入number
弹出层弹出文本框获取焦点
由于弹出层是单例模式,所以打开弹出层只会执行一次mounted钩子函数,我去监听
visible(val) { if (val) { this.$refs.textbox.focus();//这样并不能使文本框获取焦点 } else { this.detail = null; this.$refs.textbox.value = ""; } }
解决办法也是使用自定义指令
focus: { update(el) { el.focus(); } }
vue如何实现点击button 使input获取焦点
改变v-html解析后台返回的HTML样式
平时在写组件里面的样式加上scoped
,避免样式的全局污染,而从后台返回的HTML无效的,解决办法就是在组件里再加一对style标签,将样式写到这里。
转载https://segmentfault.com/a/1190000008688050
- vue2知识点实战
- vue2.0知识点汇总
- 【Web】Vue2.0 音乐APP实战中的知识点总结(一)
- 【Web】vue2.0音乐APP实战中的知识点总结(二)
- 【WEB】Vue2.0音乐APP实战中的知识点总结(三)
- 【WEB】Vue2.0音乐APP实战中的知识点总结(四)
- Vue2.0实战
- Vue2.0相关的知识点
- Ⅴ vue2.0 项目实战
- vue2 饿了吗视频实战总结
- vue2+vue-router2+webpack实战(一)
- Vue2+VueRouter2+webpack 构建项目实战
- Vue2.0 + vue-router + Vuex实战演练
- vue2.0项目实战(1)---工具
- 入门Vue2.0及学习实战项目
- 【jQuery实战知识点总结】
- Vue2
- Vue2.0 项目实战案例及Demo,基于vue2.0+vuex+vue-router+axios实现
- 《Spring in Action》第二章--自动化装配bean+音响系统例子的实现
- redis使用watch秒杀抢购思路
- 由一段小代码引发的关于“表达式”和“语句”的探讨
- Android横竖屏切换以及生命周期管理
- LFW pairs.txt解释
- vue2知识点实战
- C# Linq 的使用整理(持续更新中)
- 如何运用ABBYY FineReader实现JPEG与ePub之间的转换
- PDF压缩常用方法分享
- Nginx如何禁用非法请求http
- laravel 5.4 JWT + Dingo 构建API 攻略
- Android Service
- IBM Appscan9.0.3安全扫描简单安装、使用以及高危漏洞修复
- c++基础(19)