Vue的mvvm模式:
这个图一定得记下来
view,viewmodel,model三个层面
let vm = new Vue({
el: "#hsy",
data: {
age: 20,
name: "林之皓",
message: "小胖子"
}
});
- 在 Vue.js 中,
data
是 ViewModel 的一部分,因为它是存储应用程序状态和业务逻辑的地方,并且与视图(View)绑定,视图会自动更新以反映data
中的数据变化。 data
:这是 Vue 实例的一个属性,用来存储应用的状态数据。它是 ViewModel 的一部分。el
:这是 Vue 实例的另一个属性,指定了这个 Vue 实例要控制的 DOM 元素,它定义了 View 的根元素。
两种方式可以将数据绑定到 HTML 元素属性上:
- 使用
v-bind
指令 - 使用差值表达式
{{ }}
***:如果是在标签\元素 的属性上去引用data数据池数据时,不能使用插值表达式
需要使用v-bind, v-bind :src = :src 这两种方式都可以
数据的单向绑定:
单向绑定则相对简单一些。它指的是数据流只能从数据模型流向界面元素,而不能反过来。也就是说,当数据模型中的数据发生变化时,界面元素会自动更新。但是,在界面元素上的修改不会影响到数据模型。
单向绑定适用于一些纯展示类的场景,比如图片的 src
属性、文本内容等。开发者只需要绑定好数据源,不需要关心界面元素的修改会不会影响到数据。
<div id="hsy">
<img v-bind:src="image_path">//这两种写法都可以
<img :src="image_path">// :src 和 v-bind :src是等效的,简写而已
</div>
<script>
let vm = new Vue({
el : "#hsy",
data : {
age: 20,
name : "林之皓",
message : "小胖子",
image_path : "./001.png"
}
})
</script>
数据的双向绑定:
指的是数据和界面元素之间是互相影响的关系。当你在界面元素上输入或修改数据时,背后的数据模型也会自动更新。同时,当数据模型中的数据发生变化时,界面元素也会自动更新。
<div id ="hsy">
<h1>{{name}},输入你的兴趣爱好:</h1>
<!--数据的双向绑定-->
<input type="text" v-model="hobby.reading"><br><br>
<input type="text" v-bind:value="hobby.reading">
<!--<input type="text" :value="hobby.reading">-->
<img v-bind:src="image_path" :width="image_width" >
</div>
<script>
let vm = new Vue({
el : "#hsy",
data : {
age: 20,
name : "林之皓",
message : "小胖子",
image_path : "./001.png",
image_width : "200px",
hobby:{
reading : "读书",
coding : "编程",
traving : "旅行"
}
}
})
</script>
常用的v-on的事件绑定有:
-
鼠标事件:
click
: 点击事件dblclick
: 双击事件mousedown
: 鼠标按下事件mouseup
: 鼠标释放事件mousemove
: 鼠标移动事件mouseover
: 鼠标移入事件mouseout
: 鼠标移出事件
-
键盘事件:
keyup
: 键盘按键释放事件keydown
: 键盘按键按下事件keypress
: 键盘按键按下并释放事件
-
表单事件:
submit
: 表单提交事件focus
: 获得焦点事件blur
: 失去焦点事件change
: 值改变事件input
: 输入事件
-
生命周期事件:
mounted
: 组件挂载完成事件updated
: 组件更新完成事件beforeDestroy
: 组件销毁前事件
-
其他事件:
scroll
: 滚动事件resize
: 窗口大小改变事件load
: 资源加载完成事件
触发一个方法的事件绑定
两个步骤:
1.创建vue对象之后,在methods池里面去创建我们的方法,切记别在data池里面写了,写错了会报错
<script>
let vm = new Vue({
el : "#hsy",
data : {
age: 20,
},
//这里就是方法池
methods: {
Click_001() {
console.log('触发方法池里面的方法:');
}
}
})
</script>
2.就是在我们的对应的标签上面去添加 :v-on-click
<button v-on:click="Click_001">触发方法click</button>
关于v-on-click的简写方式:这两种都可以,但下面这种要浏览器的版本高些
细节提醒:如果要访问当前Vue实例的数据池的数据,需要this//否则,会报错ReferenceError:bookName is not defined,
比如:当我methods池里面的方法要用到data池里面的某一个数据 data_001,此时就要this.data_001,否则会出问题
修饰符:
修饰符的作用是用来增强或改变指令的行为,让指令能更好地满足开发需求。
修饰符分为:
-
事件修饰符
- 可以改变事件的默认行为,比如阻止事件冒泡、阻止默认事件等。
-
表单修饰符
- 可以自动处理表单数据,比如去除两端空格、将输入转为数字等。
-
系统修饰符
- 可以限制只有在按下特定按键时才触发指令,比如只有按下
enter
键时才提交表单。
- 可以限制只有在按下特定按键时才触发指令,比如只有按下
看代码:
<form v-on:submit.prevent.trim="handleSubmit">
//简写:<form @:submit.prevent.trim="handleSubmit">
<input v-model.trim="formData.name" type="text" placeholder="输入名称" />
<button type="submit">提交</button>
</form>
代码解释:
-
v-on:submit.prevent.trim="handleSubmit"
:v-on:
用于绑定事件监听器----------->这个可以简写成“@”.修饰符(1):prevent
修饰符用于阻止表单的默认提交行为.修饰符(2):trim
修饰符用于自动过滤输入框两端的空白字符"修饰符(3):handleSubmit"
是要绑定的方法名,如果我不正常表单提交,我就去相应的 vue的methods池去找 方法名 相同的方法(不走默认提交)- 在 Vue.js 中,修饰符可以被直接链式添加在指令后面,执行顺序从左到右
-
v-model.trim="formData.name"
:v-model
用于双向绑定表单元素的值.trim
修饰符用于自动过滤输入框两端的空白字符
关于简写的说明:
@
简写只能用于事件绑定,比如@click="handleClick"
等。- 对于其他指令,比如
v-model
、v-if
等,是不能使用@
简写的。
条件渲染:v-if v-else 和 v-show
v-if实例:
我们的这里的v-if="变量名" ,代码运行到这里,会去数据池里面看一下 有没有对应的 变量名
,然后看这个变量 的 值 :是不是为真,为真就执行,该条标签。
v-else和v-if同时出现的话,相当于v-if的变量值为:false时候,就立马执行v-else,只有v-if的时候,那么就是执行和不执行的区别。
<div id="app">
<h2>v-if 示例</h2>
<button @click="showMessage = !showMessage">切换消息显示</button>
<p v-if="showMessage">这是一条重要的消息!</p>
</div>
<script>
new Vue({
el: '#app',
data: {
showMessage: true
}
})
</script>
v-show的条件渲染
这个也可以实v-if-else的功能:
<div id="app">
<h2>v-show 示例</h2>
<button @click="showMessage = !showMessage">切换消息显示</button>
<p v-show="showMessage">这是一条重要的消息!</p>
</div>
<script>
new Vue({
el: '#app',
data: {
showMessage: true
}
})
</script>
看上面的代码:showMessage的变量值,为true的时候,就执行该标签,为false就不执行。
v-if-else和v-show的区别:前者的开销成本很大,
v-if
有更高的切换开销,因为它会根据条件完全地销毁和重建元素,v-if
适用于需要根据条件完全地渲染或销毁元素的场景v-show
则更适用于需要频繁切换显示/隐藏的场景v-else
则用于简化条件判断的代码。
v-for遍历一个数组:
解释:"fruit in fruits" "fruit"这个类似于临时变量,是我们自己取的别名,"in"类似于关键字,“fruits”这个很重要,这个直接是一个数组(对象),必须你下面的data池里面有这个名字,一模一样的写上去才行。
遍历的时候就直接: 临时变量名.属性名 就可以遍历出对应的 属性了
<ul>
<li v-for="fruit in fruits" :key="fruit.id">
<h3>{{ fruit.name }}</h3>
<p>Taste: {{ fruit.taste }}</p>
</li>
</ul>
<script>
new Vue({
data: {
fruits: [
{ id: 1, name: 'Apple', taste: 'sweet' },
{ id: 2, name: 'Banana', taste: 'creamy' },
{ id: 3, name: 'Orange', taste: 'sour' }
]
}
})
</script>
插入一个知识盲区:数组创建过后里面的对象[ ]包围的, 对象创建过后里面的属性用{ }这个包围
//对象
const myObject = {
name: 'John Doe',
age: 35,
email: 'john.doe@example.com'
};
//数组
const myArray = ['apple', 'banana', 'cherry'];
遍历一个对象:
这个要先理解:对象本质就是有属性,属性是以键值对来遍历的,所以我们遍历的时候就按照别人的语句:
<div v-for="(value, key) in 对象名" :key="key">
{{ key }}: {{ value }}
</div>
这里的value就是代表键,key就是值,建议别改名字,改名字的话下面的插值表达式也需要改
<div v-for="(001, 002) in myObject" :key="002">
{{ 002 }}: {{ 001 }}
</div>
我个人理解:把value,key还有一个Index都理解成官方的关键字好些:
当我们对一个对象,进行三个参数的遍历,value,key,index
data() {
return {
myObject: {
name: 'John Doe',
age: 35,
email: 'john.doe@example.com'
}
}
}
-----------分割线--------------
//遍历三个参数
<div v-for="(value, key, index) in myObject" :key="index">
{{ index }}. {{ key }}: {{ value }}
</div>
在 Vue.js 中,v-for="i in x"
的用法就是重复渲染 x
次对应的 HTML 元素。
<li v-for="(i,index) in 3">{{ i }}-{{ index }}</li>
1-0
2-1
3-2
在渲染时同时获取到元素的值和索引
组件化编程VUE
组件化编程优点:提高代码复用性、增强可维护性、方便测试
全局组件:
定义一个全局组件,名称为counter, 表示就是我们的组件相关的内容;template 指定该组件的界面,因为会引用到数据池的数据,所以需要是模板字符串;要把组件视为一个Vue实例,也有自己的数据池和methods ;对于组件,我们的数据池的数据、是使用函数|方法返回[目的是为了保证每个组件的数据是独立]
Vue.js 中全局 组件Vue 实例的数据定义格式:代码区别,方法区的data池变成了一个data函数,区别如下:
new Vue({
el: '#app',
data: { //区别就是这里----------------
count: 0
},
methods: {
increment() {
this.count++
}
}
})
//--------------------分割线-------------------
new Vue({
el: '#app',
data() { //------------这里变成了函数,且定义的对象必须要有 return
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
})
全局组件的实例代码:
template翻译成:组件模版
注册名和下面的 局部组件的 注册名一样:不能使用中文,或者数字开头,最好中间用 - - - 连字符区分开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Global Component Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<注册名></注册名>
</div>
<script>
// 注册全局组件
Vue.component('注册名', {
//这里有个细节需要注意,这里有的template属性后面跟了一个 “模版字符串”
template: `
<div>
<p>点击了 {{ count }} 次</p>
<button @click="increment">点击我</button>
</div>
`,
data: function() {
return {
count: 0
};
},
methods: {
increment: function() {
this.count++;
}
}
});
// 创建 Vue 实例
new Vue({
el: '#app'
});
</script>
</body>
</html>
为什么要改成一个data函数?---------确保每个组件实例都有自己独立的数据状态。有了return,就类似于new一样,防止了组件实例不会共享同一个数据对象,也就不会导致数据污染的问题。
局部组件:
1定义,2注册,3使用(放在1,2前面)
其次:使用的位置需要放在 定义 和 注册 的前面,先确保HTML页面的dom元素都加载完毕,在去运行Script里面的待明确
局部组件实例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Local Component Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<注册名></注册名>
</div>
<script>
// 定义局部组件
var 定义名 = { //第一个是vue的组件定义名,可以中文
template: '<div>This is a local component.</div>'
};
//局部组件的本质:就是创建vue实例的时候,在内部声明一个组件components,
new Vue({
el: '#app',
components: {
'注册名': 定义名
//第二个,冒号前面是vue的组件注册名,不可以中文,不能数字开头,注册名是讲究人
//记忆:先定义,后注册,再使用,注册名屁事多
}
});
</script>
</body>
</html>
vue的生命周期:
补充一点知识:页面加载和页面渲染的区别
页面加载就好比你点击了一个网页链接,这个动作会触发浏览器向服务器请求并下载这个网页的所有内容,包括HTML、CSS、JavaScript、图片等资源。就像是你在网上购买一件商品,这个过程就是把需要的商品从仓库运送到你的家里。
而页面渲染则是浏览器将下载好的网页资源进行处理和组装,形成最终在屏幕上呈现给你看的内容。就像是你把买回来的商品从包装盒里拿出来,并按照说明书把它们摆放好、组装好,让它们能正常工作起来。
也就是说,页面加载是把网页的原材料(资源)下载到你的电脑上,而页面渲染则是浏览器根据这些原材料将网页内容真正展现出来。
加载只是完成了资源的获取,而渲染则是完成了内容的呈现。
6个钩子函数:
-
beforeCreate()
- 可以获取的数据: 无
- 加载的内容: 无
- 通常用途: 很少使用。可以用于设置一些初始化的操作,但不涉及DOM或数据。
-
created()
- 可以获取的数据: 响应式数据(data)、计算属性、方法、侦听器
- 加载的内容: Vue实例
- 通常用途: 初始化数据,发送AJAX请求,添加一些事件监听器
-
beforeMount()
- 可以获取的数据: 同created
- 加载的内容: 模板编译完成,虚拟DOM已创建
- 通常用途: 在DOM被挂载之前做一些准备工作
-
mounted()
- 可以获取的数据: 所有数据和DOM元素
- 加载的内容: 真实DOM已创建并挂载到页面
- 通常用途: 访问和操作DOM,初始化需要DOM的库(如图表库),执行依赖DOM的操作
-
beforeUpdate()
- 可以获取的数据: 更新前的数据
- 加载的内容: 更新前的DOM
- 通常用途: 在数据更新导致虚拟DOM重新渲染之前访问现有的DOM
-
updated()
- 可以获取的数据: 更新后的数据
- 加载的内容: 更新后的DOM
- 通常用途: 执行依赖于DOM的操作,但要小心避免无限更新循环
个人记忆:记忆一共6个钩子,然后记忆dom对象的预加载和使用。还有更新了但是不现实dom的那个
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue生命周期钩子函数示例</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>{{ title }}</h1>
<p>{{ message }}</p>
<button @click="updateMessage">更新消息</button>
</div>
<script>
new Vue({
el: '#app',
data: {
title: 'Vue生命周期钩子函数',
message: '初始消息'
},
computed: {
computedProperty() {
return this.message + ' (计算属性)'
}
},
methods: {
updateMessage() {
this.message = '更新后的消息'
},
logData(hookName) {
console.log(`${hookName}:`)
console.log(' data:', this.$data)
console.log(' computed:', this.computedProperty)
console.log(' DOM:', this.$el)
}
},//--------------这里代码的位置是:是在方法池后面写,别写错了
beforeCreate() {
console.log('beforeCreate 钩子触发')
this.logData('beforeCreate')
},
created() {
console.log('created 钩子触发')
this.logData('created')
},
beforeMount() {
console.log('beforeMount 钩子触发')
this.logData('beforeMount')
},
mounted() {
console.log('mounted 钩子触发')
this.logData('mounted')
},
beforeUpdate() {
console.log('beforeUpdate 钩子触发')
this.logData('beforeUpdate')
},
updated() {
console.log('updated 钩子触发')
this.logData('updated')
}
})
</script>
</body>
</html>
初步了解一个vue项目:里面的目录是干什么用的
vue项目代码关于简写的说明:
个人理解:导入语句就是和java中的导入没啥区别,前面是导入对象(可修改名字),后边的是路径 , Vue实例那里是:本身是键值对的形式,用来取“别名的”,但简写就直接和导入那里的import 变量名,这里呼应上。
-
导入语句:
import App from './App.vue'
: 从当前项目的./App.vue
文件中导入App
组件。import router from './router/index.js'
: 从当前项目的./router/index.js
文件中导入router
对象。- 这里的导入语句类似于 Java 中导入类的方式,从指定的路径导入需要的模块或组件。
-
Vue 配置:
Vue.config.productionTip = false
: 禁用生产环境提示,提高性能。
-
新建 Vue 实例:
new Vue({ ... })
: 创建一个新的 Vue 根实例,并进行配置。el: '#app'
: 指定 Vue 实例挂载的 DOM 元素,这里是 ID 为app
的元素。router: router
: 将之前导入的router
对象注入到 Vue 实例中。components: { App }
: 注册App
组件到 Vue 实例中,可以在模板中直接使用。
-
路由配置:
router: router
: 这里将之前导入的router
对象注入到 Vue 实例中,用于管理应用程序的路由。components: { 'App': App }
: 在路由配置中,将App
组件与路由关联起来。
符号补充:“@”
在 Vue.js 项目中,@
符号是一种别名,用于简化路径引用。
具体来说:
-
@/components/HelloWorld
@
符号在 Vue.js 项目中默认指向项目的src
目录。- 所以
@/components/HelloWorld
等同于./src/components/HelloWorld
。
对于组件化编程vue的理解:
根组件和一般组件的区别
-
位置和作用:
- 根组件通常位于应用程序的最顶层,是整个应用的入口点。
- 根组件负责管理应用程序的整体结构和布局,定义应用的主要框架。
- 一般组件则是根组件的子组件,负责更细节的功能和视图展示。
-
依赖关系:
- 根组件不依赖于任何其他组件,它是应用程序的基础。
- 一般组件则需要依赖于根组件或其他组件,才能被正确渲染和使用。
-
渲染方式:
- 根组件会被直接挂载到 DOM 中,通常挂载在
#app
这样的容器元素上。 - 一般组件则是通过根组件或其他组件的模板中进行渲染的。
- 根组件会被直接挂载到 DOM 中,通常挂载在
main.js文件代码模版
根组件App.vue代码:
路由器 router.js代码:
总结:先要有一个Vue实例,里面有三个参数,1.挂载的标签 2.根组件 3.路由器
然后分别从这三个参数所在的文件里面去配置相关的资源,最后进行页面显示
Vue组件:分为三个区域,功能:页面渲染和数据交互,1,3页面渲染 2.提供数据交互
-
template 区域:
- 这个区域用于编写组件的 HTML 模板,定义组件的结构和布局。
- 在这里可以使用 Vue.js 的模板语法,如数据绑定、指令等。
-
script 区域:
- 这个区域用于编写组件的 JavaScript 代码,定义组件的逻辑和行为。
- 在这里可以配置组件的
data
、methods
、computed
等选项。
-
style 区域:
- 这个区域用于编写组件的 CSS 样式,定义组件的视觉效果。
- 在这里可以编写 scoped 样式,使样式只作用于当前组件。
模版图:
上面这张图我们称为: 1.vue文件,这就是一个页面, 然后再1.vue文件的二号区域,我们可以导入一些组件到这个页面里面来,前提是我们已经将组件做好了
Element UI 介绍:
ElementUI 是一个基于 Vue.js 2.0 的桌面端 UI 组件库,它提供了一系列高质量的 UI 组件和丰富的功能,帮助开发者快速构建优秀的 Web 应用程序。
说白了就是一个组件的快速出厂工具,直接搜索关键词然后学着用就行。
Axios介绍:
Axios中文文档:https://javasoho.com/axios/
它的作用:Axios 是一个功能强大、易用、高性能的 HTTP 客户端库,广泛应用于各种 JavaScript 项目中,简化了网络请求的相关操作。
Axios 的主要特点包括:
-
从浏览器创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
他有点类似于promise对象,我们使用了代码重排之后的样子:
// 使用 Axios 发送 GET 请求
axios.get('/api/users')
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
// 使用 Axios 发送 POST 请求
axios.post('/api/users', {
name: 'John Doe',
email: 'john@example.com'
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});