Vux复习一(基础)
计算属性
computed: {
getName: {
// 查询
get(){
return this.firstName+this.lastName
},
// 就是 this.getName='xxx' 会触发这个方法
set(newval) {
this.firstName=newval;
}
},
reversedMessage() {
// 计算属性是基于他们的响应式依赖进行缓存的
return this.num1.split('').reverse().join('')
}
},
methods: {
add() {
this.getName='3333';
}
},
监听属性
data() {
return {
num1: '',
ans: '正在加载数据',
fn1: null,
}
},
methods: {
//这是一个请求
add() {
console.log(1);
}
},
watch: {
num1(newValue, oldValue) {
this.fn1()
},
// 方法名
b:'someMethod'
// 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// 该回调将会在侦听开始之后被立即调用
d: {
handler: 'someMethod',
immediate: true
},
// watch vm.e.f's value: {g: 5}
'e.f': function (val, oldVal) { /* ... */ },
// 你可以传入回调数组,它们会被逐一调用
e: [
'handle1',
function handle2 (val, oldVal) { /* ... */ },
{
handler: function handle3 (val, oldVal) { /* ... */ },
/* ... */
}
],
},
created() {
this.fn1 = _.debounce(this.add, 1000)
}
}
不应该使用箭头函数来定义 watcher 函数
理由是箭头函数绑定了父级作用域的上下文,所以 this
将不会按照期望指向 Vue 实例,
条件渲染分组
v-if v-else
<ng-container>
的替换方案是<template>
<div>
<button @click="add">Click</button>
<span v-if="num1">true</span>
<span v-else>false</span>
</div>
data() {
return {
num1: true,
}
},
methods: {
//这是一个请求
add() {
this.num1=!this.num1
}
},
v-if v-else-if v-else
<div>
<button @click="add">Click</button>
<template v-if="num1===1">A</template>
<template v-else-if="num1===2">B</template>
<template v-else-if="num1===3">C</template>
<template v-else>最后默认的</template>
</div>
add() {
if (this.num1 === 1) {
this.num1 = 2
} else if (this.num1 === 2) {
this.num1 = 3
} else if (this.num1 === 3) {
this.num1 = 4
} else if (this.num1 === 4) {
this.num1 = 1
}
}
注意,v-show
不支持 <template>
元素,也不支持 v-else
。
动态路由的变化
watch: {
'$route.params': function (params) {
}
}
v-for of 代替 in
<div v-for="(item,index) of arr" :key="index">{{item}}</div>
v-for 在对象中使用
<li v-for="(val,key) in obj" :key="key">{{val}}--{{key}}</li>
/* index 是索引*/
<li v-for="(val,key,index) in obj" :key="index">{{val}}--{{key}}--{{index}}</li>
obj: {
name: '333',
age: 12,
sex: '男'
},
双重 v-for
<ul>
<li v-for="(item,index) in arr1" :key="index">
<span v-for="(itemKey,keyIndex) in events(item)" :key="keyIndex">
{{ itemKey }}
</span>
</li>
</ul>
data() {
return {
arr1: [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
],
},
methods: {
events(num) {
return num.filter(val => val % 2 === 0)
},
}
v-for
里使用值范围
v-for
也可以接受整数。在这种情况下,它会把模板重复对应次数
<div v-for="(item,index) in 10" :key="index">{{item}}</div>
v-for template 规范
<ul>
<template v-for="(item,index) in [1,2,3,4]" >
<li :key="index">{{ item }}</li>
</template>
</ul>
事件处理
<button @click="greet">++</button>
// 也可以这样 greet('xxx') 传递参数
// 如果默认传递参数 就是 $event
// 默认第一个参数,拿到event事件
greet(event){
console.log(event.target);
}
表单
单个值得true
, false
<input type="checkbox" v-model="toggle">
自定义选择的值
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no"
>
true =>
.lazy
失去焦点触发
<input v-model.lazy="msg">
.number
数字
.trim
首尾空白
子传父
父
<One title="333" @add="clickAdd"/>
clickAdd(e){
console.log(e);
}
子 触发父
// 第一个参数是事件,第二个参数是传递的参数
this.$emit('add',{age:12})
v-model
<input v-model="searchText">
等价
<input
:value="searchText"
@input="searchText = $event.target.value">
动态组件
<component :is="num"></component>
data(){
return{
num:Three,
}
},
components:{
Two,
Three
},
第一次创建缓存起来
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
<!-- 基本 -->
<keep-alive>
<component :is="view"></component>
</keep-alive>
<!-- 多个条件判断的子组件 -->
<keep-alive>
<comp-a v-if="a > 1"></comp-a>
<comp-b v-else></comp-b>
</keep-alive>
组件名
my-component-name
MyComponentName
components: {
'component-a': ComponentA,
'component-b': ComponentB,
ComponentC
}
props
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
// 验证
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // 或任何其他构造函数
}
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
function Person (firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
props: {
author: Person
}
传入一个数字
<One :date="2"/>
因为是静态的,传入的是一个数字
继承关系inheritAttrs: false
inheritAttrs: false;
如果你不希望组件的根元素继承特性,你可以在组件的选项中设置允许组件绑定的未注册属性渲染到组件根节点上的
渲染显示的问题
注意
inheritAttrs: false
选项不会影响style
和class
的绑定。页面上 <div class="form-control"></div> 设置 inheritAttrs: false 页面上 <div title="333" name="age" class="form-control"></div>
v-model 封装表单
父
<Three v-model="bool" @change="clickMethod"></Three>
data(){
return{
bool:true,
}
},
methods:{
clickMethod(e) {
console.log(e);
}
},
子
<input type="checkbox" :checked="checked" @change="$emit('change',$event.target.checked)">
model:{
prop:'checked',
event:'change'
},
props:{
checked:Boolean
}
原生事件绑定在组件上
<base-input v-on:focus.native="onFocus"></base-input>
$listeners 不用事件委托执行父亲的方法
父
<One @add="clickMethod1"/>
clickMethod1(){
console.log(1);
}
子执行父亲的方法
this.$listeners.add()
v-on="$listeners" 就是类似于 父=>孙
.async 简便父传子的方法
就是子可以直接改父的这个值
:title 只是一个触发的自定义变量
父
<Two age="sex" :title.sync="bool" ></Two>
子改父
this.$emit('update:title','3333')
传入多个
父
<Two age="sex" v-bind.sync="obj"></Two>
obj:{
name1:'333',
name2:'444',
},
子
this.$emit('update:name1','5555')
插槽
1 正常的使用
父
<Two >
<h1>angular</h1>
</Two>
子
<slot></slot>
2 默认插槽
默认父的插入数据,就展示默认的
<slot>默认插槽</slot>
3 命名插槽
父
<Two>
<h1>angular</h1>
<template v-slot:a>
<h1>111</h1>
</template>
<template v-slot:b>
<h1>222</h1>
</template>
<template v-slot:c>
<h1>bbb</h1>
</template>
</Two>
子
<slot name="a"></slot>
<slot name="c"></slot>
<slot name="b"></slot>
<slot></slot>
父也可以这样写
<Two>
<h1>angular</h1>
<template #a>
<h1>111</h1>
</template>
<template #b>
<h1>222</h1>
</template>
<template #c>
<h1>bbb</h1>
<span>{{obj.name1}}</span>
</template>
</Two>
异步组件
components: {
'my-component': () => import('./my-async-component')
}
处理状态
const AsyncComponent = (AsyncView) => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: AsyncView,
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载时组件的延时时间。默认值是 200 (毫秒)
delay: 200,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})
components: {
'my-component': () => AsyncComponent(import('@/my-async-component'))
}
依赖注入 provide/inject
provide 选项允许我们指定我们想要提供给后代组件的数据/方法
父=>子孙后代
provide(){
return{
name:'1',
change:val=>val+1
}
}
子或者后代
export default {
inject: ['name','change'],
mounted () {
console.log(this.name); // Aresn
console.log(this.change(10))
}
}
监听
通过 $on(eventName, eventHandler) 侦听一个事件
通过 $once(eventName, eventHandler) 一次性侦听一个事件
通过 $off(eventName, eventHandler) 停止侦听一个事件
清空插件的时间管理器
mounted: function () {
// 每个新的实例都程序化地在后期清理它自己
this.attachDatepicker('startDateInput')
this.attachDatepicker('endDateInput')
},
methods: {
attachDatepicker: function (refName) {
var picker = new Pikaday({
field: this.$refs[refName],
format: 'YYYY-MM-DD'
})
// 组件销毁前 清空
this.$once('hook:beforeDestroy', function () {
picker.destroy()
})
}
}
递归组件
使用 <app-circle count="10"></app-circle>
递归组件
<template>
<div>
1
// 这里写相对于写了循环条件
<app-circle v-if="count>1" :count="count-1"></app-circle>
</div>
</template>
<script>
export default {
name: "app-circle",
props:['count'],
methods: {
}
}
</script>
组件之间的循环引用
<div v-for="(item,index) in dataArr" :key="index">
<Two v-if="item.children"/>
<span v-else>暂无</span>
</div>
dataArr: [
{children: true},
{children: false},
{children: true},
{children: true},
]
强制刷新
this.$forceUpdate()
迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
过渡
https://cn.vuejs.org/v2/guide/transitions.html
混入
合并 , mixins 的优先级高于正常的
let min={
data(){
return {
num:123
}
}
};
export default {
mixins:[min],
data() {
return {
num:234,
sex:'xxx'
}
},
created() {
console.log(this.$data);
// {num: 234, sex: "xxx"}
}
}
$data
的数据, mixins 优先级高于本身的生命周期的话, 混入对象先被调用
let min={ methods:{ add(){ console.log('add'); } } }; export default { mixins:[min], methods:{ add(){ console.log('add1'); } }, created() { this.add() // add1 } }
methods
、components
和directives
,将被合并为同一个对象。两个对象键名冲突时,取自身的对象。Vue.extend()也是同样的策略合并
指令
directives
参数
-
el
:指令所绑定的元素,可以用来直接操作 DOM。 -
binding
:一个对象,包含以下 property:
name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
-
vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。 -
oldVnode
:上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
data() {
return {
num:234,
}
},
directives:{
// 不关系钩子就这样写
colors(el,attr) {
console.log(attr.value);
// 333
// el 拿到dom
el.style.color='red'
console.log(el.getAttribute('num'));
// 234
}
}
<div v-colors="333">12211212</div>
除了
el
之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的dataset
来进行。
钩子函数
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
VNodes 的细节
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
接下来我们来看一下钩子函数的参数 (即 el
、binding
、vnode
和 oldVnode
)。
directives:{
// 不关系钩子就这样写
colors:{
bind(el){
}
}
}
api
$root 根组件
$parent 父组件, 你怎么知道哪个是父组件,如果多个呢? 慎用
$refs 访问子组件或者子元素
组件 <base-input ref="usernameInput"></base-input>
this.$refs.usernameInput
生命周期
// 初始化前 data都没加载上去
beforeCreate
// 初始化 data props 方法 watch 都挂在了
created
// 挂在前: 相关的render 函数首次被调用
beforeMount
// dom操作 $el 挂载到页面上
// 注意mounted 不会保证所有子组件挂载上
mounted
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
// 数据更新时前
// 手动移除已添加的事件监听器。
// 该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行
beforeUpdate
// 数据更新时调用
// 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watch取而代之。
updated
// 注意 updated 不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}
// 被 keep-alive 缓存的组件激活时调用。
activated
// 被 keep-alive 缓存的组件停用时调用。
deactivated
// 实例销毁之前调用
beforeDestroy
// 实例销毁后调用
destroyed
// 在捕获错误时
errorCaptured
eslint
Vue/cli
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬