vue介绍
1天基础内容 7天 webpack
第一天
指令 组件 过滤器 路由 网络请求
第二天
webpack
搭建项目(手动)
第三天---第八天
项目 webpack打包压缩 上线
Vue的基本概念
Vue是什么?
渐进式 JavaScript 框架
特定:
易用
灵活
性能
一个用以创建用户接口的直观、快速、简洁的 MVVM 框架
Vue能做什么?
PC端 管理系统 网站
移动端
WebApp
原生App
如何学习?
https://cn.vuejs.org/v2/guide/
https://stackoverflow.com/
https://segmentfault.com/p/1210000008583242/read?from=timeline
作者
尤雨溪
MVVM
M:model 模型
V:view 视图
VM:view-model 相当于控制器
v ---> vm ---> model
|
v <--- vm <--- |
好处:
1、解耦
2、方便的复用
指令
{{}} 插值表达式
指令:
拓展html的标签,先在html占位,在利用真实的数据替换
让我们程序员只操作数据,即可更新视图
注意:
Vue中的指令是以v-开头的
v-text & v-html
给我们页面中的span p标签设置值
v-text 纯文本
v-html 解析带有html标签的字符串
v-bind
在html中,比如img标签为例,src的值不写死,而是src的值来自model,这个时候就要使用v-bind了
注意:以后我们视图中(img)需要的数据,必须来自model的时候,这个时候你就要想到v-bind
`v-bind:` 可以简写成 `:`
v-on
绑定事件
ng-click Angular中给某个元素绑定一个点击事件,一般都是给button绑定
注意点:
1、当要执行的函数没有参数的时候,可以写`()`也可以不写,如果有参数必须加上`()`
2、v-on:可以缩写成 `@`
v-model
双向数据绑定
model ---> 视图
视图 ---> model
v-if/v-show
v-if&v-show 接收的是boolean值
区别:
true的时候没啥区别
false的时候有区别
if 不会创建元素
show 会创建元素,但是隐藏起来
开发中如何抉择?
如果需要频繁切换(显示) show
如果不需要频繁切换(显示) if
参考:https://cn.vuejs.org/v2/guide/conditional.html
注意点:
v-if 后面接的v-else-if v-else必须紧跟v-if的后面,中间不要有任何其它元素,否则有问题
v-for
作用:
遍历
你要遍历什么,就作用于哪个元素上面
注意:
1、如果要获取我们遍历的每一行的索引
2、在使用v-for遍历元素的时候,最好给每一行设置一个唯一的标识符,通过给遍历的每个元素设置一个唯一的key值即可
组件
作用:
某一类功能代码的集合
在Vue中,你就可以认为,我们看到的每一个页面就是一个组件
组件就是代码的集合,然后我们会把实现某一功能(展示新闻列表)的代码,写在某一个文件中,我们把这个文件就称之为组件
在Vue中,凡是看到.vue结尾的文件,就是一个组件,组件里面就写了很多代码
写法
前四种,都是在html里面写的(会,看得懂就行)
第一种:
先定义,再注册,再使用
第二种:
定义注册一步到位,再使用
第三种:都是对组件中template的内容优化
template
第四种:都是对组件中template的内容优化
最后一种,在.vue(单文件组件)结尾的文件中写的
注意点:
1、在定义我们组件,必须给它一个根元素
2、在组件内部定义Model,data必须是一个函数,并且函数内部必须要返回一个对象
参考:https://cn.vuejs.org/v2/guide/components.html#data-必须是函数
好处:
1、可以把那些分散的功能,写在一个组件里面去,这样body中的代码比较少,并且看上去简洁明了
过滤器
作用:
过滤数据,一般是把服务器返回的数据,过滤成符合页面展示的数据
私有过滤器
只在该组件起作用
全局过滤器
所有的组件中都起作用
Vue.filter('过滤器的名称',处理函数)
注意点:
1、过滤器是一个函数,必须要传入值,并且必须要有返回值
2、最好把Vue.filter放在组件注册之前
路由
作用:
前端路由:根据触发的不同的路径规则,呈现不同的页面(组件)在浏览器中
Angular
html
ng-view 占位
js
$routerProvider.when('/路径',{
templateUrl:'',
controller:'xxx'
})
Vue和上面的差不多,写法参考下面
前提:
导入vue.js
导入vue-router.js
正式写代码:
html
router-link 触发的超链接,底层会转成a标签
router-view 相当于ng-view
js
1、定义组件(不要注册)
2、创建路由对象,设置路由规则(注册组件到路由中)
目的:触发了谁,把谁展示出来
3、把我们上面创建好的路由对象,注入到根实例 (new Vue({}))
路由的其它知识点
1、想一上来就让它呈现某个组件的内容
重定向:https://router.vuejs.org/zh-cn/essentials/redirect-and-alias.html
2、通过路由跳转到某一个组件的时候,如何传递参数
动态路由匹配:https://router.vuejs.org/zh-cn/essentials/dynamic-matching.html
网络请求
vue-resource
前提:
导入vue.js
导入vue-resource.js
GET请求
POST请求
注意点:
this.$http.post(url,参数,{emulateJSON:true})
emulateJSON:true 设置请求头的Content-Type:application/x-www-form-urlencoded
JSONP请求
豆瓣
jsonp方法
第二部分
内容回顾
MVVM
M:model
V:View
VM:View-Model 相当于控制器,起到调度的作用
好处:
耦合性低
视图复用性强
指令
通过指令可以让程序员较少对dom的操作,把关注点放在数据上
v-text 插值表达式{{}} 纯文本
v-html 可以解析html
v-bind 绑定,html标签的属性值,不是写死的
v-bind: / :
v-on 绑定事件 v-on: / @ click dbclick mousexxx
v-if/v-show v-if/v-else 一定要挨着写
v-for (item,index) in 数组 key="唯一的值"
组件
概念:功能代码的集合,组件就相当于可以看到的页面
好处:把一些零散的代码封装起来,使用的时候,通过组件的名称使用
五种
前四种(看得懂就行,实际开发中一般推荐使用第五种)
第一种:先定义,再注册,再使用
var 组件 = Vue.extend({}) var 组件 = {}
Vue.component('组件的名称',组件)
id=app的div中,通过自定义标签的形式使用
<组件的名称>组件的名称>
第二种:定义注册一步到位,再使用
第三种:对定义组件的时候,template属性优化
template:"#templateId"
第四种:对定义组件的时候,template属性优化
template:"#templateId"
第五种,单文件组件,不能直接运行在浏览器中,webpack通过loaders的形式,来转成浏览器能过执行的代码
过滤器
对服务器返回的数据,进行过滤,把数据过滤成符合展示需求的数据
私有
定义在组件
filters:{
过滤器:函数,接收要过滤的原始数据,返回过滤之后的数据,要参数和返回值
}
特点:只能在该组件中使用
全局
Vue.filter('过滤器的名称',处理函数)
处理函数中必须要有参数与返回值
注意点:
过滤器处理函数中的参数说明,第一个参数,就是要过滤的原始数据,第二个参数,就是调用过滤器的时候,传递的第一个参数
路由
作用:
根据触发的不同的路径,展示不同内容在浏览器中给用户看
Angular
html
ng-vew
js
模块.config
路径
templateUrl:''
Vue
html
router-view
===> a标签
js
1、定义组件
2、创建路由对象,设置路由规则
const router = new VueRouter({
routes:[
{path:'路径',component:'组件'}
]
})
3、把router注入到根实例
new Vue({
el:'#app',
router
})
发送网路请求
vue-resource
导入vue
导入vue-resource
GET:
this.$http.get(url).then(function(response){
},function(err){
})
POST:
this.$http.post(url,{key:value,key1:value1},{emulateJSON:true}).then(function(response){
},function(err){
})
JSONP:
this.$http.jsonp(url).then(function(response){
},function(err){
})
今日内容目标
Webpack
概念
Webpack 是当下最热门的前端资源模块化管理和打包工具。它可以将许
多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还
可以将按需加载的模块进行代码分隔,等到实际需要的时候再异步加
载。通过 loader 的转换,任何形式的资源都可以视作模块,比如
CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、
Coffeescript、 LESS 等。
和Gulp比较
Gulp 同步打包的方式 require("")
优势:
http://zhaoda.net/webpack-handbook/what-is-webpack.html
保护源代码
达到的理解程度
1、webpack能打包我们的源代码,把我们所有的源代码最终打包成一个bundle.js
2、很强大,使用任何模块组织的代码(CommonJS、AMD、ES6xxx)都能打包
3、打包优化之后,就可以直接上线
核心概念
入口:
webpack打包的入口文件
输出:
这个就是对源代码打包之后,得到的文件,文件我们一般命名为bundle.js
Loader:
默认情况下,webpack只能打包.js结尾的文件,但是webpack提供了很多Loader,能打包项目中任何文件
配置文件:
简化我们的配置,让我们少写代码
插件:
比如压缩js,比如开发阶段实现的热重载,xxx
为了让webpack更加强大
如何学习&查找Webpack资料
入门:http://zhaoda.net/webpack-handbook/start.html
官网:
1.x https://webpack.github.io/
2.x https://webpack.js.org/
优化:百度搜索webpack优化
出了问题:百度 www.stackoverflow.com
实际演练
前提:
安装好`webpack`全局包 npm i webpack -g
打包单个.js文件
步骤:
1、切换到项目根目录
2、使用webpack全局包打包即可
webpack 入口文件(entry.js) 输出文件(bundle.js)
3、打包得到bundle.js,建立index.html,在index.html
中导入打包之后的bundle.js
4、运行
注意点:
在index.html中导入的一定是打包之后的输出文件
打包多个具有依赖关系的.js文件
前提:
写好entry.js中的代码,也写好module.js中的代码
根据我们CommonJS来组织我们的代码的
步骤:
1、切换到项目根目录
2、使用webpack全局包打包即可
webpack 入口文件(entry.js) 输出文件(bundle.js)
3、打包得到bundle.js,建立index.html,在index.html
中导入打包之后的bundle.js
4、运行
注意点:
在index.html中导入的一定是打包之后的输出文件
Webpack 会分析入口文件,解析包含依赖关系的各个文件。
这些文件(模块)都打包到 bundle.js 。
打包非.js文件
打包的步骤和上面一样,但是有注意事项
Loaders:https://doc.webpack-china.org/loaders/
以打包.css文件为例(需要额外做的步骤)
1、安装style-loader&css-loader
cnpm i style-loader css-loader --save-dev
2、在入口文件中导入css的时候,按照下面这样写
require('!style-loader!css-loader!./site.css')
3、针对第二步,如果导入的css过多,还可以做一个简化,在入口文件,导入的时候,可以不用写前面的
require('./site.css')
但是,在使用webpack打包的时候,得这样写
webpack entry.js bundle.js --module-bind "css=style-loader!css-loader"
注意点:
"css=style-loader!css-loader" 使用双引号即可,不然会报错
配置文件
作用:简化打包的操作
步骤:
1、在项目根目录下创建一个文件名称叫 webpack.config.js的文件(默认文件名称)
2、把我们原先在cmd中写的命令,全部写到webpack.config.js中(强烈建议大家拷贝)
3、最后在根目录下,执行webpack即可打包了
插件
作用:让我们Webpack的功能更加强大
全局包&本地包
安装方式不一样
全局包 npm i webpack -g
本地包 npm i webpack --save-dev
使用的场合不一样
全局包 用在终端里面,执行命令
本地包 用在项目里面的
安装的地方不一样:
全局包:是安装在个人目录下 C:\Users\你自己的用户名\AppData\Roaming\npm
本地包:项目的根目录的node_modules中
注意点:
有些包既要全局安装,又要在项目中安装,不要觉得奇怪,应用的地方不一样
plugins在我们的webpack.config.js中写的时候,必须和entry,output,module同级
webpack打包的指令说明
webpack --progress
webpack --config 指定文件名称
webpack --watch 监控源文件,只要发生了更改就可以自动打包【了解】
wepack -p 压缩,局限性,自带的压缩里面对部分es6还是压缩不了,用webpack这个第三方中uglifyjs 【了解】
如果以后发现在终端里面有很长的命令需要执行,可以把它写在package.json中的scripts里面,这个里面也是通过属性名称和值的方式来记录的,以后我们就可以在终端中 npm run 属性名称,他就会把属性名称对应的值,拿到终端中去执行
手动搭建项目结构
基本步骤
1、把项目中的最基本的文件和文件夹建立起来
src : 项目的源代码目录
|-- main.js 项目打包的入口文件
|-- App.vue 项目启动之后看到的第一个组件(根组件)
package.json: 项目的配置文件
webpack.develop.config.js
2、在我们浏览器中,看到一个Hello Vue
3、实现我们项目的所见及所得(更改项目的源代码,能在浏览器看到效果)
在我们浏览器中,看到一个Hello Vue
1、在App.vue template中写了 Hello Vue
2、在webpack.develop.config.js中写了
entry
output
3、main.js中写代码
3.1 导入App.vue
3.2 在我们的浏览器中要想看到App.vue中Hello Vue
第一个.vue文件要被webpack打包,需要借助一个vue-loader的东西
第二个,我们要想App.vue写的内容被浏览器识别,必须导入Vue
3.3 导入vue
import Vue from 'vue'
创建一个根实例,里面要写两个属性
el:Vue解析的范围
render:决定把哪个组件挂在到id=app的div中去
参考:https://cn.vuejs.org/v2/guide/render-function.html
4、打包
在webpack.develop.config.js中配置vue-loader
webpack --config webpack.develop.config.js --progress
bundle.js
5、运行
5.1 在项目根目录新建一个index.html
id=app的div
5.2 在index.html导入bundle.js
当我们更改了App.vue(项目启动之后,看到的第一个组件)之中的内容,在浏览器中实时看到其效果,并且是不刷新浏览器的情况下
本地包 html-webpack-plugin
代码写在 webpack.develop.config.js中的plugins里面
作用:
它是以一个参照html为模版,在浏览器的内存中,生成一个index.html,并且自动给我们导入在内存中生成bundle.js
使用步骤:
1、安装html-webpack-plugin webpack webpack-dev-server
2、在项目的根目录下创建一个参照的html(template.html)
注意:参照文件只要写id=app的div即可,其它不要写
3、在webpack.develop.config.js中的plugins中写代码
见webpack.develop.config.js
全局包 webpack-dev-server
代码写在 终端
它能把我们的项目的源代码打包成bundle.js(放在浏览器内存中的)
运行项目,在内存中生成bundle.js并且把bundle.js插入到index.html中,并且最后运行index.html
在终端里面生成的指令:https://webpack.github.io/docs/webpack-dev-server.html
webpack-dev-server --progress --config webpack.develop.config.js --port 3008 --open --hot
webpack-dev-server & webpack
相同点:
都能对源代码打包,webpack-dev-server 很厉害,webpack能做的事,它都能做,并且还能做webpack不能做的事情,比如热更新
webpack-dev-server & webpack 打包的指令和后面接的参数都是一样的 --progerss --config ...
它们两个在打包的时候,都是全局包
不同点:
wepack-dev-server 开发阶段使用,打包出来的东西放在浏览器内存中,运行速度特别快
webpack 生产阶段使用,会在文件夹中生成一个bundle.js,这个文件最终是要和index.html最终一起发布到服务器上面去
今日项目中用的包
1、搭建项目时,在浏览器中想看到Hello Vue
vue vue-loader vue-template-compiler style-loader css-loader
vue:解析Vue指令和template标签
vue-loader:加载和转译 Vue 组件
vue-template-compiler style-loader css-loader 这几个都是vue-loader依赖的,所以必须安装,不然报错
安装
cnpm i vue --save
cnpm i vue-loader vue-template-compiler style-loader css-loader --save-dev
2、实现热更新的时候
html-webpack-plugin webpack webpack-dev-server
安装:
cnpm i html-webpack-plugin webpack webpack-dev-server --save-dev
vue-cli的使用
https://github.com/vuejs/vue-cli
安装:
npm install -g vue-cli
生成项目
vue init webpack-simple my_vue
运行
cd my_vue
npm install
npm run dev
第三部分
1.时间格式化
包:
生产环境的包:moment
安装方式:
npm install moment --save
2.jquery
包:
生产环境的包:jquery
安装方式:
npm install jquery --save
第四部分
内容回顾
App.vue
头部
NavigationBar
实现方案:mint-ui
中间动态变化内容
vue-router
底部TabBar
实现方案:mint-ui
vue-router 集成及使用
集成:
安装
main.js
导入
Vue.use(VueRouter)
//Vue.prototype.$route,Vue.prototype.$router
使用:
html
router-view 占位
router-link 触发
js
组件,创建单文件组件,在main.js导入
创建路由对象,设置路由规则
在格实例中注入,让我们项目拥有路由的功能
home.vue
轮播图
九宫格
今日课程目标
隐藏或是显示(头部的返回按钮和底部TabBar)
技术点:
监控路由的变化,拿到当前路径
watch:{
监控的属性名称:处理函数
}
属性名称可以是Vue的成员
写代码:
1、写在需要获取路由之后,处理的地方,App.vue
2、watch要监控`$route`
注意:
处理函数不能是箭头函数
点击返回按钮返回
声明式导航&编程式导航
导航:简单的理解就是前进、后退
声明式导航
router-link,写在组件的template里面的
编程式导航
router,写在我们js函数中的
router.push 一般是前进
router.go 既可以有前进,也可以有后退
router&route
都是属于vue-router的东西,当我们在main.js中使用了Vue.use(VueRouter),就会在Vue原型上绑定两个属性$route、$router
作用不一样:
$route: 通过它能够获取路由传递过来的参数,获取到当前浏览器地址栏的路径
$router: 编程式导航,页面前进后退就靠他
显示和隐藏TabBar
参考:https://cn.vuejs.org/v2/guide/class-and-style.html
抽取轮播子组件(父子组件之间传值)
参考:
https://cn.vuejs.org/v2/guide/components.html
实现方式1:
每个组件中写一套相同的代码(新闻详情、图片详情、商品详情),不可取
实现方式2:
把评论所有的功能抽成一个单独的组件,在需要它的组件里面,集成进来,并且给评论组件,传递数据(必要的条件),然后才能帮我们做事
我们要解决的问题
1、抽取评论组件(新建一个评论组件即可)
2、在需要评论的地方(新闻详情),把评论组件集成进来
3、把评论组件集成进来之后,要给评论组件传值,这样它才能帮我们做事
父子组件(以新闻详情组件集成评论组件为例)
父组件:新闻详情组件
子组件:评论组件
为了在组件中传值更加顺畅
步骤
1、新建一个评论子组件
2、在需要它的父组件中(新闻详情组件),集成它
2.1 导入子组件
2.2 注册
2.3 在父组件的template中使用
3、新闻详情父组件给评论子组件传值
接收方(评论子组件)
通过props声明期望获取的数据
传递方(新闻详情父组件)
在父组件的template中使用子组件的时候,通过属性名称:值的方式,传递
评论功能的实现
1、画UI(搭建界面)
完成
2、完成评论数据的展示
注意点:
2.1、一上来只会展示第一页的数据
2.2、当用户点击加载更多的时候,发送请求,加载第二页,把第二页的也展示出来
3、完成提交评论
3.1 获取评论内容
双向数据绑定
原生
jquery
ref
3.2 提交评论给服务器
3.3 评论成功之后需要做哪些事?
图片分享
图片列表
1、创建图片列表组件(photolist.vue)
2、home.vue的图片分享按钮中 router-link
3、在main.js中设置路由规则
图片列表的分类
1、获取数据
2、渲染
分类下面的图片列表
图片详情
1、跳转到图片详情,带图片id,
步骤:
1、创建photoinfo.vue
2、在photolist.vue中触发它 router-link
3、在main.js中设置路由规则
2、获取数据
3、渲染
集成评论子组件
1、导入评论子组件
2、注册 components
3、在父组件的template中使用子组件,并且传参
图片详情中的缩略图
1、发送网络请求,获取图片数组
2、展现图片数组
九宫格布局
3、实现预览功能
https://github.com/LS1231/vue-preview
第五部分
内容回顾
根据路由显示隐藏返回和Tabbar
关键点:
监控到路由的变化,watch--->$route
显示/隐藏 返回按钮 v-show
显示/隐藏 tabBar :class="xx?'':''"
评论子组件
为什么要抽取
抽取的步骤
1、创建子组件(独立的组件,具有template,style,script)
2、父组件集成子组件
3、父组件传值给子组件
图片分享
1、获取数据
2、渲染页面
3、优化样式
今日目标
图片预览
获取数据,展示出来
1、使用vue-resource获取数据
2、使用mui的九宫格布局
实现图片预览
基于Vue:
https://github.com/xLogic92/vue-picture-preview
https://xiecg.github.io/other/vue-fancybox/#/baseUsage
PhotoSwipe
原生js写的,很多地方都可以用
http://photoswipe.com/
Vue-Preview
集成
安装 npm i vue-preview -S
import VuePreview from 'vue-preview'
Vue.use(VuePreview)
使用
参考文档:https://github.com/LS1231/vue-preview
商品功能
商品列表
1、获取数据
2、渲染
商品详情
1、跳转到商品详情
1.1、创建一个商品详情组件
1.2、在商品列表组件触发router-link
1.3、在main.js中设置路由规则
2、抽取轮播图
3、渲染商品详情
4、编程式导航
抽取轮播
1、创建一个轮播子组件
2、在home.vue、goodsinfo.vue中集成
3、home.vue和goodsinfo.vue传递数据给轮播子组件,让轮播子组件做事情
3.1、把首页需要轮播数据的url和商品详情中需要轮播数据的url当作参数传递过去即可
图文介绍
1、监听图文按钮的点击
2、通过编程式导航跳转到图文介绍组件,并且跳转过去的同时,把商品id带过去
通过路由规则的设置才知道要跳转到哪个组件中去
3、来到了图文介绍组件,拿着id发送网络请求
4、渲染
触发路由靠的是 命名路由的方式,传参是通过params
商品评论
1、监听商品评论的点击
2、通过编程式导航的方式,跳转到商品评论组件中去,并且要把商品的id带过去
3、来到了商品评论组件,将我们的商品id传递给评论子组件
触发路由靠的是 path的方式,传参是通过query
关于究竟用哪种方式触发路由及哪种方式传参,根据实际业务来
加入购物车功能
数量子组件内部数据发生变化之后,告知父组件
1、在商品详情父组件中集成数量选择子组件
1.1、创建一个subnumber.vue
1.2、集成到父组件中(goodsinfo.vue)
1.3、实现subnumber内部的逻辑(界面和逻辑)
2、当子组件中的值发生更改之后传递给父组件
通过自定义事件 click dbclick
子组件传值给父组件
1、子组件(发送发),通过$emit触发自定义事件传值
this.$emit('numberChange',this.count)
2、父组件(接收方),通过v-on:监听自定义事件,实现处理函数,接收到值
注意:在监听事件的时候,我们处理函数,你写上函数名称即可
getGoodsCount(count){
console.log("---子组件传递过来的值---",count)
}
第六部分
内容回顾
今日内容
组件的生命周期
人的生命周期:
出生 ---> 幼儿园 ---> 小学 --->初中--->高中--->大学--->工作--->结婚--->生孩子--->幸福快乐的生活--->死亡
组件生命周期
beforeCreate ---> created ---> beforeMount ---> mounted ---> beforeUpdate ---> updated ---> beforeDestory ---> destoryed
概念:
在组件执行的过程中,在适当的时机,Vue底层在不同的时间点会自动调用这个生命周期钩子(函数)
注意点:
1、这些生命周期函数(钩子)都是Vue底层自动帮我们调用的
2、只有我们在组件中实现了这些生命周期钩子,Vue才会调用
3、生命周期函数和普通函数不一样的地方在于,生
命周期是Vue提供的,我们只需要实现了对应的函
数,Vue在运行中就会自动帮我们的调用,但是普通
函数,我们必须自己手工调用才能执行
4、这些生命周期钩子中,除了beforeUpdate ---> updated其它都只会调用一次
组件生命周期的应用场景
created:发送网络请求
统计用户偏好:
beforeCreate 记录一个时间 11:43:23
beforeDestory 记录一个事件 11:44:23
1分钟 发送请求给后台 newslist.vue
记录之前的状态
比如在有些页面填写了一些信息,没有提交,就不小心返回了,在beforeDestory记录起来,下次进去的时候,从localStorage中取出来,填充上去
记录上一次滚动到了哪里,返回的时候记录一下,再次进去的时候,滚动到指定位置
思考
如果数据慢了,这个时候如何解决刚刚那个问题?
非父子组件传值
以点击加入购物车,然后徽标值变化为例
商品详情组件 ---> App.vue
什么样的组件才构成父子组件关系
一个组件中通过components注册的组件,才称之为它的子组件
步骤:
1、创建一个空的Vue对象 bus
2、在发送发(goodsinfo.vue)通过 bus.$emit('自定义事件名称',值)
3、在接收方(App.vue)通过 bus.$on('自定义事件名称',处理函数)
Vuex
概念
在各个组件之间共享数据用的,全局共享
局部数据,组件内专用的,就是局部数据
状态 === 数据
什么情况下我应该使用 Vuex?
https://vuex.vuejs.org/zh-cn/intro.html
几个核心概念
State:
存储数据的地方,本身是个对象,通过属性名称和值的方式来表示的 属性名称:js类型(数组、对象,字符串...)
Getters:
从State中取出数据,他也是个对象,对象里面提供的是 属性名称:函数
Mutations
同步的往State总存储数据,他也是一个对象,对象里面提供的是 属性名称:函数
Mutations ---> State
Actions
异步的间接的往State总存储数据,他也是一个对象,对象里面提供的是 属性名称:函数
Actions ---> Mutations ---> State
Modules
注意事项
1、我们一个完整的仓库里面有State、Getters、Mutations、Actions,但是不是说必须要有这四个,这是可选的
2、如果当我们在实际开发中,一个仓库不够用,通过Modules来创建多个仓库
3、当使用Actions往State中存值的时候,不能直接存,必须借助同步(Mutations)去存
4、在Mutations中的所有函数中,第一参数是State
代码步骤
1、创建仓库
参考:https://vuex.vuejs.org/zh-cn/installation.html
1.1、安装包vuex
1.2、集成到项目中来
1.2.1、
import Vuex from 'vuex'
Vue.use(Vuex)
1.2.2、创建一个空仓库
1.2.3、注入到根实例中,让我们整个项目都能使用Vuex进行全局状态管理
2、往仓库中存储数据(点击加入购物车把商品的数据存起来)
3、从仓库中取数据(App.vue中展示徽标的时候,购物车组件)
第七部分
内容回顾
生命周期
beforeCreate
beforeDestory
注意:
生命周期钩子是Vue提供的,我们程序员只需要实现相应的生命周期钩子即可,在生命周期钩子,写上自己的业务逻辑即可,这样的话,Vue就会在恰当的时机调用并且执行我们缩写的代码
非父子组件传值
1、搞一个公共的vue对象 bus
2、在传值方,通过bus.$emit('xxx',{name:'xxx',count:10})触发事件
3、在接收方,通过bus.$on('xxx',function(count){
})
注意:事件只需要注册一次
Vuex
概念
五大核心概念
State 状态(数据)
Getters 从State中获取数据
Mutations 同步的方式对State中的数据进行更改
Actions 异步的方式对State中的数据进行更改
注意:这个得借助Mutations中的方法进行更改
Modules 创建多个仓库
代码
1、集成Vuex
安装
导入
使用
2、在项目中使用
2.1 创建了空仓库
2.2 别忘记注入进来
2.3 写store中的代码
state :{goodsList:[]},
mutations : {
函数
}
actions:{
}
getters:{
}
今日目标
各大电商购物车数据如何存储
Vuex 内存存储机制
京东:
没有登录的时候,默认在本地 cookies
优势:减少服务器资源消耗,充分利用用户浏览器的资源
缺点:可能会流失客户
登录之后 存在服务器
淘宝:
都是存在服务器
优点:客户的流失率可能会小一些
缺点:消耗服务器资源
购物车
[
{goodsId:"87",count:2},{goodsId:"88",count:3},
{goodsId:"87",count:3}
]
购物车代码思路分析
1、获得数据
[
{goodsId:"87",count:2},{goodsId:"88",count:3},
{goodsId:"87",count:3}
]
===> 目标
[
{goodsId:"87",count:5,title:'xxx'},
{goodsId:"88",count:3,title:'xxx'}
]
1.1、把存在Vuex中的数组,转化成对象
[
{goodsId:"87",count:2},{goodsId:"88",count:3},
{goodsId:"87",count:3}
]
===> var tempObj = {"87":5,"88":3}
1.2、遍历对象,把key放入到一个数组中
===> ["87","88"]
1.3 把数组中的商品id,给他整成符合后台要求的字符串参数
===> 87,88
1.4 发送请求,请求回来之后,给我们每个商品动态加上count
[
{goodsId:"87",count:tempObj["87"],title:'xxx'},
{goodsId:"88",count:tempObj["88"],title:'xxx'}
]
2、展示商品列表
2.1、展示购物车列表
2.2、展示提示信息
3、购物车里面操作的业务逻辑
1、开关发生变化的时候
统计信息(抽取公共的方法)
删除按钮样式的变化
2、删除按钮的删除操作
Vuex中的对应的数据要干掉
购物车中对应的数据要删除掉
统计信息(抽取公共的方法)
App.vue中徽标的值要发生变化
工作中遇到问题如何去做
1、先把整体功能做一个区分
2、再对各个功能各个击破
支付流程的体验(以美团买汉堡包用支付宝支付为例)
1、登录
2、提交订单
在后台数据库中生成一条该用户买的商品的记录
id name price pay_status
zni763 汉堡王猪肘子 39.9 0
https://mclient.alipay.com/home/exterfaceAssign.htm?alipay_exterface_invoke_assign_client_ip=47.74.9.76&body=%E7%BE%8E%E5%9B%A2%E8%AE%A2%E5%8D%95-124231929078451505985191&subject=%E7%BE%8E%E5%9B%A2%E8%AE%A2%E5%8D%95-124231929078451505985191&sign_type=RSA¬ify_url=http%3A%2F%2F10.53.86.13%3A8966%2Fpaygate%2Fnotify%2Falipay%2Fpaynotify%2Fwap&out_trade_no=124231929078451505985191&return_url=http%3A%2F%2Fmeishi.meituan.com%2Fi%2Forder%2Fresult%2F3948233345&sign=PcXeDQ7r4AVP1Fbz8pvKcS%2Bvkoppr8uvr6sw5wO6aXJjAnRCNhKtym%2FGmrCW%2Fo8quf3I8758hlg6fH2cAkbu0tGNPxMtUba2WrAtJ5dvap7apRodhT2XqFm7Xc4aA%2BS9P3%2Fa90nZiu0WbMZn4B%2FMREABb7CaRasrLbQJq%2BODQag%3D&_input_charset=utf-8&enable_paymethod=balance%2CcreditCardExpress%2CdebitCardExpress%2CmoneyFund&it_b_pay=1440m&alipay_exterface_invoke_assign_target=mapi_direct_trade.htm&alipay_exterface_invoke_assign_model=cashier&total_fee=15&service=alipay.wap.create.direct.pay.by.user&seller_id=2088311465207164&partner=2088311465207164&alipay_exterface_invoke_assign_sign=_z_r2k6a8_u_lt_ko_fp_q_ywdcji_s_if_y_e_q_tbehn6_g_v_rk_mxwj4k9_k5jb_ns_ftxg%3D%3D&payment_type=1
有哪些人参与
公司老板&财务
前提准备 营业执照、纳税证明和支付宝签约,成为他的合作商户
支付宝审核通过之后,会给你颁发一个唯一的标识符
美团:
2088311465207164
前台(前端、iOS、Android)
让用户选择商品,购买
1、提交订单
让后台记住这个订单
4、当用户选择了支付方式之后,发送请求给后台
让后台返回给我对应平台的一些支付的加密信息
6、浏览器接收到了支付宝那一大堆加密的信息之后,window.location.href = ""
后台
2、在后台数据库中记录该订单信息
id name price pay_status
zni763 汉堡王猪肘子 39.9 1
3、把选择支付方式的页面返回给浏览器,让用户能看到
5、在后台生成有关支付宝的加密信息
https://mclient.alipay.com/home/exterfaceAssign.htm?alipay_exterface_invoke_assign_client,把这一大堆信息返回给浏览器
7、当用户支付成功之后,支付宝服务器,会发送请求给美团后台,这样,后台接收到请求之后,就会把,最刚开始生成的订单的状态,更改为已支付
第八部分
Vue项目打包上线
步骤
1、在项目的根目录,创建一个针对生产环境的配置文件webpack.publish.config.js
2、在我们package.json的scripts标签中,添加一个pub的指令,指令的内容就是webpack --progress --config webpack.publish.config.js
3、在我们的webpack.publish.config.js把开发阶段中的内容拷贝过来,并且进行修改,改成符合生产条件的代码
html-webpack-plugin 说明
开发阶段,在内存中生成一个index.html,并且配合webpack-dev-server一起用,并且会自动导入bundle.js
生成阶段,他会在dist目录生成一个实实在在的index.html并且也会自动加上导入bundle.js的代码
优化的第一步
压缩
压缩bundle.js
使用UglifyJS,但是要是用UglifyJS必须先把我们的代码从es6转成es5
压缩index.html
压缩bundle.js的步骤(1.61M)
1、必须先把我们项目的代码从es6转成es5
使用babel来转换我们的es6代码
参考:https://babeljs.io/docs/setup
1.1、先安装包
cnpm install --save-dev babel-loader babel-core babel-preset-env
1.2、在webpack.publish.config.js中的loaders中添加一个配置
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
1.3 在项目根目录下面创建一个.babelrc的配置文件,在里面设置好预设(preset),能够使用什么样的预设转化百分之多少的es6代码
2、在借助我们webpack内置的UglifyJS来压缩js
参考:https://cn.vuejs.org/v2/guide/deployment.html
注意:因为项目中使用了vue-prview,别忘记在loaders中给它配置一下,否则有问题
{
test: /vue-preview.src.*?js$/,
loader: 'babel-loader'
}
压缩index.html
参考:https://github.com/jantimon/html-webpack-plugin
https://github.com/kangax/html-minifier#options-quick-reference
优化的第二步
拆分bundle.js,把一些内容从bundle.js剥离出来
思考:
1、图片,从bundle.js中剥离出去,放在一个专门的文件夹中
2、把项目中用到的第三方的包从bundle.js中剥离出来,形成单独的js文件
3、把css从bundle.js中剥离出来,提取到一个单独的css文件中
建议:
上面的三个内容的配置的代码比较多,能理解多少就理解多少,不明白的再看看文档,或是看看我的代码,工作中需要可以直接拷贝过去即可。
优化第二步之抽离图片
参考:https://doc.webpack-china.org/loaders/url-loader
可以给url-loader设置一个阀值
loader: 'url-loader?limit=4000&name=images/[name]-[hash:5].[ext]'
优化第二步之抽离第三方包
参考:https://doc.webpack-china.org/plugins/commons-chunk-plugin/
步骤:
1、更改入口文件
以对象的形式配置,属性名称(打包出来的js文件名称):值(第三方包的名称/自己项目源代码打包的入口main.js)
2、更改输出文件
output: { //项目打包之后的输出文件
path: path.join(__dirname,'dist'),
filename: 'js/[name].js'
}
3、在plugins中增加一个插件的配置
new webpack.optimize.CommonsChunkPlugin({name:["vuePreview","moment","vueResource","quanjiatong","mintUi"],minChunks: Infinity})
优化第二步之抽离css
参考:https://doc.webpack-china.org/plugins/extract-text-webpack-plugin/
步骤:
1、安装包
cnpm i extract-text-webpack-plugin --save-dev
2、导入
const ExtractTextPlugin = require("extract-text-webpack-plugin")
3、更改css-loader的配置
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
4、在plugins中新增一个配置即可
new ExtractTextPlugin("css/styles.css")
额外补充,打包之前干掉dist目录
clean-webpack-plugin
使用:https://github.com/johnagan/clean-webpack-plugin
浏览器出现缓存的原因
请求方式为GET
url没有变化
微信小程序
运行在`微信`里面的一种小程序
原生的App
基于微信平台
步骤:
1、注册&填写信息
2、开发
3、发布
开发者工具
https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html
App.json
https://mp.weixin.qq.com/debug/wxadoc/dev/framework/config.html
React-Native