1. Vue简介
Vue是国内开发者尤雨溪开发的JavaScript框架,它是实现UI层的渐进式框架, Vue借鉴了Angular的指令、React中组件和props等优点进行设计,从最简单的数据处理,到数据交互,到DOM操作,到路由处理等,Vue都有完整的解决方案。
2. 开发模式
- 确保电脑上装有Node 4.0以上的版本,在CMD里面运行node –v查看版本;
- 全局安装 vue-cl;
在命令行输入:$ npm install --global vue-cli,全局安装vue-cli。
默认是从国外服务器下,可以使用阿里巴巴在国内的镜像服务器,通过config命令设置默认下载路径:npm config set registry https://registry.npm.taobao.org。
然后执行 npm install --global vue-cli,这样安装的速度会快一些,完成后,检查是否安装成功:vue -V ( 注意V大写 )。
- 创建一个基于 webpack 模板的新项目,名为my-project;
在命令行输入:vue init webpack my-project,注意项目名不能有大写。
项目建立过程中,有如下选择,选择NO,该选项为使用ESLint规范你的代码,一个空格错误都将报错,不开启,避免不必要的麻烦,后两项为单元测试,可以选择No。
项目建立完成后,目录结构如下:
- 安装依赖;
(1). cd my-project 进入项目中;
(2). npm install 安装依赖文件;
完成后,会发现项目目录下多出一个node_modules文件夹,里面就是 vue-cli 创建的一个基于 webpack 的 vue.js 项目,进入项目目录文件夹my-project中,就可以使用vue进行开发了。
(3). npm run dev,便可以打开本地服务器实时查看效果,访问地址 localhost:8080;
如果浏览器打开之后,没有加载出页面,有可能是本地的 8080 端口被占用,需要修改一下配置文件 config=>index.js。
建议将端口号改为不常用的端口,另外还建议将 build 的路径前缀修改为 ' ./ ',是因为打包之后,外部引入 js 和 css 文件时,如果路径以 ' / ' 开头,在本地是无法找到对应文件的,而在服务器上没问题,所以如果需要在本地打开打包后的文件,就得修改文件路径。
npm run dev 后的初始效果如下:
退出监听,可以直接Ctrl C,输入Y回车。
3. Vue常用的属性
- el 作用域;
- data 绑定的数据;
- props 接收父组件传递的参数;
- methods 方法;
- components 组件;
- directives 自定义指令;
- filters 过滤属性;
- computed 计算属性;
- watch 监听属性;
- 生命周期属性;
(1). beforeCreate 创建前;
(2). created 创建后 (常用于发起数据请求);
(3). beforeMount 挂载前;
(4). mounted挂载后 (常用于发起数据请求);
(5). beforeUpdate 更新前;
(6). updated 更新后;
(7). beforeDestroy 摧毁前;
(8). destroyed 摧毁后;
4. Vue常用的指令
- 条件判断指令;
(1). v-if 条件成立时挂载并显示;
(2). v-else-if 紧跟 v-if 之后 , v-if 不成立时,判断当前选项是否满足条件与显示;
(3). v-else 紧跟 v-if 或 v-else-if 之后,前面的条件不成立时,挂载并显示;
最终解析如下:
2. v-for 循环指令 , 循环遍历当前选项所对应的数组或是对象;
最终解析如下:
3. v-show 显示指令,根据条件判断当前选项在DOM树上显示还是隐藏;
最终解析如下:
4. v-bind 绑定属性v-bind:src,缩写可以写成 :src;
在vue中 绑定html属性,必须使用v-bind。
最终解析如下:
v-bind的属生可以和标签原有的属性同时存在。
可以直接绑定一个数组。
可以在绑定的数组中添加对象。
5. v-model 双向数据绑定,此命令绑定的变量的值改变时,其它地方渲染这个变量的值也会同步发生改变;
(1). v-model.lazy 延迟确认后更新;
(2). v-model.number 自动将用户的输入值转为 Number 类型;
(3). v-model.trim 自动过滤用户输入的首尾空格;
当input输入框在输入时,所对应的p标签里的值也会发生改变,最终解析如下:
6. v-on 绑定事件v-on:click,缩写形式可以写成@click;
(1). v-on:click=" " 单击事件;
(2). v-on:click.once=" " 只可点击一次;
(3). v-on:click.top=" " 阻止事件冒泡;
(4). v-on:click.prevent=" " 阻止默认事件;
(5). v-on:dblclick=" " 双击事件;
(6). v-on:keydown.enter=" " 键盘按下事件,只对指定的按键号有效;
(7). v-on:keyup.13=" " 键盘弹起事件,只对指定的按键号有效;
7. v-text 将内容按文本解析;
最终,页面的内容会按如下方式去渲染。
8. v-html 将内容按html解析;
最终,页面的内容会按如下方式去渲染。
9. v-cloak 优化加载闪烁;
这个指令在渲染时会自动去掉 ,可以将具有该属性的元素初始状态不显示,等到渲染到该属性后才显示,以实现读到取数据后才加载。
5. directives 自定义指令
1. bind:只调用一次,指令第一次绑定到元素时调用;
2. update:所在组件的 VNode 更新时调用;
3. unbind: 只调用一次, 指令与元素解绑时调用;
6. filters 过滤属性
用于数据的处理,通过 | 管道符号,支持多重过滤,而且支持给过滤器传参,过滤器的本质就是一个函数,自从Vue2.0之后,就已经自带的过滤取消,不再支持,用户要想使用,有两种方法:
1. https://github.com/wy-ei/vue-filter
- 自定义过滤器;
(1). 创建,在Vue实例的filters属性中指定;
(2). 使用,依然是管道符号,只有传参方式变了:{{ price | currency('¥','@')}};
7. computed 计算属性
计算属性其实是一个方法,定义在computed属性中的方法,计算属性的优势:
- 计算属性的方法和methods中的方法实现的功能是一样的,正常情况,在methods定义方法也是可以的,但是由于方法所依赖的数据,性能开销比较大,就适合用计算属性, 计算属性是有计算缓存的,可以让更新更高效;
- 让代码更方便进行维护;
8. watch 监听属性
记录原数据,当数据更新时,会自动与原有数据进行对比。
9. components 组件
组件在vue中使用的非常普遍,它可以将一些公共的部分抽离出来,随处调用,通过传入不同的参数从而展现不同的数据,这也是vue所谓渐进式框架的精髓,在结合脚手架的开发模式中,几乎所有的页面都是一个组件,下面来看一下如何定义组件与使用组件。
定义子组件Header
在父组件Home中使用子组件Header
10. 组件之间的通信
1. 父组件给子组件传值 props;
(1). 在父组件里调用子组件时指定属性,把要传递的值赋给属性;
(2). 在子组件内部声明props,并在props里声明接收参数的属性,这样就可以通过props拿到传递过来的数据;
注意事项:
(1). 在组件中,data属性必须是带有返回值,而且返回值是对象的方法;
(2). 如果在通过属性传值时,值是会变化,通过v-bind指令将变量绑定到属性;
定义子组件Header并规定所接受的参数。
在父组件Home里调用子组件Header并传参数。
2. 子组件向父组件传值 $emit();
(1). 在调用子组件时通过v-on与@绑定自定义的事件的名称;
(2). 在子组件中传参给父组件时通过调用$emit,传递两个参数,一个为自定义的事件名称,一个为通过事件传递的数据;
定义子组件Header并声明点击事件传递参数给父组件。
在父组件Home里接收子组件Header传递过来的参数。
- 父组件获取子组件的数据或方法:$refs;
(1). 在父组件件中调用子组件时通过 ref 为子组件指定一个名称;
(2). 在父组件件中通过 $refs 调用子组件数据或方法;
定义子组件Header
在父组件Home中调用子组件Header,为它指定ref名称myHeader,在方法里通过this.$refs.myHeader获取Header的数据和方法。
- 子组件获取父组件的数据或方法:$parent;
定义子组件Header
在父组件Home中定义子组件想要的数据,让子组件获取。
5. 兄弟组件之间通信,定义事件总线 eventBus;
(1). 定义一个公共事件总线 var eventBus = new Vue(),完成事件的触发和绑定;
(2). 在第一个组件中引入事件总线,传参时eventBus.$emit('事件名','参数');
(3). 在第二个组件中引入事件总线,在生命周期钩子函数中监听eventBus.$on('事件名','function(){…...}');
定义事件总线。
在第一个组件中引入事件总线,通过事件传参。
在第二个组件中引入事件总线,通过事件接收参数。
11. 组件分发内容slot
- 单个slot;
子组件模板至少包含一个 <slot> 插口,否则调用子组件时,子组件内所分发的内容将会被丢弃。
当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身。
最初在 <slot> 标签中的任何内容都被视为备用内容,备用内容在子组件的作用域内编译,并且只有在调用子组件时,组件标签内没有要分发的内容时才显示备用内容。
定义子组件son,在组件内预留插槽slot。
在父组件里调用子组件,在子组件里分发内容。
最终显示效果如下:
- 俱名slot;
slot元素可以用一个特殊的属性 name 来配置如何分发内容,多个 slot 可以有不同的名字,具名 slot 将匹配内容片段中有对应 slot 特性的元素。
仍然可以有一个匿名 slot,它是默认 slot,作为找不到匹配的内容片段的备用插槽,如果没有默认的 slot,这些找不到匹配的内容片段将被抛弃。
定义子组件son,在组件内添加slot,为slot指定name属性。
在父组件里调用子组件,在子组件里分发内容,为内容指定slot属性值。
最终显示效果如下:
12. 动态组件is
通过使用预留的 <component> 元素,动态地绑定到它的 is 属性值,我们让多个组件可以使用同一个挂载点,并动态切换。
13. 路由配置
- 引入vue及路由中间件并使用;
- 引入所有页面组件;
- 配置路由词典;
- 导出路由配置;
- 在main.js里导入配置的路由辞典、挂载使用;
- 在app.vue里使用router-view渲染配置的路由组件;
14. 路由跳转
1. 第一种方法:指定 router-link 与 router-view,进行跳转;
2. 第二种方法:使用JS进行跳转 this.$router.push('/myLogin');
3. 第三种方法:使用a标签进行跳转,a href='#/myLogin';
15. 路由传参
- 配置接收方(main)的路由;
{ path:'/product/:id', component:product , meta: '推广素材' }
- 传参方式;
(1). href='#/product/123';
(2). router-link to='/product/123';
(3). router-link to='/product?id=123';
(4). this.$router.push('/product/123')
(5). this.$router.push({ name:'xxx' params:{ id:id } });
(6). this.$router.push({ path:'/xxx' query:{ id:id } });
注意:params传参,push里面只能是 name:'xxxx',不能是path:'/xxx',因为params只能用name来引入路由,如果这里写成了path,接收参数页面会是undefined!
- 获取参数;
(1). this.$route.query.id;
Get请注传参数获取。
(2). this.$route.params.id
Post请求传参数获取。
16. 网络请求
1. 安装axios插件,然后在main.js里引入,并将其添加为Vue的原型方法;
- 页面请求,以POST请求为例,注意下面的添加参数方法;
关于对axios请求的的封装可以查看本博客中的 Vue中封装axios请求方法 ,此处不再详细介绍。
17. 状态管理Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,如果需要构建是一个中大型单页应用,就需要考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择,下面介绍一下Vuex的用法。
- 创建store;
(1). 在页面文件中新建一个store.js文件,引入vue和vuex,并声明使明vuex;
(2). 在store.js里声明state,用来存放组件之间共享的数据;
如果页面的数据较多的时候可以在另外一个文件保存数据,然后在store.js里引入。
(3). 在store.js里声明getters,有点类似于计算属性,改变state里的数据的时候会触发getters里的方法,获取新数据;
有时候,我们需要对state的数据进行筛选或过滤,这些操作都是在组件的计算属性进行的, 如果多个组件需要用到筛选后的数据,那我们就必须到处重复写该计算属性函数;或者将其提取到一个公共的工具函数中,并将公共函数多处导入 ,这两种方法都不太理想,但是如果把数据筛选完在传到计算属性里就不用那么麻烦了,getters就是用来干这个的,getters下的函数接收接收state作为第一个参数。
(4). 在store.js里声明mutations,主要用来存放方法,这些方法用于改变state里的数据;
mutations下的函数接收state作为参数,接收payload作为第二个参数,这个参数用来记录开发者使用该函数的传递的信息,以便用这些信息作为参数和依据改变state,需要注意的是:mutations方法必须是同步方法。
(5). 在store.js里声明actions,用于异步改变state里的数据;
actions和mutations的区别:
(1). actions 提交的是 mutations,而不是直接变更状态。也就是说,actions会通过commit提交mutations,让mutations帮他提交数据的变更;
(2). action 可以包含任意异步操作,ajax、setTimeout、setInterval均可以操作;
- 引入store;
- 使用store;
如果希望可以简化写法,还可以使用vuex的辅助函数,matState、、mapGetters、mapAcions、mapMutations来映射和操作数据。