Vue的基本概念
Vue知识掌握目标
Vue基础知识
Vue全家桶(vue/vue-router/vuex/axios)
组件化开发
webpack - 前端模块化打包构建工具
ES6 - ECMAScript 6 入门
Vue项目开发
Vue介绍
- vue 中文网
- Vue.js 是什么
- Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。
- 建议:通读一遍Vue官网教程中的基础内容
Vue: 是一个渐进式的javascript框架
- 渐进式:Vue不要求整个全部用Vue的全家桶来开发
- 你可以把Vue当成一个小工具来使用,发现Vue好用了,慢慢的把Vue整个框架全部用进来。
库和框架的概念
Library
库,本质上是一些函数的集合。每次调用函数,实现一个特定的功能
- 代表:jQuery
- 使用库的时候,把库当成工具使用,需要自己控制代码的执行逻辑。
Framework
框架,是一套完整的解决方案,使用框架的时候,需要把你的代码放到框架合适的地方,框架会在合适的时机调用你的代码
- 框架规定了自己的编程方式,是一套完整的解决方案
- 使用框架的时候,由框架控制一切,我们只需要按照规则写代码
库和框架的区别
- 使用库的时候,很自由,只要调用库提供的各种各样的方法就行,也可以不用其他的一些方法
- 使用框架的时候,需要按照框架的规则写代码,限制会非常多,但同时框架的功能也很强大,可以极大的提升开发的效率。
MVVM的概念
参考资料:从Script到Code Blocks、Code Behind到MVC、MVP、MVVM
后端的MVC架构模式
MVC是一种软件架构模式,也有人叫做设计模式
- M: Model 数据模型(专门用来操作数据,数据的CRUD)
- V:View 视图(对于前端来说,就是页面)
- C:Controller 控制器(是视图和数据模型沟通的桥梁,用于处理业务逻辑)
vue是MVVM框架
MVVM,一种更好的UI模式解决方案
- M:model数据模型(ajax获取到的数据)
- V:view视图(页面)
- VM:ViewModel 视图模型
MVC vs MVVM
- MVC模式,将应用程序划分为三大部分,实现了职责分离,需要自己实现controller的代码,需要操作DOM
- MVVM通过
数据双向绑定
让数据自动地双向同步- V(修改视图) -> M(数据自动同步)
- M(修改数据) -> V(视图自动徒步)
Vue中的MVVM
虽然没有完全遵循 MVVM 模型,Vue 的设计无疑受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的简称) 这个变量名表示 Vue 实例
注意:
1. 在vue中,不推荐直接手动操作DOM!!!
2. 在vue中,通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!
Vue初体验
基本使用步骤
安装:
npm install vue
引入vue.js->创建vue实例->实例挂载到DOM
注意:开发期间使用未压缩版vue.js!!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 3.可以通过{{}}显示vue中的数据 -->
<h1>{{ msg }}</h1>
</div>
<!-- 1. 引入vue.js -->
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
// 2. createApp() 创建vue实例
const app = Vue.createApp({ // 根组件
// data 选项是一个函数。Vue 在创建新组件实例的过程中调用此函数。它应该返回一个对象
// Vue 会通过响应性系统将其包裹起来,并以 $data 的形式存储在组件实例中
// data 提供了vue中使用的数据
data(){
return {
msg:'hello vue'
}
}
})
// 3. mount() 挂载应用,该组件被用作渲染的起点
const vm = app.mount('#app')
window.vm = vm // 非必要,仅为了便于在浏览器控制台中通过vm调试vue实例
</script>
</body>
</html>
问题1:把{{msg}}
写到div#app
外能生效么?
插值表达式
插值表达式:{{ }}
也叫Mustache语法,小胡子语法,因为长得像胡子
- 解释:使用
{{ }}
(插值表达式)从data
中获取数据,并展示在模板中 - 说明:
{{ }}
中只能出现JavaScript表达式 - 说明:数据对象的属性值发生了改变,插值处的内容都会更新
- 注意:插值表达式不能用在html的属性上
<body>
<div id="app">
<p>我的自行车的牌子: {{ car.brand }} 价钱是:{{ car.price + 100 }}</p>
<p>{{ 1 + 1 }}</p>
<p>{{ car.price >= 1000 ? '卖了' : '留着' }}</p>
<p>{{ msg.toUpperCase() }}</p>
<!-- 1. 不能使用data不存在的变量 -->
<!-- <p>{{hello}}</p> -->
<!-- 2. 在插值表达式中不能出现语句 -->
<!-- <p>{{ if(car.price >= 100){} }}</p> -->
<!-- 3. 插值表达式不能用在html的属性上 -->
<!-- <h1 title="{{ msg }}"></h1>-->
</div>
<!-- 1. 引入vue.js -->
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
// 2. createApp() 创建vue实例
const app = Vue.createApp({
// data 提供了vue中使用的数据
data() {
return {
msg: 'hello',
car: {
brand: '小黄车',
price: 1000
}
}
}
})
// 3. mount() 挂载应用,该组件被用作渲染的起点
const vm = app.mount('#app')
window.vm = vm // 非必要,仅为了便于在浏览器控制台中通过vm调试vue实例
</script>
</body>
vue指令
- 解释:指令 (Directives) 是带有
v-
前缀的特殊属性,可以在html标签中使用,可以看成特殊的html属性 - 作用:指令提供了一些特殊的功能,当指向绑定到标签上时,可以给标签增加一些特殊的行为
v-bind指令
- 描述:插值表达式不能用在html的属性上,如果想要动态的设置html元素的属性,需要使用v-bind指令
- 作用:动态的设置html的属性
- 语法:
v-bind:title="msg"
- 简写:
:title="msg"
<!-- 指令中的值 不是一个字符串,而是data中的数据 变量 -->
<!-- 指令中也是可以出现表达式 -->
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
v-model指令
v-model: https://v3.cn.vuejs.org/guide/forms.html
- 作用:在表单元素上创建双向数据绑定
- 说明:监听用户的输入事件以更新数据
<body>
<div id="app">
<!-- v-model 数据双向绑定 -->
<!-- 视图改变,数据跟着改变 -->
<!-- 数据改变,视图跟着改变 -->
<input type="text" v-model="msg" placeholder="edit me">
<p>Message is: {{ msg }}</p>
</div>
<!-- 1. 引入vue.js -->
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
// 2. createApp() 创建vue实例
const app = Vue.createApp({
// data 提供了vue中使用的数据
data() {
return {
msg: ''
}
}
})
// 3. mount() 挂载应用,该组件被用作渲染的起点
const vm = app.mount('#app')
window.vm = vm // 非必要,仅为了便于在浏览器控制台中通过vm调试vue实例
</script>
</body>
<body>
<div id="app">
<h3>input框数据绑定</h3>
<!-- 忽略value属性 -->
<input type="text" v-model="msg">
<p>input框绑定的数据:{{ msg }}</p>
<h3>textarea文本框数据绑定</h3>
<textarea cols="30" rows="10" v-model="posts"></textarea>
<p>textarea绑定的数据:{{ posts }}</p>
<h3>checked框数据绑定</h3>
<input type="checkbox" v-model="isChecked">
<p>checked绑定的数据:{{ isChecked }}</p>
<h3>select框数据绑定</h3>
<select v-model="city">
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">深圳</option>
<option value="4">广州</option>
</select>
<p>select框绑定的数据:{{ city }}</p>
</div>
<!-- 1. 引入vue.js -->
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
// 2. createApp() 创建vue实例
const app = Vue.createApp({
// data 提供了vue中使用的数据
data() {
return {
msg: '',
posts: '',
isChecked: true,
city: 2
}
}
})
// 3. mount() 挂载应用,该组件被用作渲染的起点
const vm = app.mount('#app')
window.vm = vm // 非必要,仅为了便于在浏览器控制台中通过vm调试vue实例
</script>
</body>
双向数据绑定
- 双向数据绑定:将DOM与Vue实例的data数据绑定到一起,彼此之间相互影响
- 数据的改变会引起DOM的改变
- DOM的改变也会引起数据的变化
- 原理:数据劫持,
Object.defineProperty
中的get
和set
方法getter
和setter
:访问器- 作用:指定
读取或设置
对象属性值的时候,执行的操作
- 注意:
Object.defineProperty
方法是ES5中提供的,IE8浏览器不支持这个方法。因此,Vue不支持IE8及其以下版本浏览器 - Vue - 深入响应式原理
- MDN - Object.defineProperty()
Vue双向绑定的极简实现
<!-- 示例 -->
<input type="text" id="txt" />
<span id="msgBox"></span>
<script>
const txt = document.getElementById('txt')
const msgBox = document.getElementById('msgBox')
const obj = {}
// 给对象obj添加msg属性,并设置setter访问器
Object.defineProperty(obj, 'msg', {
// 设置 obj.msg 执行的操作
set: function (curVal) {
txt.value = curVal
msgBox.innerText = curVal
}
})
// 监听文本框的改变
txt.addEventListener('input', function (event) {
obj.msg = this.value
})
</script>
v-on指令
事件处理: https://v3.cn.vuejs.org/guide/events.html#监听事件
- 作用:绑定事件
- 语法:
v-on:事件名=事件处理函数
,如v-on:click="say"
orv-on:click="say('参数', $event)"
- 简写:
@click="say"
- 说明:绑定的事件从
methods
中获取
<body>
<div id="app">
<!-- v-on:事件名=事件处理函数 或 @事件名=事件处理函数-->
<button v-on:click="clickFn" @mouseenter="enterFn">按钮</button>
</div>
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
// data 提供了vue中使用的数据
data() {
return {}
},
// methods 对象: 提供vue中使用到的方法
methods: {
clickFn() {
console.log('点击了按钮!')
},
enterFn() {
console.log('鼠标指针穿过按钮')
}
}
})
const vm = app.mount('#app')
window.vm = vm
</script>
</body>
- 跑马灯案例
<body> <div id="app"> <button @click="start">走</button> <button @click="stop">停</button> <h1>{{ msg }}</h1> </div> <script src="./node_modules/vue/dist/vue.global.js"></script> <script> const app = Vue.createApp({ // data 提供了vue中使用的数据 data() { return { msg: '萨瓦迪卡,欢迎大家,欢迎大家来到美丽的泰国!', timeId: '' } }, // methods 对象: 提供vue中使用到的方法 methods: { start() { // 如果有定时器在跑, 直接返回 if (this.timeId) return // 开启一个定时器,每次让msg的第一个字符串放到最后一个 this.timeId = setInterval(() => { let first = this.msg.charAt(0) this.msg = this.msg.slice(1) + first }, 300) }, stop() { clearInterval(this.timeId) // 把timeId的值清空 this.timeId = '' } } }) const vm = app.mount('#app') window.vm = vm </script> </body>
箭头函数的使用场景
() => {
}
当不想使用指向自身的this时,可以使用箭头函数。
如上方例子中定时器中,如果使用普通函数,这内部的this指向定时器自身window,无法使用vue实例中的this.msg
一般箭头函数用在 定时器 中,以及数值的一系列方法 forEach
,map
,filter
中
事件传参
v-on 注册事件的时候,如果需要传递参数,怎么办?
- @click=”事件函数”
- @click=”事件函数(参数)”
- 如果写了函数调用的方式,没办法获取事件对象,想要获取事件,显式的传入$event
<body> <div id="app"> <!-- @click="clickFn" : 没办法传参数,第一个参数就是事件对象 --> <!-- vue中注册事件,允许直接通过函数调用的方式传递参数 --> <!-- 如果写了函数调用的方式,没办法获取事件对象,想要获取事件,显示的传入$event --> <!-- @click="clickFn(1, 2, $event)" : 可以传参数 --> <button @click="clickFn(1, 'Milton', $event)">注册事件</button> </div> <script src="./node_modules/vue/dist/vue.global.js"></script> <script> const app = Vue.createApp({ // data 提供了vue中使用的数据 data() { return {} }, // methods 对象: 提供vue中使用到的方法 methods: { clickFn(id, name, e) { // 1. 如何获取事件对象, 直接给函数提供一个形参e // 2. 将来注册事件,经常需要传递一些参数,vue注册事件传参问题 console.log('id:', id) console.log('name:', name) console.log('event:', e) } } }) const vm = app.mount('#app') window.vm = vm </script> </body>
事件修饰符
@事件名.事件修饰符=“事件函数”
.stop
阻止冒泡,调用 event.stopPropagation().prevent
阻止默认行为,调用 event.preventDefault().capture
添加事件侦听器时使用事件捕获
模式.self
只当事件在该元素本身(比如不是子元素)触发时,才会触发事件.once
事件只触发一次
<body>
<div id="app">
<!-- prevent:阻止浏览器默认行为 -->
<!-- stop:阻止事件冒泡 -->
<!-- self: 只有自己才能出发 -->
<!-- capture: 捕获阶段触发事件 -->
<!-- once: 保证事件只触发一次 -->
<div class="father" @click.self="fatherFn" style="width: 100px;height: 100px;background: pink">
<!-- @事件名.事件修饰符 = "事件处理程序" -->
<!-- 注册事件经常需要阻止冒泡 阻止浏览器默认行为 -->
<a @click.prevent="clickFn" href="http://www.baidu.com">点我一下,有惊喜</a>
</div>
</div>
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
// data 提供了vue中使用的数据
data() {
return {}
},
// methods 对象: 提供vue中使用到的方法
methods: {
clickFn() {
console.log('监听子元素的点击事件函数')
},
fatherFn() {
console.log('监听父元素的点击事件函数')
}
}
})
const vm = app.mount('#app')
window.vm = vm
</script>
</body>
按键修饰符
在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on
在监听键盘事件时添加按键修饰符:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
<body>
<!--
当按了回车键的时候,把msg打印出来
@事件名.事件修饰符或者按键修饰符
.prevent .stop .enter .esc .tab
.enter
.esc
.tab
-->
<div id="app">
<input type="text" @keyup.enter="fn" v-model="msg">
</div>
<script src="./node_modules/vue/dist/vue.global.js"></script>
<script>
const app = Vue.createApp({
// data 提供了vue中使用的数据
data() {
return {
msg: ''
}
},
// methods 对象: 提供vue中使用到的方法
methods: {
fn() {
console.log(this.msg)
}
}
})
const vm = app.mount('#app')
window.vm = vm
</script>
</body>
第一天学习总结
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。