购物车案例续
补充:
限制文字的行数带...
// 限制显示两行名字
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
初始化新项目, 清空不要的东西, 下载bootstrap库, 下载less模块
vue create shopcar
yarn add bootstrap@3.4.1 下载bootstrap库
yarn add less less-loader 下载less模块
总结:
props: [] - 只能声明变量和接收, 不能类型校验
props: {} - 声明变量和校验类型规则 - 外部传入值不对则报错
获取数据
// 创建utils/request.js
// 改造 axios 添加基地址后重新导出
import axios from 'axios'
axios.defaults.baseURL = 'https://www.escook.cn'
export default axios
// 创建api/cart.js
// 引入经过修改的 axios
import request from '@/utils/request'
// 封装接口函数, 导出供页面使用
// 获取购物车数据 (具名导出, 跟其他可能要加入的函数进行区分)
export function getCart() {
return request({
// 会自动拼接上 baseURL 配置
url: '/api/cart'
})
}
渲染商品
<template>
<div>
<CartHeader bg="#1d7bff" title="我的购物车"/>
<div class="list">
<ProdItem
v-for="item in list"
:key="item.id"
:data="item"
/>
</div>
<div class="footer">
<input type="checkbox" name="" id="">
<div class="total">合计¥1151.8</div>
<button>结算</button>
</div>
</div>
</template>
单一商品选中
主要是复习了 label 标签的使用
<input v-model="data.goods_state" class="checkbox" type="checkbox" name="" :id="data.id" />
<label :for="data.id">
<img
:src="data.goods_img"
alt=""
/>
</label>
单一商品数量
输入框已经绑定好,
需要做修改的是加减按钮
全选
被动
export default {
props: ['list'],
computed: {
isAll() {
return this.list.every(item=>item.goods_state)
}
}
};
主动
export default {
props: ['list'],
computed: {
isAll: {
get() {
return this.list.every(item=>item.goods_state)
},
set(isChecked) {
// 这里可以接收到全选的布尔值,
// 将所有商品状态改为跟全选状态一样即可
this.list.forEach(element => {
element.goods_state = isChecked
});
}
}
}
};
总数量和总价格
totalPrice() {
// 总价=列表中所有被勾选的商品的单价乘以数量累加起来
let res = 0
this.list.forEach(element => {
if (element.goods_state) {
res += element.goods_count * element.goods_price
}
});
return res
},
totalCount() {
let res = 0
this.list.forEach(element => {
if (element.goods_state) {
res += element.goods_count
}
});
return res
}
动态组件
动态组件是在同一个挂载点, 可以切换显示不同组件
使用动态组件:vue内置的component组件, 配合is属性
如何切换:改变is属性的值, 为要显示的组件名即可
方法:
- 准备被切换的 - UserName.vue / UserInfo.vue 2个组件
- 引入到APP.vue注册
- 准备变量来承载要显示的"组件名"
- 设置挂载点, 使用is属性来设置要显示哪个组件
-
点击按钮 – 修改comName变量里的"组件名"
-
在App.vue - 引入UserName.vue并使用显示
总结: vue内置component组件, 配合is属性, 设置要显示的组件名字
// 目标: 动态组件 - 切换组件显示
// 场景: 同一个挂载点要切换 不同组件 显示
// 1. 创建要被切换的组件 - 标签+样式
// 2. 引入到要展示的vue文件内, 注册
// 3. 变量-承载要显示的组件名
// 4. 设置挂载点<component :is="变量"></component>
// 5. 点击按钮-切换comName的值为要显示的组件名
<template>
<div>
<button @click="componentName = 'UserInfo'">个人信息</button>
<button @click="componentName = 'UserName'">账号登录</button>
<!-- vue内置标签 component 是动态组件挂载点, 会根据绑定的 is 属性显示名字对应的组件 -->
<component :is="componentName" />
</div>
</template>
<script>
import UserInfo from '@/components/UserInfo.vue'
import UserName from '@/components/UserName.vue'
export default {
data() {
return {
componentName: 'UserInfo'
}
},
components: {
UserInfo,
UserName
}
}
</script>
<style>
</style>
组件缓存
优点:不会频繁的创建和销毁组件, 页面更快呈现
使用Vue内置的keep-alive组件, 可以让包裹的组件保存在内存中不被销毁
1: 可以先给UserName.vue和UserInfo.vue 注册created和destroyed生命周期事件, 观察创建和销毁过程
2: 使用keep-alive内置的vue组件, 让动态组件缓存而不是销毁
语法:
Vue内置的keep-alive组件 包起来要频繁切换的组件
初步使用
<keep-alive>
<component :is="componentName" />
</keep-alive>
拓展生命周期
- activated - 激活
- deactivated - 失去激活状态
总结: keep-alive可以提高组件的性能, 内部包裹的标签不会被销毁和重新创建, 触发激活和非激活的生命周期方法
activated() {
console.log('缓存的组件被激活(显示)');
},
deactivated() {
console.log('缓存的组件被隐藏');
}
插槽使用
可以通过 slot 标签, 让组件内可以接收不同的标签结构显示
vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽
给组件插入什么标签, 组件就会显示什么标签
基本操作
<template>
<div class="topBar">
<div class="left"></div>
<div class="right">
<!-- 插槽占位标签 -->
<slot/>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
.topBar {
display: flex;
justify-content: space-between;
border: 2px solid salmon;
}
</style>
<template>
<div>
<!-- 员工页使用, 就要带导入员工新建员工按钮 -->
<TopBar>
<button>新增员工</button>
<button>导入员工</button>
</TopBar>
<!-- 工资页面使用需要一个报表按钮 -->
<TopBar>
<button>报表</button>
</TopBar>
</div>
</template>
<script>
import TopBar from '@/components/TopBar.vue'
export default {
components: {
TopBar
}
}
</script>
<style>
</style>
默认显示内容设定
目标: 如果外面不给传, 想给个默认显示内容
口诀: 夹着内容默认显示内容, 如果不给插槽slot传东西, 则使用夹着的内容在原地显示
<template>
<div class="topBar">
<div class="left"></div>
<div class="right">
<!-- 插槽占位标签 -->
<slot>
<!-- 如果外面没有传入, 默认显示的内容 -->
欢迎来到我的页面
</slot>
</div>
</div>
</template>
具名插槽
简化语法:v-slot: 可以被简化成#
语法:
- slot使用name属性区分名字
-
template配合v-slot:名字来分发对应标签
当组件内多处不确定的标签时:
可以使用slot占位, 给name属性起名字来区分
template配合v-slot:name分发要替换的标签
<div class="left">
<slot name="left"/>
</div>
<div class="right">
<!-- 插槽占位标签 -->
<slot name="right">
<!-- 如果外面没有传入, 默认显示的内容 -->
欢迎来到我的页面
</slot>
</div>
<TopBar>
<!-- v-slot: 可以被简化成# -->
<template #left>
一共 666 位员工
</template>
<template #right>
<button>新增员工</button>
<button>导入员工</button>
</template>
</TopBar>
<!-- 工资页面使用需要一个报表按钮 -->
<TopBar>
<template v-slot:left>
5月工资报表
</template>
<template v-slot:right>
<button>报表</button>
</template>
</TopBar>
作用域插槽
子组件
<slot :row="monthList" name="left">
{{monthList.first}} 工资报表
</slot>
父组件
<template v-slot:left="scope">
{{scope.row.second}} 工资报表
</template>
作用域插槽具体使用场景
封装一个灵活的表格组件
自定义指令的使用方式
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。 v-xxx
html+css的复用的主要形式是组件
你需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令
<template>
<div>
<!-- 使用自定义指令, 跟普通vue指令一样, 请千万注意,要加上 v- 前缀 -->
<input type="text">
<br>
<input type="text">
<br>
<input v-autofocus type="text">
</div>
</template>
<script>
export default {
// 局部指令注册
// directives: {
// 指令名字符串: {
// 配置对象
// 可以指定使用这个指令的元素, 在不同生命周期执行的函数
// 在这些钩子函数的形参中, 默认第一个可以获取元素本身, 第二个可以用来传参
// inserted,
// update
// }
// }
directives: {
autofocus: {
inserted(el) {
console.log(el, '自动聚焦');
el.focus()
}
}
}
}
</script>
<style>
</style>