一、使用 Vue 脚手架
1.1 初始化脚手架
1.1.1 说明
1.Vue脚手架是 Vue 官方提供的标准化开发工具(开发平台)。
2.最新版本是 4.x
3.文档 Vue CLI
1.1.2 具体步骤
1.全局安装: 全局安装 @vue/cli
命令: npm install -g @vue/cli
2.切换到创建的项目的目录,然后使用命令创建项目:
vue create xxx
3.启动项目
npm run serve
备注:
1.如果出现下载缓慢配置 npm 淘宝镜像: npm config set registry https://registry.npm.taobao.org
2.Vue脚手架隐藏了所有的 webpack 相关的配置,若想查看具体的webpack配置,请执行: vue inspect > output.js
文档: 配置参考 | Vue CLI
备注:
1.如出现下载缓慢请配置 npm 淘宝镜像:
npm config set registry https://registry.npm.taobao.org
2.Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpack 配置,请执行: vue inspect > output.js
1.1.3 模板项目的结构
脚手架文件结构:
|—— node_module
|—— public
| |—— favicon.ico: 页签图标
| |—— index.html: 主页面
|—— src
| |—— assets: 存放静态页面
| | |—— logo.png
| |—— component: 存放组件
| | |—— HelloWorld.vue
| |—— App.vue: 汇总所有组件
| |—— main.js: 入口文件
|—— .gitignore: git版本管制忽略的配置
|—— babel.config.js: babel的配置文件
|—— package.json: 应用包配置文件
|—— README.md: 应用描述文件
|—— package-lock.json: 包版本控制文件
关于不同版本的Vue
vue.js 与 vue.runtime.xxx.js 的区别:
(1)vue.js 是完整版的 Vue,包含:核心功能 + 模板解析器。
(2)vue.runtime.xxx.js 是运行版的Vue,只包含:核心功能;没有模板解析器。
因为 vue.runtime.xxx.js 没有模板解析器,所以不能使用 template 配置项,需要使用 render 函数接收到的 createElement 函数去指定具体内容。
vue.config.js 配置文件
手架进行个性化定制:详情见: https://cli.vuejs.org/zh
1.1.4 消除警告
1.关闭vue生产提示
main.js 中 Vue.config.productionTip = false;
2.安装 vue 开发者工具
1.2 ref 属性
1.被用来给元素或子组件注册引用信息(id的替代者)。
2.应用在 html 标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)。
3.使用方式:
打标识:
<h1 ref="xxx">......</h1> 或 <School ref="xxx"></School>
获取:
this.$refs.xxx
1.3 配置项 props
1.3.1 功能
让组件接收外部传过来的数据。
1.3.2 传递数据
<Demo name="xxx" />
1.3.3 接收数据
第一种方式(只接收):
props: ['name']
第二种方式(限制类型):
props: {
name: Number
}
第三种方式(限制类型、限制必要性、指定默认值):
props: {
name: {
type: String, // 类型
required: true, // 必要性
default: 'lx' // 默认值
}
}
1.3.4 备注
props 是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制 props 的内容到 data 中一份,然后修改 data 中的数据。
1.4 mixin (混入(合))
1.4.1 功能
可以把多个组件共用的配置提取成一个混入对象。
1.4.2 使用方式
第一步定义混合:例如
{
data(){},
methods:{...},
...
}
第二步使用混入:例如
(1) 全局混入:
Vue.mixin(xxx);
(2) 局部混入:
mixins: ['xxx'];
1.5 插件
1.5.1 功能
用于增强 Vue。
1.5.2 本质
包含 install 方法的一个对象,install 的第一个参数是 Vue,第二个以后的参数是插件使用者传递的数据。
1.5.3 定义插件
对象.install = function(Vue, options) {
// 1. 添加全局过滤器
Vue.filter(...);
// 2. 添加全局指令
Vue.directive(...);
// 3. 配置全局混入(合)
Vue.mixin(...);
// 4.添加实例方法
Vue.prototype.$myMethod = function () {...};
Vue.prototype.$myProperty = xxxx;
}
1.5.4 使用插件
Vue.use();
1.6 scoped 样式
1.6.1 作用
让样式在局部生效,防止冲突。
1.6.2 写法
<style scoped>
</style>
1.7 webStorage
1.7.1 存储内容一般支持5MB左右(不同浏览器可能还不一样)
1.7.2 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。
1.7.3 相关API
1.
xxxxxStorage.setItem('key', 'value');
该方法接收一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
2.
xxxxxStorage.getItem('person');
该方法接收一个键名作为参数,返回键名对应的值。
3.
xxxxx.Storage.removeItem('key');
该方法接收一个键名作为参数,并把该键名从存储中删除。
4.
xxxxxStorage.clear();
该方法会清空存储中的所有数据。
1.7.4 备注
1.SessionStorage 存储的内容会随着浏览器窗口关闭而消失。
2.LocalStorage 存储的内容,需要手动清除才会消失。
3.xxxxxStorage.getItem(xxx) 如果 xxx 对应的 value 获取不到,那么 getItem的返回值是 null。
4.JSON.parse(null) 的结果是 null。
1.8 组件的自定义事件
1.8.1 一种组件间通信的方式,适用于: 子组件 ===> 父组件
1.8.2 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)
1.8.3 绑定自定义事件
1.第一种方式,在父组件中:
<Demo @send="test" />
或
<Demo v-on:send="test" />
2.第二种方式,在父组件中:
<Demo ref="demo" />
...
mounted(){
this.$refs.xxx.$on('send', this.test);
}
3.若想让自定义事件只能触发一次,可以使用 once 修饰符,或 $once 方法。
1.8.4 触发自定义事件
this.$emit('send', 数据);
1.8.5 解绑自定义事件
this.$off('send');
1.8.6 组件上也可以绑定原生DOM事件,需要使用 native 修饰符
1.8.7 注意
通过
this.$refs.xxx.$on('send', 回调);
绑定自定义事件时,回调要么配置在 methods 中,要么用箭头函数,否则this指向会出问题。
1.9 全局事件总线(GlobalEventBus)
1.9.1 一种组件间通信的方式,适用于任意组件间通信
1.9.2 安装全局事件总线
new Vue({
...
beforeCreate() {
Vue.prototype.$bus = this; // 安装全局事件总线,$bus就是当前应用的vm
}
})
1.9.3 使用事件总线
1.接收数据:A组件想接收数据,则在A组件中给 $bus 绑定自定义事件,事件的回调留在A组件自身。
methods(){
demo(data){ ...... }
}
....
moutend(){
this.$bus.$on('xxxx', this.demo);
}
2.提供数据:
this.$bus.$emit('xxxx', 数据);
1.9.4 最好在 beforeDestroy 钩子中,用 $off 去解绑当前组件所用到的事件
1.10 消息订阅与发布(pubsub)
1.10.1 一种组件间通信的方式,适用于任意组件间通信
1.10.2 使用步骤
1.安装 pubsub
npm install pubsub-js
2.引入
import pubsub from 'pubsub-js';
3.接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods:{
demo(data){......}
}
....
mouted() {
this.pid = pubsub.subscribe('xxx', this.demo); // 订阅消息
}
4. 提供数据
pubsub.publish('xxx', 数据);
5.最好在 beforeDestory 钩子函数中, 用 pubsub.unsubscribe(pid) 取消订阅。
1.11 nextTick
1.11.1 语法
this.$nextTick(回调函数);
1.11.2 作用
在下一次DOM更新结束后执行其指定的回调。
1.11.3 什么时候用:当改变数据后,要基于更新后的新的DOM进行某些操作时,要在 nextTick 所指定的回调函数中执行
1.12 vue封装的过渡与动画
1.12.1 作用
在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名。
1.12.2 图示
1.12.3 写法
1.准备好样式
- 元素进入的样式
- v-enter: 进入的起点
- v-enter-active: 进入过程中
- v-enter-to: 进入的终点
- 元素离开的样式
- v-leave:离开的起点
- v-leave-active:离开过程中
- v-leave-to:离开的终点
2.使用 <transitions> 包裹要过渡的元素,并配置 name 属性
<transition name="hello">
<h1 v-show="isShow">你好啊</h1>
</transition>
3.备注:若有多个元素需要过渡,则需要使用:<transition-group>,且每个元素都要指定 key 值。
二、Vue中的ajax
2.1 vue脚手架配置代理
2.1.1 方法1
在 vue.config.js 中添加如下配置
devServer: {
proxy: "http://localhost:5000"
}
说明:
1.优点:配置简单,请求资源时直接发给前端(8080)即可。
2.缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
3.工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器(优先匹配前端资源)
2.1.2 方法2
编写 vue.config.js 配置具体代理规则:
module.exports = {
devServer: {
proxy: {
'/api1': { // 匹配所有以 '/api1' 开头的请求
target: "http://localhost:5000', // 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/api1': ''}
},
'/api2': { // 匹配所有以 '/api2' 开头的请求
target: "http://localhost:5000', // 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/api2': ''}
}
}
}
}
/*
changeOrigin 设置为 true 时,服务器收到的请求头中的 host 为: localhost:5000
changeOrigin 设置为 false 时,服务器收到的请求头中的 host 为: localhost:8080
changeOrigin 默认值为 true 【服务器收到的请求是否为真的请求地址】
*/
说明:
1.优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
2.缺点:配置略微繁琐,请求资源时必须加前缀。
2.2 vue项目中常用的2个Ajax库
2.2.1 axios
通用的Ajax请求库,官方推荐,使用广泛。
2.2.2 vue-resource
vue插件库,vue1.x 使用广泛,官方已经不维护。
三、插槽
3.1 作用
让父组件可以向子组件指定位置插入 html 结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件
3.2 分类
默认插槽、具名插槽、作用域插槽。
3.3 使用方式
3.3.1 默认插槽
父组件中:
<Category>
<div>html结构</div>
</Category>
子组件中
<template>
<div>
<!-- 定义插槽 -->
<slot>插槽默认内容....</slot>
</div>
</template>
3.3.2 具名插槽
父组件中
<Category>
<template solt="center">
<div>html结构1</div>
</template>
<template v-solt:footer>
<div>html结构2</div>
</template>
</Category>
子组件中
<template>
<div>
<!-- 定义插槽 -->
<slot name="center">插槽默认内容....</slot>
<slot name="footer">插槽默认内容....</slot>
</div>
</template>
3.3.3 作用域插槽
(1)理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据再 Category 组件中,但使用数据所遍历出来的解构由App组件决定)
(2)具体编码
父组件中:
<Category>
<template scope="scopeDate">
<!-- 生成的是ul列表 -->
<ul>
<li v-for="g in scopeDate.games" :key="g">{{g}}</li>
</ul>
</template>
</Category>
<Category>
<template slot-scope="scopeDate">
<!-- 生成的是ul列表 -->
<ul>
<li v-for="g in scopeDate.games" :key="g">{{g}}</li>
</ul>
</template>
</Category>
子组件中:
<template>
<div>
<!-- 定义插槽 -->
<slot :games="games"></slot>
</div>
</template>
<script>
export default {
name: 'Category',
props: ['title'],
// 数据在子组件自身
data() {
return {
games: ['red', 'blue', 'pink', 'yellow']
}
}
}
</script>
四、vuex
4.1 理解 vuex
4.1.1 vuex 是什么?
1.概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且使用于任意组件间通信。
2.Github:http://githup.com/vuejs/vuex
4.1.2 什么时候用 Vuex
(1)多个组件依赖于同一状态。
(2)来自不同组件的行为需要变更同一状态。
4.1.3 Vuex 工作原理图
4.1.4 注意
vue2中,要用 vuex 的3版本。
vue3中,要用 vuex 的4版本。
4.2 搭建 vuex 环境
1.创建文件: src/store/index.js
// 引入 Vuex 核心库
import Vue from 'vue';
// 引入 Vuex
import Vuex from 'vuex';
// 应用 Vuex 插件
Vue.use(Vuex);
// 准备 actions 对象 —— 响应组件中用户的动作
const actions = {};
// 准备 mutations 对象 —— 修改 state 中的数据
const mutations = {};
// 准备 state 对象 —— 保存具体的数据
const state = {};
// 准备 getters 对象 —— 类似计算属性
const getters = {};
// 准备 modules 对象 —— 分模块
const modules = {};
// 创建并暴露 store
export default new Vuex.Store({
actions,
mutations,
state,
getters,
modules
})
2.在 main.js 中创建 vm 时传入 store 配置项
...
// 引入 store
import store from './store';
....
// 创建 vm
new Vue({
el: "#app",
render: h => h(App),
store
})
4.3 基本使用
4.3.1 初始化数据,配置 actions、配置 mutations,操作文件 store.js
// 引入 Vuex 核心库
import Vue from 'vue';
// 引入 Vuex
import Vuex from 'vuex';
// 应用 Vuex 插件
Vue.use(Vuex);
// 准备 actions 对象 —— 响应组件中用户的动作
const actions = {
// 响应组件中的动作
jia(context, value) {
// console.log('actions中的 jia 被调用了', context, value);
context.commit('JIA', value);
}
};
// 准备 mutations 对象 —— 修改 state 中的数据
const mutations = {
// 执行加
JIA(state, value) {
// console.log('mutations中JIA被调用了', state, value);
state.sum += value;
}
};
// 准备 state 对象 —— 保存具体的数据
const state = {
sum: 0
};
// 准备 getters 对象 —— 类似计算属性
const getters = {};
// 准备 modules 对象 —— 分模块
const modules = {};
// 创建并暴露 store
export default new Vuex.Store({
actions,
mutations,
state,
getters,
modules
})
4.3.2 组件中读取 vuex 中的数据
$store.state.sum
4.3.3 组件中修改 vuex 中的数据
$store.dispatch('action 中的方法名', 数据)
或
$store.commit('mutations 中的方法名', 数据)
备注:
若没有网络请求或其他业务逻辑,组件中也可以越过 actions,即不写 dispatch,直接编写 commit。
4.4 getters 的使用
4.4.1 概念
当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工。
4.4.2 在 store.js 中追加 getters 配置
const getters = {
bigSum(state) {
return state.sum * 10;
}
}
// 创建并暴露 store
export default new Vuex.Store({
...
getters,
})
4.4.3 组件中读取数据
$store.getters.bigSum
4.5 四个 map 方法的使用
4.5.1 mapState 方法:用于帮助我们映射 state 中的数据为计算属性
computed: {
// 借助 mapState 生成计算属性: sum、school、subject (对象写法)
...mapState({ sum: 'sum', school: 'school', subject: 'subject' }),
// 借助 mapState 生成计算属性: sum、school、subject (数组写法)
...mapState(['sum', 'school', 'subject'])
},
4.5.2 mapGetters 方法:用于帮助我们映射 getters 中的数据为计算属性
computed: {
// 借助 mapGetters 生成计算属性: bigSum (对象写法)
...mapGetters({ bigSum: 'bigSum' }),
// 借助 mapGetters 生成计算属性: bigSum (数组写法)
...mapGetters(['bigSum']),
}
4.5.3 mapActions 方法:用于帮助我们生成与 actions 对话的方法,即:包含 $store.dispatch(xxx) 的函数
methods: {
// 靠 mapActions 生成:incrementOdd、incrementOdd (对象形式)
...mapActions({ incrementOdd: 'jiaOdd', incrementOdd: 'jiaWait' }),
// 靠 mapActions 生成:incrementOdd、incrementOdd (数组形式)
...mapActions(['jiaOdd', 'jiaWait']),
},
4.5.4 mapMutations 方法:用于帮助我们生成与 mutations 对话的方法,即:包含 $store.commit(xxx) 的函数
methods: {
// 靠 mapActions 生成:incrementOdd、incrementOdd (对象形式)
...mapMutations({ increment: 'JIA', decrement: 'JIA' }),
// 靠 mapActions 生成:incrementOdd、incrementOdd (数组形式)
...mapMutations(['JIA', 'JIA']),
},
备注:
mapActions 与 mapMutations 使用时,若需要传递参数,在模板中绑定事件时传递好参数,否则参数是事件对象。