vue全站式笔记
电商项目
流程:
- 登陆—产品首页—产品站—产品详情
- 购物车—订单确认—订单支付—订单列表
业务员开发流程:
- 需求整理—熟悉ui设计稿—接口规范对接—搭建前端架构—微信/支付—线上部署
核心技术:
Node环境安装
//安装后查看版本
$ node -v
Git安装和配置
进行开发环境配置,必要时配置环境变量。掌握基本命令与克隆方式即可。在项目中有时候需要添加一个.gitignore
文件来避免一些文件上传到远程仓库。
VueCli安装
$ npm install -g @vue/cli //全局安装
$ vue --version //检查版本
$ vue create myaop //可以创建vue项目了
安装依赖
$ npm install --save-dev vue-router
$ npm install axios
$ npm install --save-dev vuex
Vue DevTools
//这是一个辅助开发的工具,可用可不用
//1. 进入网站进行git克隆或下载
https://github.com/vuejs/vue-devtools
//2. 进入项目进行安装
$ npm i
//3. 进行编译生成
$ npm run build
//4. 进入扩展程序页面-加载已解压的扩展程序-导入打包后的shells/chrome
前端跨域
项目结构
- 小文件可以放在src目录下的assets文件夹下,大文件放在根目录的public下,优化请求体验。
- 项目基本结构:api、util、components、storage、store、router.js、pages:
页面home.vue
——公共组件:NavHeader|NavFooter——承载index.vue|detail.vue|product.vue(包含组件ProductParam)
页面order.vue
——公共组件:OrderHeader|NavFooter——承载orderList.vue|orderConfirm.vue|orderPay.vue|alipay.vue
页面cart.vue
——公共组件:OrderHeader|NavFooter
页面login.vue
安装插件
npm install vue-lazyload element-ui node-sass sass-loader vue-awesome-swiper vue-axios vue-cookie --save-dev //vue-axios方便我们直接用this使用,不用导入
封装路由
cookie,localStorage和sessionStorage三者区别
- 存储大小:Cookie4K、Storage5M
- 有效期:Cookie拥有有效期;localStorage永久存储;sessionStorage在浏览器关闭后删除
- Cookie会发送到服务器端,存储在内存中,Storage只存储在浏览器端
- 路径:Cookie有路径限制,Storage只存储在域名下
- API:Cookie没有清晰的API,Storage有清晰对应的API
封装Storage
- Storage本身有API,但是只是简单的key/value形式
- Storage只存储字符串,需要人工转换成json对象
- Storage只能一次性清空,不能单个清空
npm i vue-cookie --save-dev
this.$cookie.set('userId','',{expirels:'-1'})//清除
this.$cookie.set('userId',res.id,{expirels:Session})//与后台同步
接口错误拦截
统一报错;未登录统一拦截;请求值、返回值统一处理
假设这是接口返回数据的规范。成功时的status是0,没有登录的status是10
{
"status":0,
"data":{},
"msg":''
}
//main.js
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios,axios)
axios.interceptors.response.use(function (response) {
let res=response.data
let path=location.hash
if(res.status==0){
return res.data
}else if(res.status==10){
if(path!='#/index'){
//main已经用了路由跳转,而路由是挂在在vue实例里面的
//而在这里是取不到router的,所以用下面的方法跳转到登录页面
window.location.href='/#/login';
return Promise.reject(error);
}
}else{
alert(res.msg)
}
}, function (error) {
//在请求错误时
return Promise.reject(error);
});
接口基础配置
//main.js
//在接口代理的情况下,在写url的时候就可以省去前面的/api了
axios.defaults.baseURL = '/api';
axios.defaults.timeout: 8000;
//在非接口代理的情况下,要把baseURL写完整
接口环境设置
-
在非接口代理的情况下,在每种环境下配置请求的baseURL:
-
在代理的情况下,只能在vue.config.js手动更改target
Mock设置
Component
Vuex
在scr下新建store,里面:action.js、index.js、mutations.js
功能
吸顶
data(){
return {
isFixed:false
}
},
mounted(){
window.addEventListener('scroll',this.initHeight)
},
methods:{
initHeight(){
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
this.isFixed = scrollTop > 152? true:false;
}
},
destroyed(){
//切换页面时销毁 false表示冒泡
window.removeEventListener('scroll',this.initHeight,false)
}
动态绑定样式,找到你想要吸顶的元素
:class="{'is_fixed':isFixed}"
添加样式
.is_fixed{
position:fixed;
top:0;
width:100%
}
视频
动态跳转
假设你通过标签跳转页面
<a v-bind:href="'/#/product/'+item.id" target="_blank">
传id获取数据
data(){
return{
product:{}//商品信息
}
}
mounted(){
this.getProductInfo()
}
methods:{
getProductInfo(){
let id=this.$router.params.id;
this.axios.get(`/product/${id}`),then(res=>{
this.product=res
})
}
}
子组件绑定父组件的值
//父级绑定并传递属性
<product-params :title=product.title></product-params>
//子组件接收并渲染
<div>{{title}}</div>
<script>
export default{
//...
props:{
title:String
}
}
</script>
router编程式导航
@click="buy"
methods:{
buy(){
let id=this.$router.params.id;
this.$router.push(`/detail/${id}`)
}
}
浮动布局通用
.fl{
float: left;
}
.fr{
float: right;
}
.clearfix:before,.clearfix:after{
content:' ';
display:table;
}
.clearfix:after{
clear: both;
}
切换改变样式
<div :class="{'checked':version==1}" @click="version=1"></div>
<div :class="{'checked':version==1}" @click="version=2"></div>
<script>
export default{
data(){
return{
version:1
}
}
}
</script>
<style>
.checked{
//...
}
</style>
图片懒加载
npm install vue-lazyload --save-dev
import VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad,{
loading:'/imgs/loading-svg/loading-bars.svg'
})
<img v-lazy="'url'"/>
判断哪里来
在登录页面做参数跳转
this.$router.push('./index')
//第一种方式
this.$router.push('./index?from=login')
//第二种方式
this.$router.push({
path:'/index',
query:{
from'login
}
})
//第三种方式
this.$router.push({
name:'index',//路由名称
params:{
from'login
}
})
//第三种方式时
let params =this.$router.params
if(params&¶ms.from=='login'){
this.get()
}
elementUI
npm i element-ui --save-dev
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
按需加载
npm install babel-plugin-component -D
//babel.config.js (与.babelrc差不多)
module.exports={
{
"presets": [
'@vue/cli-plugin-babel/preset'
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
],
}
按需引入:但还是会加载全部
import { Button, Select } from 'element-ui';
Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
/* 或写为
* Vue.use(Button)
* Vue.use(Select)
*/
vuecli配置
//vue.config.js
publicPath:'/app'
outputDir:'dist'//输出文件名称