前言
- VUE是前端用的最多的框架;
- 这篇文章是本人大一上学习前端的笔记;
- 欢迎点赞 + 收藏 + 关注,本人将会持续更新。
Vue学习笔记
用于构建用户界面的渐进式框架
- 构建用户界面:基于数据动态渲染页面
- 渐进式:循序渐近的学习
- 框架:一套完整项目解决方案
1、Vue核心
1.1、vue实例配置对象
选项 | 说明 |
---|---|
data | Vue实例数据对象 |
methods | 定义Vue实例中的方法 |
components | 定义子组件 |
computed | 计算属性 |
filter | 过滤器 |
el | 唯一跟标签 |
watch | 监听数据变化 |
1.2、初始Vue
- 想让Vue工作,就必须创建一个Vue实例,并且要传入一个配置对象
- root容器里的代码依然符合html规范
- Vue模板:root容器中的代码
{{xxxx}}
中的xxx表达式要写js表达式- 实际开发中只有一个Vue实例
<-->引入Vue</-->
<script src=""></script>
<body>
<-->准备好一个容器</-->
<div id="root">
<h2>
hello! {{name}}
</h2>
</div>
<script>
var vm = new Vue({
el: '#root', //唯一标签
data: {
name: 'wy' //data储存数据
}
})
</script>
</body>
1.3、模板语法
<script src="vue.js文件地址"></script>
<body>
<div id="root">
<h1>
插值语法
</h1>
<h3>
hello {{name}}
</h3>
<h1>
指令语法
</h1>
<a v-bind:href="ur1">邓紫棋</a>
<-->b-vind: 的简写形式 :href</-->
</div>
</body>
总结:
-
插值语法:
- 用于解析标签内容
-
指令语法:
- 功能:用于
解析标签
(包括:标签属性、标签体内容、绑定事件……) :href
是v-bind:href
的简写形式- 备注:Vue中的很多指令都是
v-???
形式
- 功能:用于
1.4、数据绑定
<script src=""></script>
<body>
<div id="root">
单项数据绑定:<input type="text" v-bind:value="name">
双向数据绑定:<input type="text" v-bind:value="name">
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: 'wqy'
}
})
</script>
</body>
总结:
- Vue的2种数据绑定
- 单项数据绑定(
v-bind
): 数据只能从data流向页面 - 双向数据绑定(v-model):数据既可以从data流向页面,还可以从页面流向data
- 单项数据绑定(
- 技巧:
- 双向绑定都应用在表单类元素上,(如: \ 等)
- v-model:value简写成v-model
1.5、el和data的两种写法
<script>
const vm = new Vue({
//1.
el: '#root',
data: {
}
//data的第二种写法
data() {
}
})
//el的第二种写法
vm.$mount('#root')
</script>
总结;
- data有两种写法:
- 对象式
- 函数式
注意:Vue管理的函数,一定不要写出箭头函数,否则this就不再是Vue实例了
1.6、MVVM模型
总结:
- data中所有属性,最后都出现在vm上
1.8、事件处理
1.8.1、事件的基本用法
<script src=""></script>
<body>
<div id="root">
<h2>
hello , {{name}}
</h2>
<boutton v-on:click="showIndo1">点我提升信息一 </boutton>
<button @click='showIno2(66)'>
点我提示信息二
</button>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
name: 'wy'
}
methods: {
showIno1(event) {
console.log(event);
}
showIno2(num) {
console.log(num);
}
}
})
</script>
</body>
总结:
- 使用v-on:xxx或者**@xxx**绑定事件,其中xxx是事件名
- 事件的回调需要配置在methods对象中,最总会出现在vm上
- methods中配置函数,
不要使用箭头函数
- methods中配置的函数,都是被Vue所管理的函数,this指向是vm或者实例化对象
@click="demo
和@click="demo($event)"
效果一致,但后者可以传参
1.8.2、事件修饰符
- prevent:阻止默认事件(常用)
- stop:阻止事件冒泡(常用)
- once:事件只触发一次(常用)
- capture:使用事件捕获(执行顺序是有外部到内部 P31页)
- self: 只有event.target是当前操作的元素时才触发事件,简单理解:只触发自己本身的元素
- passive: 事件的默认行为为立即执行函数
技巧:修饰符可以连续写: @click.prevent.stop=“show”
1.8.3、键盘事件
<script src=""></script>
<body>
<div id="root">
<input type="text" @keydow.enter="show">
</div>
<body>
const vm = new Vue({
el: '#root',
methods: {
show(e) {
console.log(e.target.value)
}
}
})
</body>
</body>
总结:
键盘上的每个按键都有自己的名称和编码,例如:Enter(13)。而Vue还对一些常用按键起了别名方便使用
Vue中常用的按键名:
- 回车:enter
- 删除:delete
- 退出:src
- 换行: tab(必须结合keydown使用)
- 上:up
- 下:down
- 左:left
- 右:right
注意:
- 系统修饰符:ctrl shifr alt
- 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
- 配合keydown使用:正常触发事件
- Vue.config.keyCodes.自定义键名 = 键码,可以自定义键别名
1.9、计算属性
<script src=""></script>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"><br>
名: <input tyep="text" v-model="lastName"><br>
姓名:<span>{{fullName}}</span>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三'
},
computed: {
fullName: {
get() {
return this.firstName + '-' +lastName
}
set(vaule) {
const arr = value.split('-'),
this.firstName = arr[0];
this.lastName = arr[1]
}
}
}
})
</script>
</body>
总结:
- 计算属性:
- 定义:要用的属性不存在,需要计算的来
- 原理:Object.defineProperty()
- get函数(重要):
- 当初读取时会执行一次
- 依赖数据改变时会再次调用
- 备注:
- 计算属性最后会出现在vm上
- 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发送改变
- 如果计算属性不发生修改,简写形式为:
<script>
new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三'
},
computed: {
fullName() [
return this.firstName + '-' + this.lastName
]
}
})
</script>
1.10、监视属性
1.10.1、监视属性的基本用法
<body>
<div id="root">
<h2>
今天天气好{{info}}
</h2>
<button @click="changeWeather">
点击切换天气
</button>
</div>
<script>
new Vue({
el: '#root',
data: {
isHot: true,
},
computed: {
info() {
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changeWeather() {
this.isHot = !this.isHot
}
},
watch: {
isHot: {
immdiate: true, //初始化时让handler调用一下
//当isHot改变时会调用
handler(newVaule,oldValue) {
console.log(newValue,oldValue)
}
}
}
})
</script>
</body>
总结:
- 当监视的属性被变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视
- 两种写法:
- 同上
- 同下:
vm.$watch('isHot',{
immediate:true,
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
})
1.10.2、深度监视
- 深度监视:
- Vue中的watch默认不监视对象内部的值
- 改变:deep: true
<body>
<div id="root">
<h3>
a的值为:{{number.a}}
</h3>
<-->简单的代码可以这样操作</-->
<button @click="number.a++">
点我a加 1
</button
<h3>
b的值为:{{number.b}}
</h3>
<button @click="number.b++">
点我b加 1
</button>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
number: {
a:1,
b:2,
}
},
watch: {
number: {
deep: true,
handler() {
console.log('number改变了')
}
}
}
})
</script>
</body>
1.10.4、监听属性 vs 计算属性
- computed和watch之间的区别:
- computed可以完成的东西,watch都可以完成
- 但是watch可以完成的东西,computed不一定能完成,如:watch可以进行异步操作
- 两个重要原则:
- 所有被Vue管理的函数,最好写出普通函数
- 不被Vue管理的函数,最好写出箭头函数,如:计算器
使用计算属性:
<body>
<div id="root">
姓:<input type='text' v-model='firstName'>
名:<input type='text' v-model='lastName' >
姓名:{{fullname}}
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
firstName = '张',
lastName = '三'
},
conputed: {
fullName: {
get() {
return this.firstName + this.lastName;
}
set(value) {
let arr = fullName.split('-');
this.firstName = arr[0];
this.lastName = arr[1];
}
}
},
})
</script>
</body>
使用监视属性:
<script>
new Vue({
el: '#root',
data: {
firstName: '张',
lastName: '三',
fullName: '张-三'
},
watch: {
firstName: {
handler(val) {
setTimeout(()=>{
this.fullName = val + '-' + lastName;
},1000)
},
lastName: {
handler(val) {
this.fullName = this.firstName + '-' + val;
}
}
}
}
})
</script>
1.11、绑定样式
写法:
<body>
<div id="root">
绑定class样式--字符串写法,通用于类名不确定,需要动态指定
<div class="basic" :class="mood"' @click="changeMood"></div><br>
绑定class样式--数组写法,适用于:要绑定的样式个数不确定,
<div class="basic" :class="classArr"></div><br>
绑定class样式---对象写法,适用于:要绑定的样式个数不确定、名字确定
<div class="basic" :class="classObj"></div><br>
绑定style样式--对象写法
<div class="basic" :style="styleObj"></div><br>
绑定style样式--数组写法
<div class="basic" :style="styleArr"></div><br>
</div>
</body>
总结:
-
class样式:
- 写法:
class="xxx"
,xxx可以是字符串、对象、数组 - 字符串写法适用于:类名不确定,要动态获取
- 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定
- 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用
- 写法:
-
style样式:
:style="{fontSize: xxx}"
其中xxx是动态值:style="[a,b]"
其中a、b是样式对象
1.12、条件渲染
- v-if:
- 写法:
- v-if
- v-else-if
- v-else
- 写法:
- v-show:
- 写法:
- v-show=“表达式”
- 写法:
<body>
<div id="root">
<h2 v-show="true">
hello
</h2>
<div v-if="2===1"></div> <br>
<div v-else-if="3===1"></div> <br>
<div v-else></div>
</div>
</body>
1.13、列表渲染
1.13.1、基本列表
v-for
<body>
<div id="root">
<h2>人员列表(遍历数组)</h2>
<ul>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}}
</li>
</ul>
<h2>汽车信息(遍历对象)</h2>
<ul>
<li v-for="(value,k) in car" :key="k">
{{k}}-{{value}}
</li>
</ul>
<h2>遍历字符串</h2>
<ul>
<li v-for="(char,index) in str" :key="index">
{{char}}-{{index}}
</li>
</ul>
<h2>遍历指定次数</h2>
<ul>
<li v-for="(number,index) in 5" :key="index">
{{index}}-{{number}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:20}
],
car:{
name:'奥迪A8',
price:'70万',
color:'黑色'
},
str:'hello'
}
})
</script>
</body>
</html>
总结:
v-for指令:
- 用于展示列表数据
- 语法:
- ,key既可以是index,也可以是遍历数组的唯一标识
- 可遍历:数组、对象、字符串、指定次数
1.13.2、key的作用与原理
<body>
<div id="root">
<h2>人员列表</h2>
<button @click.once="add">添加老刘</button>
<ul>
<li v-for="(p,index) in persons" :key="index">
{{p.name}} - {{p.age}}
<input type="text">
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:20}
]
},
methods: {
add(){
const p = {id:'004',name:'老刘',age:40}
this.persons.unshift(p)
}
},
})
</script>
</html>
1.13.3、列表过滤
<body>
<div id="root">
<h2>
人员列表
</h2>
<input type="text" v-model="keyWord">
<ul>
<li v-for="(p,index) of filPersons" :key="index"></li>
{{p.name}} - {{p.age}} - {{p.sex}}
</ul>
</div>
<script>
new Vue({
el: '#root',
data: {
keyWord: '',
persons: [
{id:'001',name:'马冬梅',age:19,sex:'女'},
{id:'002',name:'周冬雨',age:20,sex:'女'},
{id:'003',name:'周杰伦',age:21,sex:'男'},
{id:'004',name:'温兆伦',age:22,sex:'男'}
]
},
computed: {
filPersons() {
return this.person.filter((p) => {
return p.name.indexOf(this.keyWord) !== -1;
}
}
}
})
</script>
</body>
注意:在Vue修改数组请用下面方法:
- 使用这些API:**push() \ pop() \ shift() \ splice() \ sort() \ reserse() **,这些才会更新,用[]不会,但是vue3可以
1.15、过滤器
- 定义:对要显示的数据进行特定格式化处理后再显示
- 语法:
- 注册过滤器:
Vue.filter(name,callback)
或new Vue{filters:{}}
- 使用过滤器:
{{ xxx | 过滤器名}}
或v-bind:属性 = "xxx | 过滤器名"
- 注册过滤器:
具体使用请看视频
1.16、内置指令
v-model | 双向数据绑定 |
---|---|
v-on | 监听事件 |
v-bind | 单项数据绑定 |
v-text | 插入文本内容 |
v-html | 插入包含html的文本内容 |
v-for | 列表渲染 |
v-if | 条件渲染 |
v-show | 显示隐藏 |
v-text:
v-text
会替换掉节点中的内容,但是{{xx}}
则不会
v-html:(有安全隐患)
v-html
会替换掉节点中所有的内容,但是{{xx}}
则不会v-html
可以识别html结构
v-clock指令
- 没有值:
{{name}}
- 配合css解决配速慢的问题
- 一个特殊值,Vue实例创建完毕后,会删掉v-clock
v-once指令
- v-所在节点在初次渲染后,就视为静态内容
<div id="root">
<h2 v-once>
n的值为{{n}}
</h2>
<h2>
n现在的值为{{n}}
</h2>
<button @click="n++">
点我n+1
</button>
</div>
v-pre
-
可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译
-
Vue其实很简单
1.17、自定义指令
-
局部指令:
<script> new Vue({ directives: {指令名:配置对象} }) </script>
<script> new Vue({ directives: {指令名:回调函数} }) </script>
-
全部指令:
- Vue.directive(指令名,配置对象)
- Vue.directive(指令名,回调函数)
<script>
Vue.directive('find',{
//指令与元素一上来就绑定成功
bind(element,binding){
element.value = bind.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()
}
//指令所在的模板被重新加载时
update(element,binding) {
element.value = binding.value
}
})
</script>
- 配置对象中常用的3个回调函数
bind(element,binding)
:指令与元素成功绑定时调用inserted(element,binding)
:指令所在元素被插入页面时调用update(element,binding)
:指令所在模板结构被重新解析时调用
- 注意:
- 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名
1.18、生命周期
总结:
常用生命周期钩子:
mounted
:发送ajax请求、启动定时器、绑定自定义事件、订阅消息等初始化操作beforeDestroy
:清除定时器、解绑自定义事件、取消订阅消息等收尾工作