1.1 初始化脚手架
1.1.1 说明
Vue
脚手架是Vue
官方提供的标准化开发工具(开发平台)- 最新的版本是
4.x
- 文档
1.1.2 具体步骤
第一步(仅第一次执行):全局安装
@vue/cli
npm install -g @vue/cli
第二步: 切换到要创建项目的目录 ,然后使用命令创建项目
vue create xxxx
xxxx: 项目名
第三步:启动项目
npm run serve
备注:
如出现:下载缓慢请配置淘宝镜像:
npm config set registry https://registry.npm.taobao.org
Vue
脚手架隐藏了所有webpack
相关的配置,若想查看具体的webpack
配置,请执行:vue inspect > output.js
1.1.3 模板项目的结构
├──node_modules
├──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:包版本控制文件
1.1.4 不同版本的 Vue
vue.js
与vue.runtime.xxx.js
的区别:vue.js
是完整版的Vue
,包含:核心功能 + 模板解析器。vue.runtime.xxx.js
是运行版的Vue
,只包含:核心功能;没有模板解析器
- 因为
vue.runtime.xxx.js
没有模板解析器,所以不能使用template
这个配置项,需要使用render
函数接收到的createElement
函数去指定具体内容
1.1.5 vue.config.js
配置文件
- 使用
vue inspect > output.js
可以查看到Vue脚手架的默认配置。 - 使用
vue.config.js
可以对脚手架进行个性化定制,详情
1.2 ref
1.2.1 使用说明
- 被用来给元素或子组件注册引用信息(id 的替代者)
- 应用在
html
标签上获取的是真实DOM
元素,应用在组件标签上是组件实例对象(vc
) 使用方式:
- 打标识:
或.....
- 获取:
this.$refs.xxx
- 打标识:
1.3 props
1.3.1 使用说明
- 功能:让组件接收外部传过来的数据
- 传递数据:
接收数据:
- 第一种方式(只接收):
props:['name']
- 第二种方式(限制类型):
props:{name:String}
第三种方式(限制类型、限制必要性、指定默认值):
props:{ name:{ type:String, //类型 required:true, //必要性 default:'老王' //默认值 } }
备注:
props
是只读的,Vue
底层会监测你对props
的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props
的内容到data
中一份,然后去修改data
中的数据。
- 第一种方式(只接收):
1.3.2 代码示例
父组件 App
中使用子组件 Student
,并传参数
Student
组件接收父组件传来的参数
{{ msg }}
学生姓名: {{ studentName }}
学生性别: {{ studentSex }}
学生年龄: {{ age + 1 }}
1.4 混入
1.4.1 使用说明
- 功能:可以把多个组件共用的配置提取成一个混入对象
使用方式:
第一步定义混入:
{ data(){....}, methods:{....} .... }
第二步使用混入:
- 全局混入:Vue.mixin(xxx)
- 局部混入:mixins:['xxx']
1.4.2 代码示例
定义混入 mixin.js
// 定义一个混入配置信息
// 说明:如果混入中配置的数据、方法,在组件中有同样的数据定义、方法名称,会加载组件中的数据和方法,混入中的数据和方法就不起作用
const mixin1 = {
data() {
return {
x: 200,
y: 100
}
},
methods: {
showName() {
alert(this.name)
}
},
}
// 说明:生命周期中的函数,如果混入、组件中都有配置的话,二者都会执行
const mixin2 = {
mounted() {
console.log("mixin 中的 mounted... ")
},
}
export {
mixin1,
mixin2
}
在组件中使用混入:
学校名称: {{ name }}
学校地址: {{ address }}
学生姓名: {{ name }}
学生性别: {{ sex }}
学生年龄: {{ age }}
1.5 插件
1.5.1 使用说明
- 功能:用于增强
Vue
- 本质:包含
install
方法的一个对象,install
的第一个参数是Vue
,第二个以后的参数是插件使用者传递的数据。 定义插件:
对象.install = function (Vue, options) { // 1. 添加全局过滤器 Vue.filter(....) // 2. 添加全局指令 Vue.directive(....) // 3. 配置全局混入(合) Vue.mixin(....) // 4. 添加实例方法 Vue.prototype.$myMethod = function () {...} Vue.prototype.$myProperty = xxxx }
- 使用插件:
Vue.use()
1.5.2 代码示例
定义插件 plugins.js
export default {
install(Vue) {
console.log(Vue, "@@@@@");
// 全局定义过滤器
Vue.filter("strSlice", function (value) {
return value.slice(0, 4)
})
// 全局定义指令
Vue.directive("fbind", {
// 指令与元素成功绑定时 一上来
bind(element, binding) {
element.value = binding.value
},
// 指令所在元素插入页面时
inserted(element, binding) {
element.focus()
},
// 指令所在模板被重新解析时
updated(element, binding) {
element.value = binding.value
},
})
// 给 Vue 原型上添加一个方法 vm、vc 都能使用
Vue.prototype.hello = () => {
console.log("hello world ");
}
},
}
在 main.js
中使用插件
// 引入插件
import plugins from './plugins'
// 使用插件
Vue.use(plugins)
1.6 scoped
样式
- 作用:让样式在局部生效,防止冲突。
写法:
1.7 组件化编码流程
组件化编码流程:
- 拆分静态组件:组件要按照功能点拆分,命名不要与
html
元素冲突。 实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
- 一个组件在用:放在组件自身即可。
- 一些组件在用:放在他们共同的父组件上(状态提升)。
- 实现交互:从绑定事件开始。
- 拆分静态组件:组件要按照功能点拆分,命名不要与
props
适用于:- 父组件 ==> 子组件 通信
- 子组件 ==> 父组件 通信(要求父先给子一个函数)
- 使用
v-model
时要切记:v-model
绑定的值不能是props
传过来的值,因为props
是不可以修改的! props
传过来的若是对象类型的值,修改对象中的属性时Vue
不会报错,但不推荐这样做。
1.8 webStorage
1.8.1 使用说明
- 存储内容大小一般支持 5MB 左右(不同浏览器可能还不一样)
- 浏览器端通过
Window.sessionStorage
和Window.localStorage
属性来实现本地存储机制 相关API:
xxxxxStorage.setItem('key', 'value');
该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值xxxxxStorage.getItem('person');
该方法接受一个键名作为参数,返回键名对应的值xxxxxStorage.removeItem('key');
该方法接受一个键名作为参数,并把该键名从存储中删除xxxxxStorage.clear()
该方法会清空存储中的所有数据
备注:
SessionStorage
存储的内容会随着浏览器窗口关闭而消失LocalStorage
存储的内容,需要手动清除才会消失xxxxxStorage.getItem(xxx)
如果 xxx 对应的value
获取不到,那么getItem
的返回值是null
JSON.parse(null)
的结果依然是null
1.8.2 代码示例
LocalStorage
localStorage 浏览器本地存储
localStorage 浏览器本地存储
SessionStorage
sessionStorage 浏览器本地存储
sessionStorage 浏览器本地存储
1.9 组件的自定义事件
1.9.1 使用说明
- 一种组件间通信的方式,适用于:子组件 ===> 父组件
- 使用场景:A 是父组件,B 是子组件,B 想给 A 传数据,那么就要在 A 中给 B 绑定自定义事件(事件的回调在 A 中)。
绑定自定义事件:
- 第一种方式,在父组件中:
或 第二种方式,在父组件中:
...... mounted(){ this.$refs.xxx.$on('helloWorld', this.test) } - 若想让自定义事件只能触发一次,可以使用
once
修饰符,或$once
方法。
- 第一种方式,在父组件中:
- 触发自定义事件:
this.$emit('helloWorld',数据)
- 解绑自定义事件
this.$off('helloWorld')
- 组件上也可以绑定原生
DOM
事件,需要使用native
修饰符。 - 注意:通过
this.$refs.xxx.$on('helloWorld',回调)
绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this
指向会出问题!
1.9.2 代码示例
父组件 App
学校名称是:{{ schoolName }}
学生姓名是:{{ studentName }}
子组件 School
学校名称: {{ name }}
学校地址: {{ address }}
子组件 Student
学生姓名: {{ name }}
学生性别: {{ sex }}
学生年龄: {{ age }}
1.10 全局事件总线
1.10.1 使用说明
- 一种组件间通信的方式,适用于任意组件间通信。
安装全局事件总线:
new Vue({ ...... beforeCreate() { Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm }, ...... })
使用事件总线:
接收数据:A 组件想接收数据,则在 A 组件中给
$bus
绑定自定义事件,事件的回调留在 A 组件自身。methods(){ demo(data){......} } ...... mounted() { this.$bus.$on('xxxx',this.demo) }
- 提供数据:
this.$bus.$emit('xxxx',数据)
- 最好在
beforeDestroy
钩子中,用$off
去解绑当前组件所用到的事件。
1.10.2 代码示例
在 main.js
中安装全局事件总线
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
el: "#app",
render: h => h(App),
beforeCreate() {
// 安装全局事件总线
Vue.prototype.$bus = this
}
})
在组件 School
中挂载全局事件
学校名称: {{ name }}
学校地址: {{ address }}
在 Student
组件中触发全局事件
学生姓名: {{ name }}
学生性别: {{ sex }}
学生年龄: {{ age }}
1.11 消息订阅与发布
1.11.1 说明使用
- 一种组件间通信的方式,适用于任意组件间通信
它包含以下操作:
- 订阅消息--对应绑定事件监听
- 发布消息--分发事件
- 取消消息订阅--解绑事件监听
PubSub.js
- 在线文档
- 安装:
相关语法:
import PubSub from 'pubsub-js'
: 引入PubSub.subscribe(‘msgName’, functon(msgName, data){})
: 订阅PubSub.publish(‘msgName’,data)
: 发布消息,触发订阅的回调函数调用PubSub.unsubscribe(token)
: 取消消息的订阅
使用步骤:
- 安装
pubsub
:npm i pubsub-js
- 引入:
import pubsub from 'pubsub-js'
接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods(){ demo(data){......} } ...... mounted() { this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息 }
- 提供数据:
pubsub.publish('xxx',数据)
- 最好在
beforeDestroy
钩子中,用PubSub.unsubscribe(pid)
去取消订阅。
- 安装
1.11.2 代码示例
School
组件订阅消息
学校名称: {{ name }}
学校地址: {{ address }}
Student
组件消费消息
学生姓名: {{ name }}
学生性别: {{ sex }}
学生年龄: {{ age }}
1.12 nextTick
- 语法:
this.$nextTick(回调函数)
- 作用:在下一次
DOM
更新结束后执行其指定的回调 什么时候用:当改变数据后,要基于更新后的新
DOM
进行某些操作时,要在nextTick
所指定的回调函数中执行1.13 过度与动画
1.13.1 使用说明
- 作用:在插入、更新或移除
DOM
元素时,在合适的时候给元素添加样式类名 写法:
准备好样式:
元素进入的样式:
v-enter
:进入的起点v-enter-active
:进入过程中v-enter-to
:进入的终点
元素离开的样式:
v-leave
:离开的起点v-leave-active
:离开过程中v-leave-to
:离开的终点
使用
包裹要过度的元素,并配置name
属性:你好啊!
- 备注:若有多个元素需要过度,则需要使用:
,且每个元素都要指定key
值
1.13.2 代码示例
transition
Hello World
transition-group
Hello
World
使用第三方动画库 Animate.css
Hello
World
1.14 插槽
1.14.1 使用说明
- 作用:让父组件可以向子组件指定位置插入
html
结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件 。 分类:默认插槽、具名插槽、作用域插槽
1.14.2 默认插槽
父组件
html结构1
子组件
插槽默认内容...
1.14.3 具名插槽
父组件中
html结构1
html结构2
子组件中
插槽默认内容...
插槽默认内容...
1.14.4 作用域插槽
- 理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(
games
数据在Category
组件中,但使用数据所遍历出来的结构由App
组件决定) 具体编码:
父组件中
- {{g}}
{{g}}
子组件