第一个Vue前台项目
商品上架 gitee:
day-1
-
vue-cli 脚手架初始化项目。
-
node_modules文件夹:项目依赖
-
pubic文件夹:静态资源(此文件夹中的静态资源,webpack打包的时候,会打包到dist)
- assets:多个组件公用的静态资源(webpack打包的时候,会打包到js)
- commonents:放置的是非路由组件(全局组件)
- App.vue:唯一的根组件
1.package.json:
"serve": "vue-cli-service serve --open"(自动打开浏览器)
2.项目路由分析
前端路由:KV键值对
key:URL
value: 响应的路由组件
注意:项目上中下接口
路由组件:
Home首页路由组件、Search路由组件、login登录路由、Reg注册路由
(放在pages|views文件夹中)
非路由组件:
Header(首页、搜索页)、Footer(在首页、搜索页)
配置路由:
项目中配置的路由放在router文件夹
3 .注册完路由,不管是路由组件,还是非路由组件,身上都有 $route 和 router 属性
$route:一般是获取路由信息(路径、query、params…..)
$router:一般进行编程式导航进行路由跳转 (push|replace)
路由的跳转:
1.声明式导航:router-link,可以进行路由跳转 (必须要有to属性)
2.编程式导航:push|replace,可以进行路由跳转(不仅可以做跳转,还可以做其他的业务逻辑) ($router.push|replace)
4.footer组件的现实与隐藏(v-if|v-show)
Footer组件:在Home、Search是显示的
Footer组件:在Login、Register是隐藏的
5.可以根据$route.path获取路由信息,通过路由路径判断footer显示与隐藏
6.可以给路由添加元信息【meta】,更好的实现组件的跳转和显示隐藏
路由传参:
params参数:不属于路径中的一部分,需要注意,配置路由的时候,需要占位
query参数:属于路径中的一部分,类似于ajax中的queryString /home?k=v&kv=, 不需要占位
面试题:路由传递参数(对象写法)path是否可以结合params参数一起使用?
this.$router.push({
// 在router/index 给路由起名字
name:'search',
params: {
keyword: this.keyword
},
query: {
k: this.keyword.toUpperCase()
}
})
面试题:如何指定params参数可传可不传?
//如何指定params参数传递或者不传递:可以在配置路由的时候,在占位(:keyword?)后面加【?】
面试题:params可传可不传,但是如果传递空串,如何解决?
params:{keyword:''||undefined}
面试题:路由组件能不能传递props数据?
// 路由组件能不能传递props数据?
// 布尔值写法:params
// props:true
// 对象写法:额外的给路由组件传递一些props
// props:{a:1}
// 函数写法:可以把params参数、query参数,通过props传递给路由组件
props:($route) => {
return {keyword:$route.params,k:$route.query.k}
}
编程式路由跳转,多次执行会抛出NavigationDuplicated的错误
this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`,() =>{}, () =>{})
解决:通过给push方法传递相应的成功、失败的回调函数,可以捕获到当前的错误
// 这种写法治标不治本,将来在别的组件当中push|replace,编程式导航还是有类似的错误
this:当前组件实例(search)
this.$router属性:当前的这个属性,属性值VueRouter类的一个实例,当在入口文件注册路由的时候,给组件实例添加$router| $route 属性
push:VUeRouter类的一个实例
function VueRouter(){}
// 原型对象的方法
VueRouter.prototype.push = function(){
// 函数的上下文是VueRouter类的一个实例
}
let $router = new VueRouter();
$router.push(xxx);
day-2
Home模块组件拆分
1.先把静态页面完成
2.拆分出静态组件
3.获取服务器的数据进行展示
4.动态业务
三级联动组件
1.由于三级联动,在Home、Search、Detail使用,所以注册为全局组件
好处:只需要注册一次,就可以在项目任何地方使用
完成其余静态组件
1.Html+css+img
2.axios二次封装
(有XMLHttpRequest、fetch、JQ、axios)
3.安装axios
4.baseURL: ‘/api’(基础路径)
5.配置axios
6.接口统一管理
项目很小:完全可以在组件的生命周期函数中发请求
项目很大:需要封装接口
1.封装api/index.js
2.解决跨域问题(JSonp、cros、代理)
3.nprogress进度条
start:进度条开始
done:进度条结束
vuex状态管理库
1.vuex:是插件,状态管理库,集中式管理项目中组件公用的数据(项目大,组件多) .登录与注册
assets文件夹–放置全部组件公用的静态资源
在样式中也可以使用@符号 :~@:src
2.登录业务
- 注册—通过数据库存储用户信息
- 登录—-登录成功,后台为了区分,服务器下发token,
- 前台持久化存储token,【带着token找服务器要用户信息进行展示】
vuex仓库存储,不是持久化的
3.交易页面完成(商品清单) 动态展示服务器数据完成
4.提交订单
- 先把支付静态组件搞定
- 提交订单:向服务器发请求【吧支付的信息给服务器】
- 不用vuex了,在组件用
5.获取支付信息(不再使用vuex)
- 别在生命周期函数中使用async
- elementUI+按需引入
组件库:react(Vue):antd(PC)
antd-mobile[移动端]
Vue:ElementUI(PC) vant(移动端)
表单验证
vee-validate
路由懒加载
打包
map:准确输出哪一行有错
设置安全组
利用xshell登录服务器
linux: / 更目录
cd 跳转目录 ls 显示目录
mkdir:创建目录
xftp 7:上传文件到云服务器
pwd:查看绝对路径
nginx:反向代理
在 xshell 的 etc可以配置nginx
如果没有nginx yum install nginx
安装完成后,在nginx目录下,在nginx.conf中编辑
vim nginx.conf :编辑,主要添加
按住:insert编辑 esc:退出 wq:保存
组件通信
-
第一种:props 适用于的场景:父子组件 注意事项: 如果父组件给子组件传递数据(函数):本质其实是子组件给父组件传递数据 如果父组件给子组件传递的数据(非函数):本质就是父组件给子组件传递数据
书写方式:3种
[‘todos’],{type:Array},{type:Array,default:[]}
小提示:路由的props
书写形式:布尔值、对象、函数
-
第二种:自定义事件
适用于场景:子给父传
$on $emit -
第三种:全局事件总线$bus
Vue.prototype.$bus = this
-
第四种:pubsub-js:React种使用多
-
第五种:Vuex
-
第六种:插槽(父子组件)(一般是结构)
默认插槽、具名插槽、作用域插槽
事件:
- 系统事件:click、鼠标系列
- 自定义事件
// 原生DOM-可以绑定系统事件 // 组件标签--可以绑定系统事件(需要加修饰符.native)(其实是给子组件的根节点绑定了事件---利用了事件的委派) ========================= 1.给原生DOM绑定自定义事件没有意义,因为没有办法发出$emit函数
v-model(组件通信方式的一种)
结合表单元素(文本框、复选、单选….)
作用:收集表单数据
// 原生DOM有oninput事件(经常结合表单元素使用)
vue2:可以通过value和input事件实现v-model功能(:value="msg" @input="msg=$event.target.value")
//==========================================
// v-model 实现父子组件通信
// 父组件 :value:是props @input:是自定义事件(不是原生DOM的事件)
//:value="msg" @input="msg =$event":可以简化成 v-model="msg"
<son :value="msg" @input="msg =$event"></son>
// 子组件 :value:是动态属性 @input:是原生DOM绑定的事件
<input :value="value" @input="$emit('input',$event.target.value)">
props:['value']
v-model原理: value和input事件实现的,还可以实现父子组件数据同步
sync属性修饰符
:money:sync:代表父组件给子组件传递props[‘money’],且给当前子组件绑定一个自定义事件(update:“当前属性的名字(money)”)
$attrs|listeners
$attrs :属于组件的一个属性,可以获取到父组件传递过来的props数据 (v-bind:‘’¥attrs‘’)
$listeners:也是组件的一个属性,累获取到父组件给子组件传递的自定义事件 (v-on=“¥listeners”)
$children|parent
ref可以获取DOM节点,也可以获取子组件标签(操作子组件的数据方法)this.$refs.名字.xxx = xxxx
$chidlren:可以获取到当前组件种,所有的子组件(返回的是一个 数组)
this.$children.forEach(item=>{
item.money -= 200
})
$parent属性:可以获取某一个组件的父组件
this.$parent.money += 200
混入 mixin
项目中出现很多结构类似功能,想到组件复用
项目中出现很多组件JS业务逻辑相似,想到mixin
// myMixin.js
export default {
methods: {
xi() {}
},
mounted() {
....
},
computed:{
.....
}
}
// 需要的组件中
import myMixin from myMixin.js
mixins:[myMixin]
插槽
插槽:实现父子组件通信—(结构的通信)
默认插槽、具名插槽、作用域插槽
作用域插槽:子组件的数据来源于父组件,子组件是决定不了自身结构与外观
// ==========子
<li v-for="(item,index)in todos">
// 作用域插槽
<slot :todo =“item">回传数据给父组件</slot>
</li>
props:{
todos:Array
}
// ==========父
<List :todos="todos">
<template slot-scope="todox">
<span :style="{color:todox.todo.xxx}">
</template>
</List>
todos:[{},{},{},{}]
=================
1.子组件的数据是父组件给的
2.子组件拿到数据后,用插槽回传给父组件
\