小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
Vue2 基础语法
文章都是我从自己的笔记中复制过来的,所以整篇文章风格更加偏向笔记风,没有像文章那样的解释之类的
let vm = new Vue({
// 挂载点
el: '.app',
// 存放响应式数据
data: {
msg: '你好',
msg2: '数据'
},
// 计算属性
computed: {
'msgGetters':function(){
return this.msg2 + '测试'
}
},
// 存放方法
methods: {
clickDiv(){
console.log('点击了 div')
}
}
})
v-xxx 基础指令
- v-text
渲染 vue 数据,但不能渲染数据中的 HTML 标签
- v-html
渲染 vue 数据:v-html = 'msg'
能够渲染数据中的 HTML 标签
- v-cloak
解决刷新页面时,数据闪烁问题。
- v-bind
单向绑定数据:v-bind:属性名 = 'msg'
简写::属性名 = 'msg'
修饰符:
-
- .prop:将数据绑定到元素的 property 上。
- .sync:语法糖,用来修改父组件数据。
- v-on
事件绑定:v-on:click = 'add()'
简写为: @click = 'add()'
修饰符:
- .stop:阻止事件冒泡
- .prevent:阻止 DOM 默认行为
- .capture:实现捕获触发事件的机制
- .self:规定冒泡与捕获无法触发本事件
- .once:规定只能触发一次本事件
- .left:规定只有鼠标左键才能触发此事件
- .right:规定只有鼠标右键才能触发此事件
- .midde:规定只有鼠标中键能够触发本事件
- @keyup.按键码:将事件绑定到键盘,当按下对应事件码时触发事件。
- v-model
双向数据绑定,修饰符:
- .lazy:取代 input 监听 onchange事件
- .number:将输入的字符串转为有效数字
- .trim:清除输入数据的首尾空格
- v-for
循环渲染数组、对象、数字、字符串
- v-if
创建删除元素
- v-else
配合 v-if 使用
- v-else-if
配合 v-if 和 v-else 使用
- v-show
显示隐藏元素
- v-slot
插槽指令
- v-pre
声明跳过此元素的编译过程,显示原始标签。
- v-once
表明此 DOM 或组件只渲染一次,之后这个 DOM、组件及其所有的子节点都将被视为静态内容而不会被更新渲染。可以用于优化更新性能。
filter 过滤器
私有过滤器比全局过滤器优先级要高。(Vue3 已删除过滤器语法)。
// 全局过滤器
// 第一个参数永远代表数据本身,第二个则是自定义的参数
Vue.filter('filterVal', function(msg, data){
return data + 1
})
// 私有过滤器
let vm = new Vue({
// 挂载点
el: '.app',
filters:{
filterVal: function(msg, data){
return data + 1
}
}
})
// 过滤器使用时:响应式数据 | 过滤器(参数)
<p>{{ data | filterVal('1') }}</p>
watch 侦听器
watch 会对目标进行侦听,当侦听的目标发生变化时就会触发侦听器的事件。
let vm = new Vue({
// 挂载点
el: '.app',
data: {
msg: '你好'
},
// 监听数据
watch: {
// 侦听数据
// 侦听器的第一个参数为最新的值,第二个值为上一次的值。
msg(newMsg, oldMsg){
this.msg = this.msg + '+我好'
},
// 侦听路由
'$route.path': function(newMsg, oldMsg){
// 处理事件
}
// immediate 属性,设置为 true 后,将会在加载页面时就对数据进行一次事件处理
// 而非等待数据发生变化再去触发事件处理
immediate: true
// deep 深度监听
deep: true,
// 开启深度监听后可以监听对象中的数值
'Obj.a'(newMsg, oldMsg){
// 处理事件
}
}
})
computed 计算属性
计算属性内部的所有 data,只要其中一个发生了变化,那么就会立刻调用这个计算属性函数,并将结果缓存下来,方便下次使用。
let vm = new Vue({
// 挂载点
el: '.app',
data:{
msg: 1,
msg1: 2
},
// 计算数据
computed: {
'fullMsg': function(){
return msg + msg1
},
// getter 和 setter 属性
// setter 可以在数据被修改时执行一些操作
'modifyMsg':{
// getter
get: function () {
// 处理事件
},
// setter
set: function (newValue) {
// 处理事件
}
}
}
})
// 使用,使用时不必要当做函数调用而加上(),
// 只需要将其当做普通数据使用就可。
// 可以将其理解为一个进行加工后的数据。
<p>{{ fullMsg }}</p>
keyup 按键修饰符
常见按键修饰符:
- .enter
- .tab
- .delete (捕获“删除”和“退格”键)
- .esc
- .space
- .up
- .down
- .left
- .right
系统按键修饰符
- .ctrl
- .alt
- .shift
- .meta
鼠标按揭修饰符
- .left
- .right
- .middle
// 输入框按下回车键时触发
<input @keyup.enter="add()">123</input>
// ctrl 加单击时触发
<o @click.ctrl="sum()">123</p>
<!-- alt 和回车同时按下才会触发 -->
<input @keyup.alt.enter="clear" />
.exact 修饰符
对按键修饰符进行精确控制。
<!-- 按住 ctrl 的同时安装其他键盘也可以触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 只有在按下 ctrl 时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有按下任何键盘时才会触发 -->
<button @click.exact="onClick">A</button>
directive 自定指令
八个常用自定指令:
定义的指令在调用时需要加上 v- 前缀。
// 定义全局指令
Vue.directive('clickColor', {
// 执行事件
})
let vm = new Vue({
// 挂载点
el: '.app',
// 局部自定指令
directives:{
// 指令定义时可以使用大写,
// 但在调用时必须改为小写:v-click-color
clickColor:{
// 执行事件
}
}
})
// 给指令传参数时需加上 '' 号
<p v-click-color="'blue'">指令测试</p>
钩子函数生命周期
mounted
- 模板挂载时调用。
bind
- 只调用一次,在指令绑定到元素上时调用。(CSS 样式最早在这使用)。
inserted
- 只调用一次,在被绑定元素插入父节点时调用。(js 行为最早在这使用)。
update
- 绑定元素 Vnode 更新时调用。
componentUp的、ate
- 帮顶元素 Vnode 及子 Vnode 都更新时调用。
unbind
- 只调用一次,指令解绑时调用。
// 定义全局指令
Vue.directive('clickColor', {
mounted(){},
bind(){},
inserted(){},
update(){},
componentUpdate(){},
unbind(){}
})
钩子函数参数
el
- 指令绑定的元素本身,用来操作 DOM。
binding
- 返回一个对象,对象中包含。
name
- 指令的名称,不包含 v-。
value
- 通过指令传入的所有值。
oldvalue
- 指令绑定的前一个值,只能在 update 和 ComponentUpdate 中使用。
expression
- 字符串形式的指令表达式。
arg
- 传给指令的参数。
modifiers
- 包含修饰符的对象。
- Tips:arg 与 modifiers 的区别在于一个是使用 : 冒号一个是使用 . 点号。
vnode
- Vue 编译成的虚拟节点。
oldvnode
- Vue 编译成的上一个虚拟节点,只能在 update 和 ComponentUpdate 中使用。
// 定义全局指令
Vue.directive('clickColor', {
bind(el, binding, vnode){
// ...
},
inserted(el, binding, vnode){
// ...
},
// oldVnode 只能在 update 和 componentUpdate 中使用
update(el, binding, vnode, oldVnode){
// binding 中的 oldvalue 属性
// 只能在 update 和 componentUpdate 中使用
console.log(binding.oldvalue)
},
componentUpdate(el, binding, vnode, oldVnode){
// ...
},
unbind(el, binding, vnode){
// ...
}
})
component 组件
组件简单学习
// 定义一个名为 button-counter 的组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: `<button v-on:click="count++">
组件定义:{{ count }}</button>`
})
// 另一种定义方法
Vue.component('button-counter2', {
data: function () {
return {
count: 0
}
},
template: '#myTemp'
})
<template id="myTemp">
<p v-on:click="count++">第二种组件定义方法:{{ count }}</p>
</template>
// 私有组件定义
let vm = new Vue({
// 挂载点
el: '.app',
// 局部组件
components:{
temp:{
// 组件名
template: '#add-count',
data: function(){
return{
count: 1
}
},
methods:{
add(){
this.count ++
}
}
},
temp1:{
// 组件名
template: '#content'
}
}
})
// 组件1
<template id="add-count">
<p @click="add()">{{ count }}</p>
</template>
// 组件2
<template id="content">
<p>组件内容</p>
</template>
组件切换
使用 component 的 is 属性来切换组件的使用。
// 通过切换不同的组件名来实现,组件的切换效果
<component :is="组件名"></component>
// 使用 transition 给组件添加切换时的动画效果
// out-in 定义组件动画为先出去再进来
<transition mode="out-in"
// 退出动画定义
leave-active-class="类名"
// 进入动画定义
enter-active-class="类名"
// 设置组件的进入退出时间
:duration="{enter:1000,leave:400}">
// 切换组件
<component :is="组件名"></component>
</transition>
// 组件缓存
<keep-alive
include="匹配那些组件可以被缓存"
exclude="定义那些组件不可以被缓存"
max="定义最多可以缓存多少组件,默认为 5 个">
<component :is="组件名">缓存</component>
</keep-alive>
ref
ref 是 Vue 内部提供的一个用来获取 DOM 的语法糖。因为也可以获取到子组件 DOM,所以常用来做父子组件通信。
<p ref="p">123</p>
<子组件 res="component"></子组件>
// 输出:123
console.log(this.$ref.p.innerText)
// 使用子组件数据
console.log(this.$refs.component.msg)
// 调用子组件方法
this.$refs.component.function()
Vue2 生命周期
创建前
- beforeCreate(){}
创建后
- created(){}
模板挂载前
- beforeMount(){}
模板怪哉后
- mounted(){}
更新前
- beforeupdate(){}
更新后
- update(){}
销毁前
- beforDestroy(){}
销毁后
- destroy(){}
slot 插槽
插槽使用场景:如果子组件需要显示的内容并非来自本身,而是父组件传递进来的,是不会显示的。需要在原本子组件内容里添加个 slot 标签才会显示。
例如下面这个:
<div id="app">
<me-component>
// 此时 h1 标签是不会显示的
<h1>我是header</h1>
</me-component>
</div>
<script>
Vue.component('me-component', {
template:
`<div>
<p>你好</p>
</div>`
})
var vm = new Vue({
el:"#app"
})
</script>
修改后:
<div id="app">
<me-component>
// 能够显示了
<h1>我是header</h1>
</me-component>
</div>
<script>
Vue.component('me-component', {
template:
`<div>
<p>你好</p>
// 加上 slot 插槽标签
<slot></slot>
</div>`
})
var vm = new Vue({
el:"#app"
})
</script>
具名插槽(v-slot:name)
如果需要显示多个内容时,可以使用具名插槽。
<div id="app">
<me-component>
<h1 v-slot:header>我是 header</h1>
<h2 v-slot:footer>我是 footerr</h2>
</me-component>
</div>
<script>
Vue.component('me-component', {
template:
`<div>
<p>你好</p>
<slot name="header"></slot>
<slot name="footer"></slot>
</div>`
})
var vm = new Vue({
el:"#app"
})
</script>
插槽默认内容
另外,插槽还支持默认内容显示:
<div id="app">
<me-component>
<h1 slot="header">我是header</h1>
<!-- <h1 slot="footer">我是footerr</h1> -->
</me-component>
</div>
<script>
Vue.component('me-component', {
template:
`<div>
<p>你好</p>
<slot name="header">我是默认内容1</slot>
<slot name="footer">我是默认内容2</slot>
</div>`
})
var vm = new Vue({
el:"#app"
})
</script>
作用域插槽(scope)
插槽的内容最后是在子组件模板上渲染的,但是假设这时我们需要使用子组件中的数据,这种时候就需要作用域插槽解决问题了。
作用域插槽是一种特殊类型的插槽,用作一个(能被传递数据的)可重用模板,来代替已经渲染好的元素。利用 slot 标签将子组件的数据传递到分发的内容上,类似于父子组件传值的 prop 传递数据。
<div id="app">
<me-component v-slot:userName="scope">
<p v-for="(key, value) in scope" v-key="key">{{ value }}</p>
</me-component>
</div>
<script>
Vue.component('me-component', {
template:
`<div>
<p>你好</p>
<slot name="name" :userName="user"></slot>
</div>`
})
var vm = new Vue({
el:"#app",
data: {
user: {
firstName: '张三',
lastName: '李四'
}
}
})
</script>
keep-alive 组件缓存
keep-alive 是 vue 的内置组件,用作缓存组件。
<template>
<div id="app">
<keep-alive>
<router-view/>
</keep-alive>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
1. 参数
- include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
- exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
- max - 数字。最多可以缓存多少组件实例。
<template>
<div id="app">
// 1. 将缓存 name 为 test 的组件
<keep-alive include='test'>
<router-view/>
</keep-alive>
// 2. 将缓存 name 为 a 或者 b 的组件,结合动态组件使用
<keep-alive include='a,b'>
<router-view/>
</keep-alive>
// 3. 使用正则表达式,需使用 v-bind
<keep-alive :include='/a|b/'>
<router-view/>
</keep-alive>
// 5.动态判断
<keep-alive :include='includedComponents'>
<router-view/>
</keep-alive>
// 5. 将不缓存 name 为 test 的组件
<keep-alive exclude='test'>
<router-view/>
</keep-alive>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
2. 独有生命周期:activated、deactivated
注意一点:activated, deactivated 这两个生命周期函数一定是要在使用了keep-alive 组件后才会有的,否则则不存在。
当引入 keep-alive 的时候,页面第一次进入,钩子的触发顺序为:created-> mounted-> activated,退出时触发 deactivated。当再次进入组件(前进或者后退)时,只触发 activated。
一般事件挂载的方法,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中, activated 中的不管是否需要缓存多会执行。