VUE最后第一天
01-反馈
姓名 意见或建议
*** 又是一年端午节了,好激动,有家不能回,孩儿立志出乡关,学不成名誓不还!!周老湿给咱再花丶时间捋一下项目需求分析....到打包上线呐
-
city github github.com/iceyangcc/p…
-
需求分析:产品经理 需求文档
-
原型图: UI 产品经理
-
设计稿:UI
-
静态页面:前端
-
后台工作:数据库设计 接口开发 接口文档
-
前端开发 和后台的交互 和用户的交互
-
测试:测试工程师
-
bug: 修改
-
准上线环境
-
上线
-
修改bug
-
项目完成
-
打包 优化
-
组件的传值
02-vuex基础-介绍
当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏。
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
- Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。
- 这需要对短期和长期效益进行权衡。
- 如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。
- 确实是如此——如果您的应用够简单,您最好不要使用 Vuex。
总结:项目复杂使用vuex可以简化逻辑,但是如果项目简单使用vuex则会增加逻辑。
结论:
- Actions 发送请求 响应成功 把数据提交给 Mutations
- Mutations 接收到数据后 去更新State中的数据
- State管理的数据是响应式的 当数据改变时渲染视图
03-vuex基础-初始化
初始化:
-
第一步:npm i vuex
-
第二步:import vuex from 'vuex'
-
第三步:Vue.use(vuex)
-
第四步:const store = new Vuex.Store()
-
第五步:在根组件 配置 store 选项指向 store实例对象
import Vue from 'vue' import Vuex from 'vuex' Vue.use(vuex) const store = new Vuex.Store({}) new Vue({ el: '#app', store: })
04-vuex基础-state
作用申明数据,提供给其他组件使用,在组件中computed去使用
在实例化store对象申明:
new Vuex.Store({
state: {
count: 100
}
})
在组件中使用:
<template>
<!-- 直接使用 -->
<p>{{$store.state.count}}</p>
<!-- 通过计算数据使用 -->
<p>{{count}}</p>
</template>
<script>
export default {
computed: {
count () {
return $store.state.count
}
}
}
</script>
05-vuex基础-mapState
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。
我们可以使用 mapState 辅助函数帮助我们生成计算属性
把state中的数据映射成计算属性
对象写法:
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
数组写法:
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
展开符写法:
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
...mapState(['count'])
}
06-vuex基础-mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件。
在实例化store对象申明:mutation 必须同步执行
const store = new Vuex.Store({
state: {
count: 100
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
在组件中使用:
-
默认提交
this.$store.commit('increment')
-
提交传参
// ... mutations: { increment (state, payload) { state.count += payload.amount } }
this.$store.commit('increment', { amount: 10 })
07-vuex基础-mapMutations
-
这是vuex提供的 辅助函数 在methods映射函数的
import { mapMutations } from 'vuex'
export default { // ... methods: { ...mapMutations([ 'increment' // 将
this.increment()映射为this.$store.commit('increment')]), ...mapMutations({ add: 'increment' // 将this.add()映射为this.$store.commit('increment')}) } }
08-vuex基础-actions
Action 类似于 mutation,不同在于:
- Action 提交给 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
在实例化store对象申明:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
setTimeout(()=>{
// 数据获取成功
context.commit('increment')
},1000)
}
}
})
在组件中调用:也可以提交参数。
this.$store.dispatch('increment')
09-vuex基础-mapActions
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
10-vuex案例-豆瓣接口说明
豆瓣的接口有请求次数限制,普通用户一分钟内10次,在平台注册的用户40次。
豆瓣的图片前端页面无法直接访问,需要使用代理:images.weserv.nl?url='图片地址'
- 接口地址 支持jsonp (包名jsonp) 不支持cors
11-vuex案例-初始化
- vue init webpack-simple vuex-example
- cd vuex-example
- npm i
- npm run dev
12-vuex案例-路由和组件骨架
-
四个大组件
- 正在热映 /hot
- 即将上映 /movie
- top250 /top
- 电影详情 /item
-
头部组件 my-header 底部组件 my-footer
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter)
import Hot from '../components/Hot' import Movie from '../components/Movie' import Top from '../components/Top' import Item from '../components/Item'
const router = new VueRouter({ routes: [ {path:'/', redirect: '/hot'}, {path:'/hot', component: Hot}, {path:'/movie', component: Movie}, {path:'/top', component: Top}, {path:'/item', component: Item} ] })
export default router
13-vuex案例-组件布局
14-vuex案例-电影列表
- 正在热映 (默认选中)
- 即将上映
- top250
第一步:
在 store 申明了数据
state: {
// 标题
title: null,
// 电影列表
movieList: null
},
第二步:
在组件中映射数据到计算属性
computed: {
...mapState(['movieList'])
},
第三步:
在 store 去定义actions的请求函数
actions: {
getHot (context) {
// context 当前的 vuex 实例
// 通过 jsonp 去获取数据
jsonp(baseURL + '/v2/movie/in_theaters', (err, res) => {
if (err) return alert('获取数据失败')
// 注意:不能直接修改 state 而是通过commit去提交修改
context.commit('setData', res)
})
},
}
第四步:
在store 去定义 mutaions 去修改数据
mutations: {
setData (state, payload) {
state.title = payload.title
state.movieList = payload.subjects
}
},
第五步:
去组件渲染完毕的时候去调用actions函数,看页面是否有更新
methods: {
...mapActions(['getMovie'])
}
mounted () {
this.getMovie()
},
<ul v-if="movieList" class="list">
<li v-for="item in movieList" :key="id">
<img :src="'https://images.weserv.nl?url='+item.images.small" alt="">
<div class="info">
<p style="font-size: 12px;font-weight: bold">{{item.title}}</p>
<p style="font-size: 12px;color: #999">豆瓣评分:{{item.rating.average}}</p>
<p>
<span v-for="(tag,i) in item.genres" :key="i" class="tag">{{tag}}</span>
</p>
</div>
</li>
</ul>
<div v-else style="margin: 20px">正在加载数据...</div>
15-vuex案例-电影详情
- 注意:/item/:id $route.params.id
- g根据ID去调用actions中的请求函数
16-vuex案例-网络延时优化
- 组件切换动画
- 使用transition的标签包裹
- 组件重置数据
-
created
-
清空 movieList 的数据
-
使用mutations的函数去修改
clearData (state) { state.title = null state.movieList = null state.item = null }
-
调用:
created () {
this.clearData()
},
17-webpack-介绍
- 中文官网:www.webpackjs.com
前言:很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(less,sass等),并将其转换和打包为合适的格式供浏览器使用。
18-webpack-安装
对于大多数项目,我们建议本地安装。
新建一个项目:在该项目下安装
npm install --save-dev webpack
npm install --save-dev webpack-cli
19-webpack-打包js
-
新建一个 src 目录
- main.js 文件导入 calc.js 文件
-
创建webpack.config.js文件在项目根目录
-
配置入口文件和输出文件
const path = require('path');
module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' } };
-
新建一个 index.html 文件来使用打包好的bundle.js
-
验证打包的结果
20-webpack-打包css
npm install --save-dev style-loader css-loader
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: [
+ 'style-loader',
+ 'css-loader'
+ ]
+ }
+ ]
+ }
};
21-webpack-打包图片
npm install --save-dev file-loader
onst path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
+ {
+ test: /\.(png|svg|jpg|gif)$/,
+ use: [
+ 'file-loader'
+ ]
+ }
]
}
};
22-webpack-打包字体文件
+ {
+ test: /\.(woff|woff2|eot|ttf|otf)$/,
+ use: [
+ 'file-loader'
+ ]
+ }
23-webpack-生成.html&清空dist
npm install --save-dev html-webpack-plugin
+ plugins: [
+ new HtmlWebpackPlugin({
+ title: 'Output Management'
+ })
+ ],
如果你想要了解更多 HtmlWebpackPlugin 插件提供的全部功能和选项,那么你就应该多多熟悉 HtmlWebpackPlugin 仓库。
+ plugins: [
+ new HtmlWebpackPlugin({
+ template: 'index.html'
+ })
+ ],
npm install clean-webpack-plugin --save-dev
+ const CleanWebpackPlugin = require('clean-webpack-plugin');
plugins: [
+ new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
24-sourceMap
为了更容易地追踪错误和警告,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。如果一个错误来自于 b.js,source map 就会明确的告诉你。
+ devtool: 'inline-source-map',
plugins:
25-webpack-dev-server
webpack-dev-server 为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)
npm install --save-dev webpack-dev-server
devtool: 'inline-source-map',
+ devServer: {
+ contentBase: './dist'
+ },
package.json
"scripts": {
+ "start": "webpack-dev-server --open",
执行:
npm start