1. Vue.js-是国内开发者尤雨溪开发的js框架,它是实现UI层的渐进式框架, Vue借鉴了Angular的指令、React中组件和props等优点进行设计,从最简单的数据处理,到数据交互,到DOM操作,到路由处理等,VueJS都有完整的解决方案。
2. 两种开发模式
(1). 直接引入vue.js文件即可
(2). vue-cli
①. 确保电脑上装有NodeJS 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
项目建立完成后,目录结构如下:
④. 安装依赖
A. cd my-project 进入项目中
B. npm install 安装依赖文件
完成后,会发现项目目录下多出一个node_modules文件夹,里面就是 vue-cli 创建的一个基于 webpack 的 vue.js 项目,进入项目目录文件夹(my-project)中,就可以使用vue进行开发啦
C. npm run dev,便可以打开本地服务器实时查看效果(localhost:8080)
如果浏览器打开之后,没有加载出页面,有可能是本地的 8080 端口被占用,需要修改一下配置文件 config>index.js
建议将端口号改为不常用的端口,另外我还将 build 的路径前缀修改为 ' ./ '(原本为 ' / '),是因为打包之后,外部引入 js 和 css 文件时,如果路径以 ' / ' 开头,在本地是无法找到对应文件的(服务器上没问题),所以如果需要在本地打开打包后的文件,就得修改文件路径
npm run dev后的初始效果
退出监听,可以直接Ctrl+C,选择Y
3. Vue常用的属性
(1). el 作用域(一般为顶层容器的id)
(2). data 绑定的数据
(3). props 接收父组件传递的参数
(4). methods 方法
(5). components 组件
(6). directives 自定义指令
(7). filters 过滤属性
(8). computed 计算属性
(9). watch 监听属性
(10). 生命周期属性
①. beforeCreate 创建前
②. created 创建后 (常用于发起数据请求)
③. beforeMount 挂载前
④. mounted挂载后 (常用于发起数据请求)
⑤. beforeUpdate 更新前
⑥. updated 更新后
⑦. beforeDestroy 摧毁前
⑧. destroyed 摧毁后
4. Vue常用的指令
(1). 条件判断指令
A. v-if 条件成立时挂载并显示
B. v-else-if 紧跟v-if之后 , v-if不成立时,判断当前选项是否满足条件与显示
C. 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 双向数据绑定,此命令绑定的变量的值改变时,其他地方渲染这个变量的值也会同步发生改变。
①. v-model. lazy 延迟(确认后)更新
②. v-model. number 自动将用户的输入值转为 Number 类型
③. v-model. trim 自动过滤用户输入的首尾空格
当input输入框在输入时,所对应的p标签里的值也会发生改变,最终解析如下:
(6). v-on 绑定事件,缩写形式:v-on:click可以写成@click
①. v-on:click=" " 单击事件
②. v-on:click.once=" " 只可点击一次
③. v-on:click.top=" " 阻止事件冒泡
④. v-on:click.prevent=" " 阻止默认事件
⑤. v-on:dblclick=" " 双击事件
⑥. v-on:keydown.enter=" " 键盘按下事件,只对指定的按键号有效
⑦. 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 过滤属性
用于数据的处理,与ng一样,通过 | 管道符号,支持多重过滤,而且支持给过滤器传参,过滤器的本质就是一个函数,自从Vue2.0之后,就已经自带的过滤取消,不再支持,用户要想使用,有两种方法:
①. https://github.com/wy-ei/vue-filter
②. 自定义过滤器
A. 创建,在Vue实例的filters属性中指定
B. 使用,依然是管道符号,只有传参方式变了:{{ price | currency('¥','@')}}
7. computed 计算属性
计算属性其实是一个方法,定义在computed属性中的方法,计算属性的优势:
(1). 计算属性的方法和methods中的方法实现的功能是一样的,正常情况,在methods定义方法也是可以的,但是由于方法所依赖的数据,性能开销比较大,就适合用计算属性, 计算属性是有计算缓存的,可以让更新更高效
(2). 让代码更方便进行维护
8. watch 监听属性
记录原数据,当数据更新时,会自动与原有数据进行对比
9. components 组件
组件在vue中使用的非常普遍,它可以将一些公共的部分抽离出来,随处调用,通过传入不同的参数从而展现不同的数据,这也是vue所谓渐进式框架的精髓,在结合脚手架的开发模式中,几乎所有的页面都是一个组件,下面来看一下如何定义组件与使用组件。
定义子组件Header
在父组件Home中使用子组件Header
10. 组件之间的通信
(1). 父组件给子组件传值 props
①. 在父组件里调用子组件时指定属性,把要传递的值赋给属性
②. 在子组件内部声明props,并在props里声明接收参数的属性,这样就可以通过props拿到传递过来的数据
注意事项:
①. 在组件中,data属性必须是带有返回值,而且返回值是对象的方法
②. 如果在通过属性传值时,值是会变化,通过v-bind指令将变量绑定到属性
定义子组件Header并规定所接受的参数
在父组件Home里调用子组件Header并传参数
(2). 子组件向父组件传值 $emit()
①. 在调用子组件时通过v-on与@绑定自定义的事件的名称
②. 在子组件中传参给父组件时通过调用$emit,传递两个参数,一个为自定义的事件名称,一个为通过事件传递的数据
定义子组件Header并声明点击事件传递参数给父组件
在父组件Home里接收子组件Header传递过来的参数
(3). 父组件获取子组件的数据或方法:$refs
①. 在父组件件中调用子组件时通过 ref 为子组件指定一个名称
②. 在父组件件中通过 $refs 调用子组件数据或方法
定义子组件Header
在父组件Home中调用子组件Header,为它指定ref名称myHeader,在方法里通过this.$refs.myHeader获取Header的数据和方法
(4). 子组件获取父组件的数据或方法:$parent
①. 在子组件中通过 $parent 调用父组件的数据或方法
定义子组件Header
在父组件Home中定义子组件想要的数据,让子组件获取
(5). 兄弟组件之间通信,定义事件总线 eventBus
①. 定义一个公共事件总线 var eventBus = new Vue(),完成事件的触发和绑定
②. 在第一个组件中引入事件总线,传参时eventBus.$emit('事件名','参数')
③. 在第二个组件中引入事件总线,在生命周期钩子函数中监听eventBus.$on('事件名','function(){…...}')
定义事件总线
在第一个组件中引入事件总线,通过事件传参
在第二个组件中引入事件总线,通过事件接收参数
11. 组件分发内容slot
(1). 单个slot
子组件模板至少包含一个 <slot> 插口,否则调用子组件时,子组件内所分发的内容将会被丢弃
当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身
最初在 <slot> 标签中的任何内容都被视为备用内容,备用内容在子组件的作用域内编译,并且只有在调用子组件时,组件标签内没有要分发的内容时才显示备用内容
定义子组件son,在组件内预留插槽slot
在父组件里调用子组件,在子组件里分发内容
最终显示效果如下:
(2). 具名slot
slot元素可以用一个特殊的属性 name 来配置如何分发内容,多个 slot 可以有不同的名字,具名 slot 将匹配内容片段中有对应 slot 特性的元素
仍然可以有一个匿名 slot,它是默认 slot,作为找不到匹配的内容片段的备用插槽,如果没有默认的 slot,这些找不到匹配的内容片段将被抛弃
定义子组件son,在组件内添加slot,为slot指定name属性.
在父组件里调用子组件,在子组件里分发内容,为内容指定slot属性值
最终显示效果如下:
12. 动态组件is
通过使用预留的 <component> 元素,动态地绑定到它的 is 属性值,我们让多个组件可以使用同一个挂载点,并动态切换
13. 路由配置
(1). 引入vue及路由中间件并使用
(2). 引入所有页面组件
(3). 配置路由词典
(4). 导出路由配置
(5). 在main.js里导入配置的路由辞典、挂载使用
(6). 在app.vue里使用router-view渲染配置的路由组件
14. 路由跳转
(1). 第一种方法:指定 router-link 与 router-view,进行跳转
(2). 第二种方法:使用JS进行跳转 this.$router.push('/myLogin')
(3). 第三种方法:使用a标签进行跳转,a href='#/myLogin'
15. 路由传参
(1). 配置接收方(main)的路由
{ path:'/product/:id', component:product , meta: '推广素材' }
(2). 传参方式
①. href='#/product/123'
②. router-link to='/product/123'
③. router-link to='/product?id=123'(get传参)
④. this.$router.push('/product/123')
⑤. this.$router.push({ name:'xxx' params:{ id:id } })
⑥. this.$router.push({ path:'/xxx' query:{ id:id } })(get传参)
注意:params传参,push里面只能是 name:'xxxx',不能是path:'/xxx',因为params只能用name来引入路由,如果这里写成了path,接收参数页面会是undefined!
(3). 获取参数
①. this.$route.query.id (get传参数获取)
②. this.$route.params.id (post传参数获取)
16. 网络请求
(1). 安装axios插件,然后在main.js里引入,并将其添加为Vue的原型方法
(2). 页面请求,以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来映射和操作数据