木灵鱼儿 - vue前端开发快速入门与专业应用
type: channel
link: https://www.mulingyuer.com/category/vue%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8%E4%B8%8E%E4%B8%93%E4%B8%9A%E5%BA%94%E7%94%A8/
items: vue入门感受
items: Vue 路由
items: Vue 动态组件
items: Vue 过渡
items: Vue过滤器
items: 入门基础

vue入门感受
type: item
date: 2019-11-20T00:50:25+08:00
description: 实习的地方使用的vue，于是只能硬着头皮学了，之前买过一本vue的书，于是派上了用场，但是实际其实用处感觉不大，前期的内容还是挺简单的，就是讲了几个vue的标签，指令这些的用法，但是一到路由这里就卡主了，因为1.0和2.0版本不同，很多东西都变了，而且例子也不详细，无奈只能放弃继续读下去，于是找一个视频教程和一本项目实战的书，期待能有新的认知，这里就暂时放弃继续写这本书的笔记了。

Vue 路由
type: item
date: 2019-11-18T09:45:00+08:00
description: 基本写法首先引入vue的插件router，地址：https://unpkg.com/vue-router/dist/vue-router.js下载后head引入,然后创建好html的标签: 主页 列表 关于 使用router-link标签to属性表示路径,使用router-view用于显示组件入口.var home = Vue.component('my-home',{ template : ' 主页 ' }); var list = Vue.component('my-list',{ template : ' 列表 ' }); var about = Vue.component('my-about',{ template : ' 关于 ' });我们再创建三个组件用于显示,可以使用Vue.extend或者Vue.component,都要用一个变量引用.var routes = [ {path:'/',component:home}, {path:'/list',component:list}, {path:'/about',component:about}, {path:'*',redirect:'/'} ];创建一个数组变量,里面使用对象来编写路由路径,每个{}表示一个路由页面,path则是浏览器地址栏显示的地址,component的参数为之前创建的组件的变量名.其中{path:'*',redirect:'/'}表示重定向,一般写在最末尾,表示当地址栏指向的地址非指定好的path时,会自动跳转到home,类似于404提示.var router = new VueRouter({ routes : routes });路由配置文件写好后自然要创建路由了,new VueRouter创建路由实例,routes的值要为刚刚创建的配置文件routes变量,我们也可以写简写形式,如:var router = new VueRouter({ routes });直接传入这个配置的变量名即可.至此路由创建完毕,我们还需要在对应的vue中引用才可以正常使用.var app = new Vue({ el : '#app', router });在对应的Vue实例中加上router即可.二级路由一般来说不可能就只有一个一级路由,二级路由甚至三级路由,等等,我们现在就可以看看二级路由.假设我要在一级路由显示的biz组件里面再加两个路由地址,然后这两个二级路由也有对应的router-view;首先创建一个Biz组件var Biz = Vue.component('my-biz',{ template : ' \ 二级路由 \ \ 二级路由1 \ 二级路由2 \ \ \ ' });html上加上这个路由链接元素 主页 列表 关于 Biz 路由器配置var routes = [ {path:'/',component:home}, {path:'/list',component:list}, {path:'/about',component:about}, {path:'/biz',component:Biz, children:[ {path:'list',component : { template : ' 二级路由进来了1 ' }}, {path:'about',component:{ template : ' 二级路由进来了2 ' }} ] }, {path:'*',redirect:'/'} ];在biz的对象中添加一个children数组,表示子路由,里面也是一样有path,component,注意子路由path不需要反斜杠表示.component里面template和平时写的一样,你可以直接写html文本,也可以用#xx 获取htm文件中的对应的组件.基本二级路由就完成了,如果三级路由就继续这样嵌套就行了,但是vue不建议嵌套太多,本身就是作为单页面app开发用的注意:组件的html文本必须要有一个根元素将所有的内容包裹路由匹配如果我们要复用一个组件,只是路径名发生了变化,就可以使用路由匹配,比如一个user的组件,不同id的用户都要用这个组件来渲染,我们可以通过匹配他后面带的用户名参数来判断.var Biz = Vue.component('my-biz',{ template : ' \ 二级路由 \ \ 二级路由1 \ 二级路由2 \ \ \ ', watch : { '$route'(to,from) { console.log(to) console.log(from) } } }); 我们对Biz组件加多一级路径,一个/foo,一个/bar,然后使用watch监听这个路由的变化,to是最新路由地址,from则是过去的路由地址,…

Vue 动态组件
type: item
date: 2019-11-17T18:31:00+08:00
description: component通过compoent标签加上:is就可以判断让哪些组件显示。compoent可以理解为一个所有组件的母体，它包含了所有的组件，通过:is的值就可以让对应的组件显示出来。 主页 列表 关于 var app = new Vue({ el : '#app', data : { showview : 'home' }, components : { home : { template : ' 主页 ' }, list : { template : ' 列表 ' }, about : { template : ' 关于 ' } } });keep-alive:is属性每次让元素显示或者隐藏都是一次完整的渲染，如果说这个显示的内容是不需要每次显示都更新一次，那么就可以使用keep-alive标签包裹，这样vue就会将隐藏的内容暂存在内存中，显示时在拿出来，以减少性能消耗。 主页 列表 关于 var app = new Vue({ el : '#app', data : { showview : 'home' }, components : { home : { template : ' \ 主页 \ \ {{item}} \ \ ', data(){ return { items : [] } }, mounted : function(){ console.log('1'); this.items = [1,2,3,4,5] } }, list : { template : ' 列表 ' }, about : { template : ' 关于 ' } } });我们给home组件添加一个mounted的生命周期钩子，表示元素渲染后会运行里面的内容。当我们切换的时候，会发现，除了第一次console.log('1')运行了，后面都没有再重复了，表示这个生命周期并没有结束， keep-alive有效。注意keep-alive也可以不和component配合使用，keep-alive可以包裹多个子组件，只要确保所有的子组件只要一个是激活状态，其他都是隐藏的，比如使用v-if/v-else。集中式事件处理器由于子组件和父组件之前是相对独立的，那么事件的创建触发相对来说会很麻烦，像之前的使用props来接受父组件的方法，$emit来传参这些都很麻烦，我们可以创建一个空的vue实例，然后对这个实例进行事件的集中处理。首先创建一个空的vue实例var bus = new Vue();然后对这个实例使用$on方法创建并监控一个自定义事件和方法bus.$on('create', function(data) { alert(data); })然后我们通过$emit来触发这个bus的自定义事件，就可以做到快速传值了，也没有之前做的那么麻烦假设我们要在某个按钮click后才触发bus.$emit('create','666');通过一个全局的实例bus，我们可以在任何地方访问，方便于集中管理，所有的通信类事件都可以通过该方式做到，并且还可以在函数作用域下拿到父级的this来操作对应的内容。然后触发$emit和监控$on，都可以自由的放置在不同的组件中，注意on要先运行。

Vue 过渡
type: item
date: 2019-11-10T19:03:00+08:00
description: class类名之间的区别单个说明不是很好理解，我们直接看它的流程图v-enter(动效开始之前)>------>------>------>v-enter-to(动效结束) v-leave(动效开始之前)>------>------>------>v-leave-to(动效结束)这两个表示一个来回，第一次点击运行第一个v-enter,第二次点击运行v-leave，这样有来有回就产生动效。两个动效一般都不会在类名里面写transition：all .3s；这种来控制动效时间，他们都有一个通用的类名，在开始到结束一直存在的：v-enter-active 第一次的v-leave-active 第二次的这两个主要存放动效的transition属性假设我们要做一个opacity的过渡，我们要这样写.v-enter { opacity:0; } .v-enter-to { opacity:1; } .v-enter-active { transition: opacity 1s ease; }这样写表示第一个流程，第二个流程实际上就是反过来，css就没必要重新写了，直接共用.v-enter,.v-leave-to { opacity:0; } .v-enter-to,.v-leave { opacity:1; } .v-enter-active,.v-leave-active { transition: opacity 1s ease; }那么这里一个动效类名就写好了，实际上这个类名就是vue默认调用的一个类名，也就是如果你没有指定transition元素name属性，他就会默认使用这个类名作为切换的效果。注意：过渡的是active记得要写在最后，让他的css权限比enter，leave大，以免过渡时这两个里面写了transition属性造成动效出现问题！实际上这个css还可以继续简写，我们元素默认就是显示的，不管opacity为1，他也是显示的，除非你设置为0，那么vue操作类名的时候不会像jq一样，操作完结束时是什么，元素上就是什么，vue会将class类名全部清除掉，就好像动效之后什么都没有发生，那么我们甚至可以不写结束时的类名。首先我们看下流程：第一次点击，元素先添加了.v-enter，瞬间将元素设置为动效开始前的状态，此时元素透明为0，然后移除.v-enter，接着添加.v-enter-active和v-enter-to通过active产生动效，当他达到1时，class被清除。第二次点击，也是一样。那么由于元素本身就是现实的，移除opacity，不设置动效结束时opacity为1，在active的影响下元素也会发生透明度动效。以上就是class类名的理解，然后就是自定义类名了，因为我们不可能都是使用默认的吧！自定义类名transition有一个name属性，它的值可以为自定义的class类名，比如name=“fade”然后我们创建一个fade的cass效果.fade-enter,.fade-leave-to { opacity:0; } .fade-enter-to,.fade-leave { opacity:1; } .fade-enter-active,.fade-leave-active { transition: opacity 1s ease; }实际上我们只需要把之前的class类名v改为我们自己的name值，然后就可以了，vue会自动补全后面的值，因为后面的都是固定的，所以在设置的时候，只需要name=“fade”即可。动态绑定动效名只要为transition的name绑定一下就行了 绑定后他会去获取data里面的transitonName的值，当我们修改了它的transitonName的值时，transition的name值也会发生变化，这样就可以做到随心变化了，我们只需要设置好css效果然后添加就行了，每次只用改data里面的值，这样就不用在繁多的transition中一个个修改。引入animate动画库css动画库有一个比较有名的，就是animate.css了，vue可以通过引入这个css文件然后使用它提供的动画效果。animate官网下载后在head里link引入这个css文件，然后在vue的transition元素上添加一下是哪个属性：enter-active-class 表示第一次动画效果leave-active-class 表示第二次动画效果:duration 表示动画的时间 enter-active-class和leave-active-class如果引入的是animate.css前面一定要加上animated专门的class类名。animated这个类名实际上就是设置了动画的时间以及循环次数，一般…

Vue过滤器
type: item
date: 2019-11-09T00:54:00+08:00
description: 由于2.0版本取消了所有的内置过滤器，而且过滤器只能在插值中使用，也就是{{xxx}}中使用，格式为{{name | 过滤器}}；通过一个管道符号将前面需要过滤的内容隔开，后面写一个函数用于过滤，过滤器会将name作为第一个参数传入这个函数中，并且还支持传参。创建一个过滤器全局过滤器Vue.filter('deta',function(value){ if(!data instanceof Data) return value; return value.toLocaleDateString(); });通过Vue.filter创建一个全局过滤器，deta为过滤器名字，后面接一个函数，第一个则是管道符号前面的值，该方法的意思是，如果这个value不是Date对象下的实例，那么就直接返回这个对象，反之则将这个value转换成本地时间格式返回，一般为2019/11/9这种，然后使用的时候就是这样： {{date|deta}} var app = new Vue({ el : '#app', data : { date : new Date() } });该方法还支持传入多个参数，但是其实用的还是参数接收，格式如下：Vue.filter('deta',function(value,parameter){ //parameter就是传入的参数 }); {{date|deta(parameter)}} data()在括号里传入参数即可，你可以传数组，也可以传string，obj，甚至可以传动态参数，比如我们在vue的data里面添加一个flag:true的参数用于判断这个东西是否需要过滤，当然这个也只是一个例子 {{date|deta(flag)}} 需要注意的是如果是动态参数就不要加引号，如果不是则要加上引号，具体自行测试。局部过滤var app = new Vue({ el : '#app', data : { date : new Date() }， filters : { name : funciton(value){ //局部过滤器 } } });直接再vue对象里面加入filters参数，其他都一样，vue有一个规律，凡是全局有的，在局部里使用都加了一个s。双向过滤器除了动态参数外，其他的都是在元素渲染至dom前就进行过滤，并不影响到数据本身，也就是data里面的值不会发生变化，使用双向过滤就可以将data绑定到的属性进行写入。Vue.filter('deta',{ read : function(value) { //渲染到dom时 if(!data instanceof Data) return value; return value.toLocaleDateString(); }, write : function(){ //写入到data时 if(data instanceof Data) { return value.toLocaleDateString(); } } });实际上read和write没必要都要一样，比如人民币的换算，一般为了避免浮点数的运算，都是在服务器里存储整数的，一般以分为单位，已知1元=10角=1000分，以分为单位。用户显示和输入都是以元为单位。Vue.filter('money',{ read : function(value) { //渲染到dom时 return '￥:'+(value/1000); }, write : function(){ //写入到data时 return value*1000; } }); var app = new Vue({ el : '#app', data : { money : 5000 } }); {{money|money}} 2.0移除了这个东西，我日连续过滤 {{money | money | money}} 通过管道符号隔开，之前的过滤器return的值会作为后面过滤器的参数再次过滤，以此类推。

入门基础
type: item
date: 2019-11-07T23:12:00+08:00
description: v-if/v-else看书上说v-show也可以和v-else配合使用，实际上并不行。:style 也支持三元判断，和:class一样，三元需要加个括号，然后里面如果是普通的string值需要用引号括起来，不然会认为是对象或者Vue对象的属性方法那些，从而报错。例子： v-for需要为每个循环出来的对象加上:key=“index”，index就是对应的下标v-text{{msg}} == v-text，但是v-text可以避免在内容还未更新时先出现{{msg}}这个字符，然后再被替换成对应文本的闪现。v-html原来可以通过{{{data}}}的方式来插值，现在不行了，只能通过指令v-el2.0放弃了这个方法，使用rel=“xxx”来获取对应的dom元素，然后通过$refs.xxx来获取对应的dom对象，如果在vue对象里面就使用this.$refs.xxx如果再外面，就使用实例的名字.$refs.xxx来获取注意，title-h2表示驼峰命名，调用时等于titleH2ref也可以给子组件添加标记，效果一样v-pre阻止{{}}插值的内容被替换渲染，直接输出插值的文本，然后使用了v-pre，通过ref获取的标记也会消失，使用$refs.xxx便会报错 {{msg}} v-cloak延时，如果渲染的内容过多，可以使用单属性v-cloak来隐藏未编译的{{}}mustach插值，等对应的实例对象编译完成再显示。 {{msg}} v-once表示该元素及子元素或者包含的组件只会渲染一次，哪怕我们后面修改了绑定的数据，他也不会再页面变化。 {{msg}} 自定义指令指令注册注册全局指令Vue.directive('name',{});局部指令在子组件extend或者component中加入directives，该局部指令只能在该子组件上使用Vue.extend('templeta',{ directives : { 'local-class' : {} //-连接表示驼峰命名，调用是v-localClass } });定义指令的对象有三个属性：bind：只会调用一次，就是当指令绑定到元素上时update：元素内容第一次渲染以及后续更新内容绑定内容时运行，它接收两个参数，为newValue和oldValueunbind：指令从元素上解绑时触发Vue.directive('wCc',{ bind : function(){ console.log('bind',arguments) }, update : function(newValue,oldValue){ console.log('update',newValue,oldValue) }, unbind : function(){ console.log('unbind',arguments) } }); var app = new Vue({ el : '#app', data : { value : '初始化', flag : true, html : ' 我是一个HTML ' }, methods : { } }); {{html}} 首次运行时我们可以看到bind的arguments包含了几个参数，其中0为绑定的元素本身，1则是指令绑定的内容，剩下几个就不是很清除了，以后再研究修改内容在浏览器输入：app.value = ‘内容更新了’我们可以看到update运行了，他的newValue实际上是被绑定的div元素本身，而oldValue是一个object对象，他里面包含了上一个内容和新的内容，展开后他的oldValue属性是旧的绑定内容，value则是新的内容。取消绑定时取消绑定实际上就是让元素消失，v-if这些，我们给他加个flag判断，然后将flag改为false。实际上和bind一样，所以就不多解释了。如果我们只需要使用update的话，可以使用简写形式创建Vue.directive('wCc',function(value,value2){ console.log(value,value2);}); 直接传一个带参数的函数就行了，va1，va2对应上面说的。 如果你的指令绑定是一个string值，那么update只会运行一次，因为你的值不是vue对象的，那么就不能进行响应，而且传的如果是string需要用引号括起来表示，如：`v-w-cc="'string'"` vue2.0后自定义指令又增加了几个属性： 1. `inserted` 被绑定元素插入父节点时调用 (仅保证父节点存在，但不一定已被插入文档中) 2. `componentUpdated`指令所在组件的 VNode 及其子 VNode 全部更新后调用。 之前说的参数都比较浅显，我们来深入一下 这些属性都对应…