Vue
什么是Vue
是一套用于构建用户界面的渐进式框架,而渐进式则表示使用vue框架的时候,可以自由选择使用,而不是强制使用所有特性
Vue的概念
1,组件( 模版, 生命周期, 组件通信(props, inject, events), watch, computed, methods, 插槽slot, 内置组件 )
2,指令
3,路由
4,插件
5,过滤器
6,mixin
vue中创建组件的方式
1,全局组件使用Vue.component’
语法:Vue.component('name', 选项)
一般用来创建全局组件
2,选项:components
语法:
components: {
name: 选项
}
3,扩展子类Vue.extend()需要手动实例化
const ComponentClass = Vue.extend(选项)
new ComponentClass(选项参数)
new Vue(选项)做了什么
1,执行init方法
2,选项资源合并
3,执行beforeCreate
4,数据初始化工作
5,执行created
6,判断是否有el属性,如果有自动执行$mount如果没有就不在执行了
组件通信
组件通信就是两个或者两个以上组件数据的传递,称为组件通信,而组件通信有这么几个场景 (父子,子父,同级,跨级),不同的场景有不同的组件通信方法
父子:(子组件使用父组件传递的数据)
1,props传递,
2,子组件通过$paren获取父组件实例拿到数据,推荐使用props
子父:(父亲组件使用子组件的数据),
1,自定义事件,在子组中触发事件传递数据,父亲组件接受
2,$children获取子组件实例
3,$refs 获取子组件实例
同级:
1,状态提升至同级组件共同的父组件上
2,自定义事件,一个组件中定义事件,一个组件中触发事件
跨级:
1,provide / inject
2,vuex
3,自定义事件
vuex可以实现所有场景的组件通信
通信方法有很多,而在实际场景中我们只选择一种最合适
组件中的数据选项
data
Vue 实例的数据对象。Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。
以 _ 或 $ 开头的属性 不会 被 Vue 实例代理
实例创建之后,可以通过 vm.data.a。
在组件中data的值是一个function返回一个对象,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
props
用来接受副组件传递的数据
/// 传递
<Component :aaa="aaa">
new Component({
propsData: {
aaa: 'aaa'
}
})
// 接收
{
props: ['aaa'],
props: {
aaa: {
type: String,
default: ''
}
}
}
computed
计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。
computed本质是一个惰性求值的观察者,具有缓存性,只有当依赖变化后,第一次访问 computed 属性,才会计算新的值
var vm = new Vue({
data: { a: 1 },
computed: {
// 仅读取
aDouble: function () {
return this.a * 2
},
// 读取和设置
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
vm.aPlus // => 2
vm.aPlus = 3
vm.a // => 2
vm.aDouble // => 4
生命周期
就是一个组件从创建到销毁的过程中做了很多事务,然后在不同类型的事务执行执行后添加的回调函数,让使用可以在不同位置做不同自定义事务
在vue分为了数据初始化,dom初始化挂载,更新,销毁,缓存
<template>
<div>{{a}}</div>
</template>
{
data: () => ({
a: '1',
b: 2
}),
updated () {
console.log('跟新') // 无法获取到底是那个属性改变引起重新渲染
},
mounted () {
setTimeout(() => {
this.a = 100 // 触发更新
}, 1000)
setTimeout(() => {
this.b = 100 // 不触发更新
}, 2000)
}
}
<template>
<div>{{a}} {{b}}</div>
</template>
{
data: () => ({
a: '1',
b: 2
}),
mounted () {
setTimeout(() => {
this.a = 100 // 触发更新
this.$nextTick(() => {
console.log('a更新完成')
})
}, 1000)
setTimeout(() => {
this.b = 100 // 不触发更新
console.log('b更新完成')
}, 2000)
}
}
销毁 beforeDestroy destroyed 实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。 只能销毁vue内置的东西(数据,事件),但是无法销毁手动绑定的内容(事件,定时器),需要在这个生命周期手动清除
如何触发销毁,路由切换,v-if, component动态组件切换, 手动调用this.$destroy()
ref
作用在组件上绑定的是组件实例,作用在dom元素上绑定的是dom元素,可以通过$refs去访问到
$attrs
用来访问不是props的属性,也就是元素属性
<Component aa="aa" class="ccc" bb="bb" />
{
props: ['aa'],
mounted () {
console.log(this.$props) // {aa: 'aa'}
console.log(this.$attrs) // {class: 'ccc', bb: 'bb'}
}
}
vm.
set && vm.$delete
vm.watch可以在js中按照逻辑自动处理是否要监听
vm.$set 向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi')
<template>
<div>
<ul>
<li v-for="(value, name) in form">{{name}}:{{value}}</li>
</ul>
</div>
</template>
{
data () {
return {
aa: 1,
bb: 2,
form: {
age: 1,
name: '111'
}
}
},
mounted () {
this.aa = 22; //没问题视图可以更新
setTimeout(() => {
// 页面并不会有任何变化
this.form.sex = '男'
this.form.height = 110
// 页面会更新
this.$set(this.form, 'sex', '男')
this.$set(this.form, 'height', 110)
})
}
}
插件
插件是用来扩展Vue全局的一种实现方式,vue生态中很多都是以插件的形式存在,可以理解插件为一个包,这个包是一组相关的内容
vue-router:
router
组件的导航守卫
vuex
$store
插件需要注册才能使用 Vue.use(插件对象, 传递给插件的参数)用来注册插件 而Vue.use会自动执行,插件对象中的install方法,并且传递Vue类,和自定义参数
const pluginsObj = {
install (Vue, options) {
// 各种vue的全局扩展
Vue.proptotype.axx = {}
Vue.component()
Vue.filter()
...
}
}
Vue.use(pluginsObj, 'aaaa')
自定义插件
1,对象中有install方法 const pluginsObj = { install (Vue, options) { // 各种vue的全局扩展 Vue.proptotype.axx = {} Vue.component() Vue.filter() ... } }
2,直接就是一个函数 export default (Vue, options) { // 各种vue的全局扩展 Vue.proptotype.axx = {} Vue.component() Vue.filter() ... }