**—
title: VUE框架学习
keywords: web
tags: [web,vue,js,html,python,flask]
categories: 前后端
top_img: /img/前后端.png
VUE框架学习
前言
解决Python web框架(如Flask)与vue渲染变量的冲突(冲突会导致vue渲染报错,网页无法显示)
导语:现在主流的Python web框架中,模板的表达式声明常见的有{{ something }}这与Vue.js的语法冲突,导致在运行如Flask的Python web框架时,会报错,前端网页无法渲染。这也是阻止我用VUE的因素,但现在阻碍消除了。后续文章有网上别的大佬的内容,如果大佬觉得不妥请用邮箱与我联系,我这边会删除
使用 Jinja2 的 raw 标签标记html代码。如下代码(在x.html里修改):
{% raw %}
<div id="app">
{{ js_var }}
</div>
{% endraw %}
基本模板语法及指令
1、插值语法
使用双大括号"{{ }}"作为插值语法来将数据绑定到HTML模板中。这样可以将Vue实例中的数据动态地渲染到页面上。类似于Django的模板语法,使用方法都是一样的,两个大括号。vue中的插值语法可以插入文本、HTML以及表达式:
- 文本插值:在vue实例中,对数据进行定义后,就可以在html模板中直接使用了。
<div id="app">
<p>{{ message }}</p>
</div>
- HTML插值
html中这样来使用,就可以使用v-html
指令,将要插入的html代码作为其值。
<div id="app">
<p v-html="message"></p>
</div>
script中的数据是这样定义的,渲染后的网页就会是加粗的内容了。
new Vue({
el: '#app',
data: {
message: '<strong>Hello, Vue!</strong>'
}
});
- 表达式插值:双大括号里除了可以是一个变量也可以使用javascript表达来进行计算和操作。下面例子中的num1和num2分别是vue实例中data里定义的两个变量。
<div id="app">
<p>{{ num1 + num2 }}</p>
</div>
2、指令语法
vue的指令语法形式上为:v-xxx,其实就是为了在html中实现各种逻辑、计算、数据绑定等各种功能。
- v-bind // 单向数据绑定
- v-model // 双向数据绑定
- v-on // 事件监听绑定
- v-show // 条件渲染
- v-if // 条件渲染
- v-else // 条件渲染
- v-for // 遍历数组、对象、字符串
(1)v-html
如果数据是一段html代码,并需要将其进行渲染,而不是当作字符串来使用,就可以使用v-html
指令,将要插入的html代码作为其值。
<div id="app">
<p v-html="message"></p>
</div>
script中的数据是这样定义的,渲染后的网页就会是加粗的内容了。
new Vue({
el: '#app',
data: {
message: 'halo TitoChan'
}
});
(2)v-bind(简写 :属性名)
v-bind
指令用于动态地绑定HTML属性。它可以将Vue实例中的数据绑定到HTML元素的属性上。语法为v-bind:属性名
或简写为:属性名
。例如,将一个src
属性绑定到Vue实例的imageURL
属性上:
<img v-bind:src="你的url 如imageURL">
//简写
<img :src="imageURL">
当imageURL
的值发生变化时,src
属性将会更新。
(3)v-on(简写 @事件名)
v-on
指令用于绑定事件监听器。它可以在DOM事件触发时执行相应的Vue实例方法或表达式。语法为v-on:事件名
或简写为@事件名
。例如,监听一个按钮的点击事件并执行doSomething
方法:
<button v-on:click="doSomething">点击我</button>
//简写
<button @click="doSomething">点击我</button>
//也可以给事件传参
<button @click="doSomething('abcde')">点击我</button>
doSomething
方法定义在methods中,当按钮被点击时,该方法将被调用。
需要注意的是:event.target.innerText
能拿到标签的值,但是调用时可以不加()
或者加($event)
常用事件修饰符:
- 阻止默认事件
// js中的阻止默认事件
e.preventDefault()
// vue
@click.prevent=“doSomething” - 阻止事件冒泡
// js中的阻止事件冒泡
e.stopPropagation()
// vue
@click.stop=“doSomething”
// 阻止冒泡、默认事件连用
@click.stop.prevent=“doSomething” - 只触发一次事件
@click.once=“showMessge”
(4)v-model
v-model
指令用于实现表单元素和Vue实例数据的双向绑定。它将表单元素的值与Vue实例中的数据进行同步。语法为v-model="数据属性"
。例如,绑定一个输入框的值到Vue实例的message
属性:
<input v-model="message">
当输入框的值改变时,message
属性的值也会相应地更新;反之亦然。
注意事项:
v-model
只能用于表单元素上,如<input>
、<textarea>
和<select>
等。- 在使用
v-model
时,Vue会根据表单元素的类型自动选择正确的方式进行数据绑定。 - 对于复选框和单选按钮,
v-model
绑定的是选中状态的值,可以通过设置value
属性来自定义绑定的值。 - 对于多选的下拉框(
<select>
),可以通过设置multiple
属性来实现多选,并使用一个数组来绑定选中的值。 - 在自定义组件中,可以通过在组件内部定义
model
选项来实现v-model
的自定义行为。
(5)v-for
v-for
指令用于循环渲染列表数据,将一个数组的元素或对象的属性重复渲染为多个元素。语法为v-for="item in 列表"
。例如,渲染一个包含数组元素的无序列表:
<ul>
<li v-for="item in items">{{ item }}</li>
</ul>
在Vue实例中,定义一个items
数组,例如items: ['Apple', 'Banana', 'Orange']
,则会渲染出三个列表项。
注意事项:
v-for
需要提供一个唯一的key
属性,以便Vue能够跟踪每个渲染的元素,以便高效地更新DOM。- 在使用
v-for
时,可以访问当前迭代的元素和索引,例如可以使用item
和index
来访问当前迭代的元素和索引。 - 可以使用对象迭代的形式,使用
v-for="(value, key) in object"
来遍历对象的属性。 - Vue会在内部尽可能地复用已有的元素,而不是完全重新渲染。因此,对于表单中有依赖关系时或有input框时,在使用
v-for
时尽量避免使用索引作为key
,而是使用具有唯一标识的属性作为key
。
key定义:为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key
。
key作用:
key
值使用数组的索引index,或者不加,在数组元素顺序打乱时,会产生不必要的DOM更新以及界面效果出问题;key
主要用在 Vue 虚拟 DOM(类似 js 对象格式的数据) 的 Diff 算法,新旧虚拟 DOM 对比,复用不变的旧节点,渲染改变的节点,提高渲染速度
<li v-for="(item,index) in obj" :key="item.id">{{item.name}}</li>
new Vue({
el: '#app',
data: {
obj: [
{ name: 'banana', id: '1' },
{ name: 'apple', id: '2' },
{ name: 'pear', id: '3' },
],
},
});
(6)v-if、v-else、v-else-if
v-if
指令用于根据条件渲染元素,如果条件为真,则渲染该元素;否则,将其从DOM中移除。v-else
和v-else-if
可以与v-if
配合使用,实现条件分支渲染。例如,根据showMessage
的值决定是否显示一个消息:
<p v-if="showMessage">显示的消息</p>
<p v-else>隐藏的消息</p>
当showMessage
为true
时,显示第一个p
元素;否则,显示第二个p
元素。
v-show
<p v-show="count===1">显示的消息</p>
注意事项:
- 可以在同一元素上使用
v-if
和v-else
来实现条件切换。 - 当条件为假时,使用
v-if
的元素将从DOM中移除,而使用v-show
的元素将隐藏但仍然保留在DOM中。因此,v-show
在需要频繁切换元素可见性时更适用。 - 当
v-if
与v-for
同时存在时,v-for
的优先级更高。所以,如果同时使用v-if
和v-for
,请确保在父元素上使用v-if
,而不是在循环的元素上使用。
上面是一些常见的Vue指令,Vue.js还提供了许多其他指令,如v-text
、v-show
、v-cloak
、v-pre
等,用于更灵活地控制DOM元素的显示和行为。可以根据需要在Vue.js的官方文档中查找更多详细信息。
3、计算属性
计算属性就是通过已定义的属性计算来的,在computed
中进行定义后,无需再在data
中定义,可以当作一个data的属性来使用,相比于methods
和watch
的函数,计算属性的值会根据依赖的响应式数据自动进行更新,并且会进行缓存,只有当依赖数据变化时才会重新计算,效率高,所以同等情况下,建议优先选用计算属性来实现。
(1)定义计算属性
在Vue实例的computed
选项中定义计算属性。在下面的代码中,fullName
是一个计算属性,根据firstName
和lastName
的值返回全名。
new Vue({
data: {
firstName: 'John',
lastName: 'Doe'
},
computed: {
fullName: function() {
return this.firstName + ' ' + this.lastName;
}
}
});
(2)使用计算属性
在Vue实例中,可以像使用普通属性一样访问和使用计算属性。可以通过在模板中插值、绑定属性或作为条件判断的依据来使用计算属性。下面的代码中,在<p>
标签中使用了计算属性fullName
进行插值,同时将计算属性绑定到输入框的值上。
<div>
<p>{{ fullName }}</p>
<input v-model="fullName">
</div>
(3)注意事项
- 计算属性是基于它们的依赖进行缓存的。只有当依赖的响应式数据发生变化时,计算属性才会重新计算。这意味着多次访问计算属性时,只有在相关的依赖数据发生改变时才会重新计算,而不是每次访问都重新计算。
- 计算属性应该是纯粹的,即不应该有副作用,不应该修改依赖数据的值。如果需要有副作用或需要进行异步操作,应该使用方法(methods)或侦听器(watch)。
- 计算属性可以依赖于其他计算属性,当依赖的计算属性发生变化时,所有依赖于它们的计算属性都会重新计算。
- 可以使用计算属性的
set
函数来实现计算属性的双向绑定,允许在修改计算属性时同时修改依赖的数据。
(4)对比方法(methods)和侦听器(watch)
- 计算属性适用于基于现有数据进行计算和处理的情况,特别是当需要根据多个数据进行复杂计算时,使用计算属性可以使代码更清晰、简洁。
- 方法适用于需要执行具有副作用的操作或涉及到参数传递的操作。
- 侦听器适用于需要观察并在数据变化时执行异步或复杂操作的情况。
- 当需要在模板中直接访问数据的结果或进行简单计算时,优先考虑使用计算属性。
- 如果需要手动触发数据处理逻辑,或者需要对数据变化进行更精确的控制和处理,可以使用方法或侦听器。
- 在性能方面,计算属性会进行缓存,只在依赖的数据发生变化时重新计算;而方法和侦听器没有缓存机制,每次调用都会重新执行。
4、监视属性
在Vue.js中,监视属性(Watch)用于观察和响应Vue实例中的数据变化,执行相应的操作。通过监视属性,可以监听指定的数据变化,并在数据变化时执行自定义的回调函数。
(1)定义监视属性
在Vue实例的watch
选项中定义监视属性。可以使用键值对的形式,其中键是要监视的属性名,值是对应的回调函数。回调函数接收两个参数:新值和旧值。例如:
new Vue({
data: {
message: 'Hello, Vue.js!',
counter: 0
},
watch: {
message: function(newValue, oldValue) {
// 在message属性变化时执行操作
this.counter++;
console.log('message的值发生了变化');
console.log('新值为:' + newValue);
console.log('旧值为:' + oldValue);
}
}
});
在上述代码中,当message
的值发生变化时,会执行回调函数并对counter
进行自增操作。
(2)使用监视属性
监视属性会在Vue实例中的指定属性发生变化时触发回调函数。可以在回调函数中执行相应的操作,例如更新数据、发送网络请求等。
(3)注意事项
- 监视属性可以监听多个属性的变化,可以在
watch
选项中定义多个键值对,也可以使用深度监视(deep
选项)来观察对象内部属性的变化。。 - 回调函数中的
this
指向当前Vue实例,因此可以在回调函数中访问Vue实例的其他属性和方法。 - 监视属性是在数据变化后立即触发的,可以用于响应式数据的变化并执行相应的操作。
- 监视属性可以接收第三个参数
options
,用于更详细地配置监视属性的行为,例如deep
选项用于深度监视对象内部属性的变化。 - 可以使用
vm.$watch
方法动态创建监视属性,更灵活地监视属性的变化。 - 可以使用
immediate
选项设置监视属性的初始触发行为,使其在初始数据绑定时立即触发回调函数。 - 当计算属性和监视属性都能实现时,优先使用计算属性。
开启初始化调用和深度监视的示例:
watch: {
message: {
immediate:true, // 开启初始化调用
deep:true, // 开启深度监视
handler: function(newValue, oldValue) {
// 在message属性变化时执行操作
this.counter++;
},
},
}
5、绑定class
和style
样式
(1)class
-
字符串写法:样式的类型不确定时使用,手动触发样式改变,字符串使用的是vue实例data中的已有属性
```Hello!`` -
对象写法:样式个数、类名确定时,通过Boolean动态展示与否,在对象中,键表示样式类名的字符串,值为布尔值,用于决定是否应用该样式类。
在下面代码中,isRed
和isBold
是Vue实例中的响应式数据,当它们true
时,red
和bold
样式类将被应用到<div>
元素上。 -
Hello
// 也可以将对象写在data中来使用
Hellodata: {
list: {‘red’:‘isRed’,‘bold’:‘isBold’},
} -
数组写法:需要绑定的样式个数不确定,类名也不确定,数组中的每个元素表示一个样式类名。在下面代码中,
redClass
和boldClass
是Vue实例中的计算属性或者直接指定的样式类名,它们会被应用到<div>
元素上。<div :class="['redClass', 'boldClass']">Hello</div> // 三元表达式 <div :class="[isActive?'redClass':'', 'boldClass']">Hello</div> // 写在data中 <div :class="list">Hello</div> data:{list:['border', 'bg_red']}
(2)style
-
对象语法:可以使用对象语法来绑定多个样式属性和值。在对象中,键表示样式属性名,值表示样式属性的值。例如:
data: {textColor:‘red’,fontSize:‘30px’,},
在上述代码中,textColor
和fontSize
是Vue实例中的响应式数据,它们会被应用到<div>
元素的color
和fontSize
样式属性上。 -
数组语法:可以使用数组语法来绑定多个样式对象。每个对象表示一个独立的样式规则。例如:
在上述代码中,
textStyle
和backgroundStyle
是Vue实例中的计算属性或者直接指定的样式对象,它们会被应用到<div>
元素上。
(3)注意事项:
class
和style
绑定可以使用动态数据,这些数据可以是响应式的属性、计算属性、方法的返回值等,使用对象语法和数组语法的结合来实现更灵活的样式绑定效果。- 可以通过绑定的方式来控制样式的动态变化,以实现样式的切换、根据条件添加样式等动态样式效果。
- 对于
class
绑定,可以使用三元表达式、对象、数组等方式来实现更复杂的样式绑定逻辑。 - 当需要频繁切换样式,或根据多个数据的组合生成样式类名或样式属性值时,可以考虑使用
computed
属性来缓存样式计算结果,以提高性能。
6、列表常用操作
(1)列表过滤
列表过滤是指根据某些条件筛选出符合条件的列表项。
-
使用计算属性进行过滤: 可以使用计算属性来根据特定条件筛选列表项,并将筛选结果作为新的计算属性返回。
<ul> <li v-for="item in filteredItems" :key="item.id">{{ item.name }}</li> </ul> computed: { filteredItems() { return this.items.filter(item => item.price > 50); }, //搜索的方式 newList() { return this.items.filter((i) => { return i.name.indexOf(this.inputValue) !== -1; }); }, }
在上述示例中,使用
computed
属性filteredItems
来过滤items
列表,只返回price
大于50的列表项。搜索的方式则根据输入框的数据来进行筛选,筛选出包含输入数据的列表数据。 -
使用过滤器进行过滤: Vue.js提供了过滤器的概念,可以用于对数据进行格式化和过滤。
<ul> <li v-for="item in items" :key="item.id" v-if="item.price > 50"> {{ item.name }} </li> </ul>
在上述示例中,使用
v-if
指令在遍历列表时对每个列表项进行条件判断,只渲染price
大于50的列表项。
(2)列表排序
列表排序是指根据特定的规则对列表项进行排序。
-
使用计算属性进行排序: 可以使用计算属性来对列表进行排序,并将排序后的列表作为新的计算属性返回。
- {{ item.name }}
computed: {
sortedItems() {
return this.items.sort((a, b) => a.price - b.price);
}
}
在上述示例中,使用computed
属性sortedItems
来对items
列表进行排序,按照price
属性的升序排列。 -
使用自定义方法进行排序: 可以在方法中对列表进行排序,并在模板中调用该方法。
- {{ item.name }}
<button @click=“sortItems”>Sort
methods: {
sortItems() {
this.items.sort((a, b) => a.price - b.price);
}
}
在上述示例中,点击"Sort"按钮会调用sortItems
方法,该方法会对items
列表进行排序,按照price
属性的升序排列。生命周期函数
通常也叫生命周期回调函数、生命周期函数、生命周期钩子,vue初始化时在不同的阶段调用的不同函数,生命周期函数的
this
指向为vue实例,名字不能更改生命周期函数主要有以下:
- 创建前、创建后(beforeCreate、created)
- 挂载前、挂载后(beforeMount、mounted)
- 更新前、更新后(beforeUpdate、updated)
- 销毁前、销毁后(beforeDestroy、destroyed)
1、beforeCreate
- 在实例被创建之初,数据观测和事件配置之前调用。
- 该阶段组件实例的属性和方法还未被初始化,无法访问
this
。 - 通常在这个阶段进行全局配置、插件的注入等操作。
2、created
- 在实例创建完成后被调用。
- 在该阶段,组件实例的属性和方法已经被初始化,可以访问
this
。 - 可以进行一些初始化操作,例如数据的获取、初始化操作、事件的订阅等。
3、beforeMount
- 在组件挂载到DOM之前被调用。
- 该阶段组件的模板已经编译完成,但尚未将组件挂载到实际的DOM节点上。
- 通常在这个阶段进行DOM操作前的准备工作。
4、mounted(常用)
- 在组件挂载到DOM后被调用。
- 该阶段组件已经被挂载到实际的DOM节点上,可以访问到DOM元素。
- 可以进行DOM操作、启动定时器、发送网络请求、订阅消息、绑定事件等操作。
5、beforeUpdate
- 在组件更新之前被调用,即数据发生变化,但尚未重新渲染DOM。
- 在该阶段可以访问到更新之前的数据和DOM状态,进行一些准备工作。
6、updated
- 在组件更新完成后被调用,即数据发生变化,DOM已经更新。
- 在该阶段可以执行DOM操作,处理更新后的数据和DOM状态。避免在此阶段修改组件数据,以免引起无限循环的更新。
7、beforeDestroy
- 在组件销毁之前被调用。
- 在该阶段可以进行清理工作,例如取消定时器、解绑事件等,但无法阻止组件的销毁。
8、destroyed
- 在组件销毁后被调用。
- 在该阶段组件实例及其相关的DOM已经被完全销毁,无法再访问组件实例和DOM元素。**