Vue 是一套用于构建用户界面的渐进式框架
main.js中render函数是因为引入runtime.js vue库中不包含模板解析器,利用render中createElement函数解析模板,
vue配置信息可创建vue.config.js配置。
父-->子传递数据 props ref
父-->子传递数据 组件自定义事件 props // $emit触发 $off解绑
组件销毁后所有自定义事件全部销毁 // $destroy销毁
脚手架搭建项目
npm install -g @vue/cli
npm update -g @vue/cli
vue create 项目名称
不同版本vue说明
可以添加vue.config.js修改配置 cli.vuejs.org/zh
el与data写法
1. 声明式渲染
文本插值
文本插值
<div id="app">
{{ message }}
</div>
绑定元素 attribute
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>`
2.指令
v-once
<span v-once>这个只执行一遍: {{ msg }}</span>
v-html
<span v-html="rawHtml"></span>
v-bind (属性attribute上)
<div v-bind:id="dynamicId"></div>
缩写 <a :href="url">...</a>
v-module
v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定
<textarea>{{text}}</textarea> 不生效
v-if // 支持 <template v-if="ok"></template>
v-else-if
v-else
v-show
v-for
// 也可以遍历对象
let object= {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>
<div v-for="item in items"></div>
<div v-for="item of items"></div>
{{ number + 1 }} // 计算
{{ ok ? 'YES' : 'NO' }} // 三目
{{ message.split('').reverse().join('') }} // 方法
<div v-bind:id="'list-' + id"></div> // 拼接
v-for
v-if
v-on
<a v-on:click="doSomething">...</a>
<a @click="doSomething">...</a>
自定义指令
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// 区局
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
// 使用
<input v-focus>
3.动态参数 (:[])
<a v-bind:[attributeName]="url"> ... </a>
<a v-on:[eventName]="doSomething"> ... </a>
4.修饰符
.prevent 阻止默认行为 // event.preventDefault()
<form v-on:submit.prevent="onSubmit">...</form>
.stop 阻止事件流
<div @click="get.stop"></div>
.capture 先执行父级的函数,再执行子级的触发函数
.self 只有点击目标元素才执行
.once 只执行一次
.passive 通过passive将内核线程查询跳过, 滚动
<div v-on:scroll.passive="onScroll">...</div>
每次事件产生,浏览器都会去查询一下是否有preventDefault阻止该次事件的默认动作。
我们加上passive就是为了告诉浏览器,不用查询了,我们没用preventDefault阻止默认动作。
.lazy
<input v-model.lazy="msg"> 将input改成change事件
.number // 如果这个值无法被 parseFloat() 解析,则会返回原始的值
<input v-model.number="age" type="number">
.trim // 去掉首尾空白字符
<input v-model.trim="msg">
keyup的修饰符
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
// 鼠标
.left
.right
.middle
.exact 有且只有 Ctrl 被按下的时候才触发
<button v-on:click.ctrl.exact="onCtrlClick">A</button>
原生js阻止捕获及冒泡
ev.stopPropagation();
5.监听与计算属性 (对象)
computed可以设置get、set属性方法 watch监听对象需要设置handler和deep
computed:{}
<div id="demo">{{ fullName }}</div>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
},
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
}
})
上面代码是命令式且重复的。将它与计算属性的版本进行比较:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
// computed set方法
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
6.Vue能监听倒得数组方法
// 改变原数组
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
// 返回新数组
- filter()
- concat()
- slice()
7.事件
click
<div @click="get,$event"></div>
submit
scroll
keyup
8.DOM事件处理
1) DOM0
内联模式 <div onclick="btnClick()">click</div>
脚本模型
let btn3 = document.getElementById("btn3");
btn1.onclick=function(){
console.log(1)
}
2) DOM2
事件侦听器 (事件名,函数,false表示使用冒泡机制、true表示捕获机制)
var btn=document.getElementById("btn");
btn.addEventListener("click",hello,false);
btn.addEventListener("click",helloagain,false);
结论:冒泡捕获都绑定的话,先执行捕获,目标元素依据绑定代码顺序,再冒泡。
事件委托
target返回触发事件的元素,不一定是绑定事件的元素
currentTarget返回的是绑定事件的元素
9.组件
keep-alive组件缓存,tab切换不需要重新渲染
9.1定义组件
组件名一般全小写,或者大驼峰,或者-连接
Vue.component("A",{
data:function(){
return {}
},
template:"<div>1</div>"
})
全局注册
Vue.component('component-a', { /* ... */ })
局部注册
let componentA = {}
9.2data 必须是一个函数,组件复用状态不受影响
9.3传递参数
父传子 传递属性或方法
子传父 通过$emit方法
9.4.动态组件
currentTabComponent
1.已注册组件的名字,
2.一个组件的选项对象.
<component v-bind:is="currentTabComponent"></component>
解析 DOM 模板时的注意事项
<table>
<tr is="blog-post-row"></tr>
</table>
9.5.异步组件
components:{
text:()=>import('./components/Text')
}
10.prop
prop 不区分大小写
<blog-post post-title="hello!"></blog-post>
属性需要写成
类型检查 (beforeCreat之前,所以此处data,computed不可用)
id: {
type: [Number,String],
default: 100,
required: true,
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
},
type类型
String
Number
Boolean
Array
Object
Date
Function
Symbol
.sync 修饰符 // todo 没理解
11.插槽
1.插槽内容
将 <slot> 元素作为承载分发内容的出口。
2.编译作用域
3.后备内容 不传内容显示默认内容
<slot>Submit</slot>
3.1
插槽内容传给父组件,子插槽slot用属性绑定例 :user=user
父组件内template 用v-slot:default='props'接收
4.具名插槽 (v-slot 只能添加在 <template> 上)
使用base-layout组件
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
定义base-layout组件
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
5.多个具名插槽,且带数据
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</current-user>
6.解构插槽
<current-user v-slot="{ user = { firstName: 'Guest' } }">
{{ user.firstName }}
</current-user>
7.v-slot缩写
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
<current-user #default="{ user }">
{{ user.firstName }}
</current-user>
12、生命周期
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestory
destoryed