函数(function
)是将一个对象转化成另外一个对象的规则 ,假设出f(x)=x^2
,那么就会定义出一个函数f
,他会将任何数变为自己的平方,假设你将f(2)=4
的时候,那么f
作为函数是被引用
,f(2)
所对应的数值是4
,这样的道理在计算机中也依然运用。
之后我们将f(x)=x^2
修改为g(x)=x^2
,我们可以把x
看作变量,我们可以随便的赋值
,在定义域中,仅仅可以包含一个大于或等于零的数值 ,我们通常将这类数称之为:“非负数
”。
定义域 例如我们新建一个函数g(-1/2)
他的定义域是非负数
,而f(-1/2)=1/4
,但是 g(-1/2)
没有被定义,值得注意的是,函数g
会拒绝他非定义域中的一切 数值,但是由于g
和f
有类似的数据,换而言之可以说g
的数据是基于f
得来的,且还拒绝非负数外的数据 ,所以自然而然要比函数 f
小一点,且函数g
是由限制f
的定义域所产生的。
对于定义域,目前我们将h(x)=x
,那么假设h
的定义域是所有动物的集合,那么这样我们就可得到h(马)=4
,其中马的数值是4
,因为所有动物的腿都是非负数
,所以函数 h
上的都是所有非负整数的集合
。
一个函数必须给每一个有效的输入指定唯一的输出 ,为了印证这个道理,首先我们假设你有一只狗狗,他的名字叫 one
,他每次吃饭的时候都会吐出来,one 将食物变成了很恶心的东西,我们此时尅通过使用 j(x)=one
,x
是 one 每次吐出的颜色,其中x
的定义域是one
每次吃的食物集合,而上域
是一切有可能输出的颜色集合。
为了使得遵守一个函数必须给每一个有效的输入指定唯一输出 ,我们假设 one
吃了面包,吐的时候是黑色
的,如果有时候吐的是黑色
,有时候吐的是白色
就不符合这个定理。
值域 对于值域,我们只需要注意到当我们输入
的时候,他是定义域 ,而当他输出的时候,他是一个值域
,值域虽然是上域的子集,但值域与上域的区别就是,上域是可能 输出的集合,而值域 确实实际
上输出的集合。
区间(interval
),假设函数上域R
包含了所有有可能输出的集合 ,那么定义与也有肯能会和上域R
差不多。就像是{x:2 ≤ x < 5}
这样的连通区间 ,而他的本质意思是介于2和5之间的所有数,包括2,但不包括5(”≤” 可以包括 “x = 2”,也可以包括小于”2”以下的数,但”<”只能包括小于”5”的数,不能包含”5”) ,因此为了让数学的表示更加简洁,出现了区间表示法。
闭区间 区间表述法主要分为(a,b)
代表了开区间 以及[a,b]
表示闭区间 ,其中闭区间 是指a ~ b
端点间的所有实数,并包括 a,b 。如 [2,5]
代表了所有介于 “2” 和 “5” 之间的实数集合,同时也包括了 2 and 5 ,按照开头的表述方法就是 x:2 ≤ x ≤ 5
开区间 开区间,主要表示不想包括的
,通常也必须以[]
表示,假设(2,5)
及表示介于“2” 和 “5” 之间的所有实数集合,但不包含“2”和“5” ,按照开头的表示方法就是x:2 < x < 5
。
半开区间 半开区间主要就是闭区间
和开区间
的一种集合,将他们分别混合组成为(2,5]
那么将会表述介于2和5之间的所有实数,但不包括”2”,只包括小于“2”的数,包括“5”和以下的实数。 ,按照开头的表述方法就是x:2 < x ≤ 5
那将半开区间换过来就是[5,2)
表述出介于2和5之间的所有实数,但不包括”5”,包括“2” ,也就是咱一开始的表述方法[x:2 ≤ x < 5]
∞ ∞
主要表述无穷大(infinite
)假设(2,∞)
那么将会表示出大于 2 但不包括”2”的所有实数 ,当然∞
也可以用-∞
来表示出无穷小 ,也可以配合半开区间使用,例如:[a,∞)
则表示出大于”2”且包括”2”的所有实数
微积分(Calculus
)主要分为微分(Differentiation
)以及积分(Integration)
,重点研究包括了极限、函数、切线、积分、微分及其应用。通常积分 用于计算曲线面积,微分 用于计算瞬时速度(物理瞬时速度
,即近似值)。
常用符号 通常的情况下,微分
会通过使用dx/dy
等进行代替,其中d
源于拉丁语中的差(Differentia)
的地一个字母。
而积分符号,会通过使用 ∫
来进行代替,他也是拉丁语中总和(Summa)
的第一个字母所拉长的效果。
pinia overview Pinia 是一个适用于 Vue2~3 的跨组件共享状态维持 项目,与 vuex、bus 等原理类似,但都比前者简单高效许多,在 2019 年 11 年重新被设计使用,其维护团队为 Vuejs。
特点在于更加容易调试,可以使得 store
出现在其他组件中并使用,以及在不重新加载页面的情况下修改 store
共享数据,并保持现有状态,同时占用空间小的特点。
1 反观 Vuex 和专注于兄弟组件之间通信的 Bus 相比,Pinia 根据简单和[官方](https://github.com/vuejs/pinia)团队维护等特点深受开发人员喜爱。
Store 首先,Pinia 拥有和 Vuex 类似的特性及功能(毕竟是同类型项目),而 Store 的定义主要是可以让该数据被所有组件共享。
在本文中,我们主要通过 vue-cli 来构建 vue3 project,并使用 vue add vue-cli-plugin-pinia
来添加 pinia 支持。
之后可以在 src/store/
下看到其自动帮我们所创建的 pinia store,之后我们可以重命名或者直接在此基础上进行开发,来进行共享数据。
同时他也会在 mian.js
文件下为我们引入 pinia 并使用,返回给 Vue。
在使用的时候,你需要记得,在 store 目录下的共享数据内的方里,默认的会为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import { defineStore } from 'pinia' export const useCounterStore = defineStore ('counter' , { state : () => ({ count : 0 }), getters : { double : state => state.count * 2 , }, actions : { increment ( ) { this .count ++ }, }, })
我们需要记得导出的方法,也就是 useCounterStore
之后在组件中直接 import { useCounterStore } from "@/stores/index"
这么引用,然后在 setup()
语法糖下赋值给 store
:
1 2 3 4 5 6 7 setup ( ) { const store = useCounterStore () return { store, } }, })
这之后在 template
下,就可以通过插值 {{ store.count }}
来直接进行使用了。
1 这在官方文档关于定义 Store 中有详细的描述:“并且它需要一个唯一的名称,作为第一个参数传递”
State State 是 Stores
所定义的中心部分,也就是共享数据\状态的起点,在 PInia 中会被定义为返回初始的状态函数:
1 2 3 4 5 6 7 8 9 import { defineStore } from 'pinia' export const useTabStore = defineStore ('tab' , { state : () => ({ rowItems : [] })
Getters & Actions Actions 在此之前,我们需要知道,getters
是被动获取,也就是说需要有组件取调用这个方法。而 Actions 则是可以实现在文章开头,Pinia 所说的特性之一:”Stores appear in components where they are used”,即可以在组件中实现将组件的数据,传入到 State 中。
1 需要注意的是,在一般情况下,Vuex、和 Bus 很难去解决组件和组件之间的传值,需要通过 emit,props 等方法,先将兄弟组件的数据传给父组件,父组件再将数据传给兄弟组件,以此来实现传值。
在组件传值之前,我们首先需要在 store
下定义参数,准备接受组件所传来的数据,并之后传给 state()
下的共享状态变量 rowItems
:
1 2 3 4 5 6 7 8 9 10 11 12 13 import { defineStore } from 'pinia' export const useTabStore = defineStore ('tab' , { state : () => ({ rowItems : [] }), actions : { addItem (name ) { this .rowItems .push (name) }, }, })
1 在真实的开发环境中,一般先定义 ```state``` 下的共享变量,再去定义 ```actions```,之后才是 ```getters```
上述 Code 中,我们主要通过 this.rowItems.push
方法,来将获取到的 name
参数传递给 state
,之后 getters
来获取 state
下的共享数据/状态变量。
下面,我们需要通过在传递数据的组件内,引入 import { useTabStore } from "@/stores";
,之后按照 setup()
语法糖:
1 2 3 4 5 6 7 8 export default defineComponent ({ setup (props, {emit}) { const tab = useTabStore () return { tab } }, })
由于我们是按照 setup()
语法糖的 Vue3 的写法,那么基本上数据是在 setup()
下的 return
来进行编写,我们需要做的就是通过 tab.addItem(value)
将数据传递给 stores
,之后就完成了组件的传递。
Getters 可以理解为获得数据,他与 ```state``` 所定义的数据/状态是完全等价的,且处于被动,也就是说可以通过组件访问 ```getters``` 所关联的 ```state``` : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ```js import { defineStore } from 'pinia' export const useTabStore = defineStore('tab', { state: () => ({ /* return {Array} */ rowItems: [] }), getters: { items: (state) => state.rowItems.reduce((items, item) => { console.log({name: item},'{name: item}') items.push({name: item}) return items }, []), }, actions: { addItem(name) { this.rowItems.push(name) console.log(name,'->>>>>>YES') }, }, })
在上述的 Code 中,我们首先在 state
先定义共享状态 rowItems
变量,当获取数据的时候,我们需要他可以循环遍历,那么就通过 reduce 之后 方法来按照数组的顺序来进行返回。
然后通过 push 方法将元素添加至数组的末尾,最后返回 items
变量,这是通过 actions
所获取到的数据并输出。
在数据的获取部分,我们需要在组件中同样引入 import { useTabStore } from "@/stores/index"
,然后按照 setup()
语法糖的写法:
1 2 3 4 5 6 7 8 export default defineComponent ({ setup (props, {emit}) { const tab = useTabStore () return { tab } }, })
之后通过 template
的模板语法以及 v-for
和 v-bind
就可以完成共享数据的循环输出:
1 2 3 <li v-for ="item in store.items" :key="item.name" > {{ item.name }} </li>
Get or Post 在上一个章节中我们了解到 Axios 是一个基于 Promise 的网络请求库,通常运用在 node.js 中,使得可以完成在原来之前传统开发环境下的 ajax,在此之前,我们还需要通过下述命令完成安装和添加的操作:
在安装完成后,我们需要在自己的 Vue 项目中添加 axios 来作为库并进行使用,可以通过 vue add axiso
在 export default
中定义如下方法:
然后在 .vue 文件下 script
元素中的 export default
方法中增加 created()
方法中,以此来调入接口,之后通过:
1 2 3 4 5 created ( ) { axios.get ('' ).then (function (res ) { console .log (resp) }) }
通过上述的 code 来请求 api,并输出全部响应到的数据后,我们就可以通过在之前请求相应的数据中进行单个解析:
1 2 3 4 5 6 created ( ) { const _this = this axios.get ('' ).then (function (res ) { _this.tableData = res.data .content }) }
除了上述方法外,我们还可以使用下述方法来进行实现其同样的效果,但主要的区别就是在于代码的可视性。
1 2 3 4 5 6 axios ({ method : 'get' , uri : 'API' }).then (function (res ) { console .log (res) })
假设你如果要发送 POST 请求,那么我们可以将上述的 Code 改为下述示例:
1 2 3 4 5 6 7 8 axios ({ method : 'post' , uri : 'uri' , name : 'administrator' , pass : '123456789' }).them (res => { console .log (res) })
需要注意的是,在上述 POST 请求中,user
和 pass
是 API 中需要我们所传入的信息,当然,这些可以根据实际情况自行进行调整。
1 在 ```created``` 方法中写入 Axios 是为了在加载时第一时间获取到数据,如果是需要触发才会发生的事件,那么建议你在 ```methods``` 方法中定义一个方法事件。
在上述的 code 中,我们首先通过 _this
来解决作用域的问题,并通过 axios
的解析目标 API 所相应的数据(data) 下的 content
Key,然之后就需要在数据表格中写入:
1 2 3 4 5 data ( ) { return { tableData : null } }
由于我们拿到的是数组数据,我们可以通过在其组件外在套一件 template
并通过 v-for
指令来进行循环输出,在此之后,我们就可以通过翻阅 Axios 的官方文档 ,来满足我们大部分的需求。
Backage 在正常的开发环境中,一般情况下我们很少会直接去使用 Axios 来直接去写入到方法中,更多的情况是定义一个实例 来满足请求(request)\响应(response)拦截器(interceptors) ,这通常被称之为《封装》
在此之前,我们需要在当前的 Vue 项目中率先构建出一个封装目录,可以在 src/request
目录也可以直接在根目录中新建一个 utils
目录进行封装。
实例 (Create) 之后还需要在此目录中创建两个 .js
文件,分别为 request.js
和 api.js
两个,并在 request.js
中定义一个实列:
1 2 3 4 5 6 7 import axios from 'axios' const instance = axios.create ({ baseURL : "" , timeout : 10000 headers : {'X-Custom-Header' : 'foobar' } })
在上一段 Code 中, baseURL
是我们 API 的基础 URI,举个例子,假设我的 API 是 https://axios-http.com/zh/docs/instance
,那么 baseURL
就是 https://axios-http.com
。
而之后的两个参数就是 timeout
超时时间的设置以及 headers
请求头的加入。
拦截器 (Interceptors) 拦截器的定义主要分为 request & response 即请求和相应的拦截,因为 Axios 是基于 promise 上构建的,Code 如下:
1 2 instance.interceptors .request .use (callback, callback) instance.interceptors .response .use (callback, callback)
在上述的拦截器中,所返回的 callback
中,第一个代表成功,而第二个表示错误的拦截,是不是很像 Promise,现在,我们在此基础上再次进行编写:
1 2 3 4 5 6 7 8 9 10 11 instance.interceptors .request .use (config => { }, er r=> { return Promise .reject (err) }) instance.interceptors .response .use (res = > { return res; }, err => { return Promise .reject (err) })
在上述 Code 中,在请求中,如果有特定需要你可以在 config
中来进行添加你的 Code,这会在请求的同时发送出去,而之后的响应在没有特定需要的情况下,可以直接返回响应即可。
同样的你也可以在这里编写一个处理响应的 Code 在返回,这都根据你的项目需要来进行编写。
1 export default instance;
最后,我们需要通过 Node 所提供的 Model 概念来将我们的实例导出,然后在 api.js
中进行使用
封装 之后在 api.js
文件中,需要引入我们刚刚全部导出的封装,来将他整体引入:
1 import request from '@/request/request.js'
由于我们已经引入了之前的 request.js
实例,之后我们需要在当前文件中写入需要的 API 进行请求:
1 export const GetUser = ( ) => request.get ('uri' );
而之后的使用我们可以在之前的 .vue
文件中,在 created
或 methods
方法,定义一个参数,但在此之前我们还需要引入之前封装的 api.js
文件:
1 2 3 4 5 6 7 8 9 import { GetUser } from '@/request/api.js' ;methods : { UserLogin () { GetUser ().then (function (res ) { console .log (res) }) } }
通常 ,在少部分的情况下的功能需求会让我们在请求时加入一些参数,而封装之后的参数部分定义主要可以体现在 Post 请求的发送过程上:
1 export const PostUser = (params ) => request.post ('uri' , params);
假设如果是 POST 方法的请求,那么我们可以在 .Vue
文件的 created
或 methods
方法下同样和 Get 一样定义个参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import { GetUser , PostUser } from '@/request/api.js' ;methods : { UserLogin () { GetUser ().then (function (res ) { console .log (res) }) }, PostRegister () { PostUser ({ user : 'administrator' , pass : '123456789' }).then (res => { console .log (res) }) } }
通过对 axios 的实例封装使得我们可以通过上述 Code 非常简单的来实现对 API 的操作,通过 params
增加了 Code 的可读性和后期维护的成本。
Callbacks and Asynchronous AXIOS 正如文档 中所描述的,它是一个基于 promise 用于因此 的网络请求库,即异步(async) 和 同步(await) 同时也在文档中描述了一段故事:
1 2 3 4 5 6 7 8 9 想象一下,你是一位顶级歌手,粉丝没日没夜的询问你什么时候发送新歌,为了从中解放,你承诺(promise)会在单曲发布的第一时间发给他们。你给了粉丝们一个列表。他们可以在上面填写他们的电子邮件地址,以便当歌曲发布后,让所有订阅了的人能够立即收到。即便遇到不测,例如录音室发生了火灾,以致你无法发布新歌,他们也能及时收到相关通知。 每个人都很开心:你不会被任何人催促,粉丝们也不用担心错过歌曲发行。 这是我们在编程中经常遇到的事儿与真实生活的类比: 1. 生产者代码,会做一些事并且需要一定时间,例如通过网络加载数据的 code; 2. 消费者代码,想要在生产者代码完成工作的第一时间就可获得回馈(也就是工作结果),可以理解为粉丝。
而 promise 就是将上述两者连接在一起的特殊 JavaScript 对象,使得可以立即获得相关信息,这也被称之为 “异步”,因为 Promise 是 AXOPS 的基础,所以本章也会从 Promise 开始来进行学习。
在此之前我们需要了解下 Promise
对象,他主要用于表示一个异步操作最终完成的结果,当然也会包含失败的结果值。
Callbacks 又被称之为或调参数,即将一个参数传递给另一个参数的过程被称之为回调 ,在 JavaScript 回调 (w3schools.com) 这一章节中您可以清除的了解到 callback 的主要用法。
抛出基础问题不谈,Callbacks 主要就针对 调用 两个字来进行深入,以及将参数带入函数中进行计算,完成后回调,这里 W3 的例子是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <!DOCTYPE html> <html> <body> <h2>JavaScript Callbacks</h2> <p>Do a calculation and then display the result.</p> <p id="demo"></p> <script> function myDisplayer(something) { document.getElementById("demo").innerHTML = something; } function myCalculator(num1, num2, myCallback) { let sum = num1 + num2; myCallback(sum); } myCalculator(5, 5, myDisplayer); </script> </body> </html>
在上述的 code 中,myDisplayer
函数中的 something
参数被之后的 document……
方法引入,之后 myCalculator
将 num1
和 num2
参数通过 myCallback
回调给 sun,之后当 myCalculator
被调用时所添加的参数也会被解析到 sun
这个变量中进行计算,并将 myCalculator
函数绑定返回给 myDisplayer
Asynchronous 异步通常与 Callbacks 一起使用,同样在 w3 这一章节中所提供的例子使得我们可以快速了解 Asynchronous 和 Callbacks 一起使用的范例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function myDisplayer (some ) { document .getElementById ("demo" ).innerHTML = some; } function getFile (myCallback ) { let req = new XMLHttpRequest (); req.open ('GET' , "mycar.html" ); req.onload = function ( ) { if (req.status == 200 ) { myCallback (this .responseText ); } else { myCallback ("Error: " + req.status ); } } req.send (); } getFile (myDisplayer);
在异步的定位中,主要将与其他函数并行运行的函数为异步,结合上述的 Code 我们可以知道,getFile
与 myDisplayer
是同时执行的,这加快了网站加载的速度以及用户的体验。
同样是在 getFile
下的 myCallback
参数,之后该参数返回的则是当前的请求信息和错误,以至于最后如果 GET 请求成功的情况下可以获取到 mycar.html
的上下文信息。
Promise 在了解过回调(callbacks)和异步(Asyncchronous)之后,回归正题,Axios 主要是基于 Promise 来进行构建,那么 Promise 在通过一开始所介绍的 “故事” 内,我们知道,生产者代码需要一些时间,而消费者代码是可以得到反馈的。
Promise Object 1 2 3 4 5 6 7 8 9 10 11 12 let myPromise = new Promise (function (myResolve, myReject ) { myResolve (); myReject (); }); myPromise.then ( function (value ) { }, function (error ) { } );
JavaScript Promise Object 包含了上述中生产者带么和消费者代码的实现,当之后 Promise 执行时,他会调用两个回调方法,如果时结果值那么就 successful,否则 error,这也对应着 Promise Object 所支持的两个属性,状态和结果。
.then() 最终,Promise 会通过 .then()
来返回成功和失败的回调函数,他的概念主要还是 Promise Object 所支持的两个属性,更加详细的可以参考下 MDN 的 Promise.prototype.then() - JavaScript | MDN (mozilla.org) 详细了解具体原理。
最后总结一点是,如果 Promise 返回了一个值,那么 then
将会成为接受(accept)状态,没返回任何值,then
同样会返回接收状态,并将接受状态的回调参数设置为 undefined
。
假设抛出一个错误,那么 then
也会返回一个拒绝状态,并将错误信息回调到参数值中。但如果是一个接受的 Promise,那么 then
就会将状态设置为 fulfilled
,反之则是 rejected
。
如果遇到一个未定状态(pending
),那么 then
所返回的 Promise 也会是未定的,在 W3 中,同样给了我们一个非常简单的例子供我们进行理解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <!DOCTYPE html> <html > <body > <h2 > JavaScript Promise</h2 > <p id ="demo" > </p > <script > function myDisplayer (some ) { document .getElementById ("demo" ).innerHTML = some; } let myPromise = new Promise (function (myResolve, myReject ) { let x = 0 ; if (x == 0 ) { myResolve ("OK" ); } else { myReject ("Error" ); } }); myPromise.then ( function (value ) {myDisplayer (value);}, function (error ) {myDisplayer (error);} ); </script > </body > </html >
在上述的 Code 中,同样的有两个最后的状态进行输出,一个是成功的而另一个则是错误的状态信息进行输出,通过 .then()
使得我们可以处理异步中的错误,以及成功返回的信息。
Async/Await Async 在 async 和 await 还未出现之前,异步编程通常会苦恼当前的开发人员,但在 ECMAScript 2017 中,async/await 通过 promises 使得将异步的编写更加容易和方便,同时增加的阅读性。
我们可以将 async 和 await 拆分下来(虽然 await
离开了 async 些许并没有什么作用),async 可以理解为 promise 中的生产者代码:
1 2 3 4 async function hello ( ) { console .log ("Hello,world!" ) } hello ();
上述代码中的 async
同等与传统方法中的 function
,之后,我们还需要配合 await
来进行使用。
Await 而之后的 await,他实际上就是 .then
,只可以和 async
搭配进行使用,基于 promise 的函数之前。它会暂停代码在该行上,直到 promise 完成,然后返回结果值。在暂停的同时,其他正在等待执行的代码就有机会执行了:
1 2 3 4 5 async function hello ( ) { return greeting = await Promise .resolve ("Hello" ); }; hello ().then (alert);
顾名思义,也就是在 await
的同时,他会来进行回调的调用,来代替之前我们之前直接一个函数来进行回调,同时他也完成了 then
的部分工作,使得 then
会减少使用。
vue 的表单处理主要通过v-model
指令,且仅仅限制于在<input>、<select>、<textarea>
等HTML表单元素创建双向数据绑定。v-model 可以根据HTML控件的类型来自动选取正确 的方法来进行更新。
当使用输入法如中日韩等语言时,需要使用 value
绑定,而不是 v-model
需要值得注意的是v-model
指令会忽略所有的表单value、checked、selected
等属性的初始值,所以需在js
内的data
选项中声明初始值。
指令在内部为不同的输入元素使用了不同的属性并抛出不同的事件: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | Name | Info | | ---------------- | ---------------------------------- | | text & textarea | 使用value 属性和input 事件 | | checkbox & radio | 使用 checked 属性 和 change 事件 | | select | 将以value 作为属性并和 change 事件 | ## Demo ### input  当使用 ```v-model``` 绑定 message 属性的时候,通过 Mustache 表达式获取 message 属性值来达到双向绑定的效果。 > 在 ```<input>``` 元素中所设置的 value 默认值将不会被绑定,这是因为 ```v-model``` 指令会忽略所有表单元素的 value、checked、selected 属性的初始值,更或者说该指令只会获取 ```v-model``` 所绑定的 message 属性值。 ```js <ui id="app"> <input type="text" v-model="message" placeholder="echo" /> <p>{{message}}</p> </ui> <script> const app = Vue.createApp ({ data() { return { message: null } }, methods: { echo(message, event) { alert(message) if (event) { alert('v-on:' + event.target.tagName) } } } }) const vm = app.mount('#app') </script>
checkbox
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <ui id="app" > <input type ="checkbox" v-model ="message" /> <label > This is message: {{message}}</label > </ui> <script > const app = Vue .createApp ({ data ( ) { return { message : false } }, methods : { echo (message, event ) { alert (message) if (event) { alert ('v-on:' + event.target .tagName ) } } } }) const vm = app.mount ('#app' ) </script >
复选框 value 绑定
直接通过 checkbox
的 value 来写入 message 数组当中,当显示的时候也是以数组的形式进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <ui id="app" > <h2 > JavaScript</h2 > <input type ="checkbox" v-model ="message" value ="Vue" /> <label > Vue</label > <input type ="checkbox" v-model ="message" value ="Jquery" /> <label > Jquery</label > <input type ="checkbox" v-model ="message" value ="Ajax" /> <label > Ajax</label > <input type ="checkbox" v-model ="message" value ="D3.js" /> <label > D3.js</label > <input type ="checkbox" v-model ="message" value ="Lodash" /> <label > Lodash</label > <h2 > Web</h2 > <input type="checkbox" v-model="message" value="Node.js"><label>Node.js</label> <input type="checkbox" v-model="message" value="Java"><label>Java</label> <input type="checkbox" v-model="message" value="PHP"><label>PHP</label> <input type="checkbox" v-model="message" value="GO"><label>GO</label> <h2>SQL</h2> <input type="checkbox" v-model="message" value="MySQL"><label>MySQL</label> <input type="checkbox" v-model="message" value="Redis"><label>Redis</label> <input type="checkbox" v-model="message" value="SQL"><label>SQL</label> <input type="checkbox" v-model="message" value="HBase"><label>HBase</label> <input type="checkbox" v-model="message" value="ORACLE"><label>ORACLE</label> <hr /> <p>This is message: {{message}}</p> </ui> <script> const app = Vue.createApp ({ data() { return { message: [] } }, methods: { echo(message, event) { alert(message) if (event) { alert('v-on:' + event.target.tagName) } } } }) const vm = app.mount('#app') </script>
radio 对于 radio
类型的 <input>
元素依然可以使用 value 对 message 进行双向的数据绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <ui id="app" > <h2 > JavaScript</h2 > <input type ="radio" v-model ="message" value ="Vue" /> <label > Vue</label > <input type ="radio" v-model ="message" value ="Jquery" /> <label > Jquery</label > <input type ="radio" v-model ="message" value ="Ajax" /> <label > Ajax</label > <input type ="radio" v-model ="message" value ="D3.js" /> <label > D3.js</label > <input type ="radio" v-model ="message" value ="Lodash" /> <label > Lodash</label > <h2 > Web</h2 > <input type="radio" v-model="message" value="Node.js"><label>Node.js</label> <input type="radio" v-model="message" value="Java"><label>Java</label> <input type="radio" v-model="message" value="PHP"><label>PHP</label> <input type="radio" v-model="message" value="GO"><label>GO</label> <h2>SQL</h2> <input type="radio" v-model="message" value="MySQL"><label>MySQL</label> <input type="radio" v-model="message" value="Redis"><label>Redis</label> <input type="radio" v-model="message" value="SQL"><label>SQL</label> <input type="radio" v-model="message" value="HBase"><label>HBase</label> <input type="radio" v-model="message" value="ORACLE"><label>ORACLE</label> <hr /> <p>This is message: {{message}}</p> </ui> <script> const app = Vue.createApp ({ data() { return { message: [] } }, methods: { echo(message, event) { alert(message) if (event) { alert('v-on:' + event.target.tagName) } } } }) const vm = app.mount('#app') </script>
textarea
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <ui id="app" > <textarea v-model ="message" placeholder ="echo" > </textarea > <p > This is message: {{message}}</p > <hr /> <p style ="white-space: pre-line" > This is message: {{message}}</p > </ui> <script > const app = Vue .createApp ({ data ( ) { return { message : null } }, methods : { echo (message, event ) { alert (message) if (event) { alert ('v-on:' + event.target .tagName ) } } } }) const vm = app.mount ('#app' ) </script >
元素通常用于处理较多的文字输入,因此对他双向绑定可以使用 [white-space](https://developer.mozilla.org/zh-CN/docs/Web/CSS/white-space) 来处理用户的换行输入。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ### select  ```js <ui id="app"> <select v-model="message"> <option disabled value="">Select</option> <option value="vue">Vue</option> <option value="Jqery">Jquery</option> </select> <hr /> <p>This is message: {{message}}</p> </ui> <script> const app = Vue.createApp ({ data() { return { message: '' } }, methods: { echo(message, event) { alert(message) if (event) { alert('v-on:' + event.target.tagName) } } } }) const vm = app.mount('#app') </script>
在上述的code当中,我们主要通过使用 value 来设置 option 被选择时的属性,此时 value 依然会写入 message,之后 <p>
元素对 message 进行数据绑定。
修饰符 在 vue中,自然而然的也为表单处理所加入了一些较为常用的修饰符,如.lazy、.number、.trim
,他们分别对输入和输出进行提供了修改:
Name
Info
.lazy
当输入完成时在同步信息
.number
将输入的值自动转换为 number
类型
.trim
自动过滤首尾空白
.lazy
在未使用 .lazy
的情况下,<input>
所接受到触点事件将会记录我们所写入的信息,自然而然的也会传入到 message
属性中,而 .lazy
的主要作用就是当 <input>
触点事件结束时才开始将数据发送给 message
.trim
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ```js <ui id="app"> <textarea v-model.trim="message" placeholder="start"></textarea> <textarea v-model="trims" placeholder="start"></textarea> <hr /> <p>This is message: {{message}}</p> <p>This is message: {{trims}}</p> </ui> <script> const app = Vue.createApp ({ data() { return { message: '', trims: '' } }, methods: { echo(message, event) { alert(message) if (event) { alert('v-on:' + event.target.tagName) } } } }) const vm = app.mount('#app') </script>
.number
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 > 但需要输入头部数据是 number 类型,否则 ```.number``` 修饰符的作用不大 ```js <ui id="app"> <textarea v-model.number="message" placeholder="echo"></textarea> <hr /> <p>This is message: {{message}}</p> </ui> <script> const app = Vue.createApp ({ data() { return { message: '' } }, methods: { echo(message, event) { alert(message) if (event) { alert('v-on:' + event.target.tagName) } } } }) const vm = app.mount('#app') </script>
v-on 的缩写为 @
,其参数为 event
即监听对应的事件是否被触发,这主要用法就是绑定事件监听器,事件的类型都由修饰符进行指定。也可监听鼠标、键盘等事件来运行相应的 JavaScript,如 v-on:click="methodName"
或 @click="methodName"
:
@click 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <ui id="app" > <button @click ="counts +=1" > Add 1</button > <button @click ="counts -=1" > Remove 1</button > <p > This is {{counts}}</p > </ui> <script > const app = Vue .createApp ({ data ( ) { return { counts : 0 } } }) const vm = app.mount ('#app' ) </script >
@click function 为应对更加复杂的业务环境,v-on
还提供调用 function
的支持,这会让 @click
的功能的监听更加的多样化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <ui id="app" > <button @click ="add" > Add</button > </ui> <script > const app = Vue .createApp ({ data ( ) { return { counts : 'Hey,v-on' } }, methods : { add (event ) { alert ('This is ' + this .counts ) if (event) { alert ('v-on:' + event.target .tagName ) } } } }) const vm = app.mount ('#app' ) </script >
内链处理方法 鼠标左击处理也是通过内链直接调用的,所谓内链就是与html 标签元素写在一起即大多数都被称之为内链。
Vue 使用的是 $ 前缀来通过组件实例所暴露自己的内置 API,对于内部还提供了 _ 前缀。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <ui id="app" > <button @click ="echo('hey,world!',$event)" > Add</button > </ui> <script > const app = Vue .createApp ({ data ( ) { return { } }, methods : { echo (message, event ) { alert (message) if (event) { alert ('v-on:' + event.target .tagName ) } } } }) const vm = app.mount ('#app' ) </script >
修饰符
Name
Info
Full
click.stop
调用 event.stopPropagation()
阻止捕获和冒泡阶段中当前事件的进一步传播
click.prevent
调用 event.preventDefault()
阻止默认的点击事件执行
.capture
添加事件侦听器时使用capture(捕获) 模式
.self
只当事件从侦听器绑定元素本身触发时才进行回调
```.{keyCode
keyAlias}```
只当事件从特定键触发时才进行回调
.once
只触发一次回调
.left
只当点击鼠标左键时触发
.right
只当鼠标点击右键时触发
.middle
当鼠标中键时触发
.passive
以 { passive: true } 模式添加侦听器
事件的修饰符处理通常是调用 event.stoppPropagation()
方法来进行实现的,但只有纯粹的数据逻辑而不是处理 DOM 事件,因此 Vue v-on
指令提供了修饰符。
我们主要以 prevent
为例,监听其 submit 元素是否被触发,并组织默认的单击事件执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div id="app" > <form v-on:click.prevent ="doThis" > <a :href ="home" > {{message}}</a > </form > </div> <script > var App = { data ( ) { return { message : 'Go Jiangxue Team' , home : 'https://www.jiangxue.team/' } } } Vue .createApp (App ).mount ("#app" ) </script >
或者通过 v-on
的简写 @
来实现没有表达式的阻止默认行为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div id="app" > <form @click.prevent > <a :href ="home" > {{message}}</a > </form > </div> <script > var App = { data ( ) { return { message : 'Go Jiangxue Team' , home : 'https://www.jiangxue.team/' } } } Vue .createApp (App ).mount ("#app" ) </script >
可参考下 Vue 官方文档中所提供的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <!-- 方法处理器 --> <button v-on:click ="doThis" > </button > <!-- 动态事件 --> <button v-on: [event ]="doThis" > </button > <!-- 内联语句 --> <button v-on:click ="doThat('hello', $event)" > </button > <!-- 缩写 --> <button @click ="doThis" > </button > <!-- 动态事件缩写 --> <button @[event ]="doThis" > </button > <!-- 停止冒泡 --> <button @click.stop ="doThis" > </button > <!-- 阻止默认行为 --> <form @submit.prevent > </form > / <form @click.prevent></ form><!-- 阻止默认行为,没有表达式 --> <form @click.prevent > </form > <!-- 串联修饰符 --> <button @click.stop.prevent ="doThis" > </button > <!-- 键修饰符,键别名 --> <input @keyup.enter ="onEnter" /> <!-- 点击回调只会触发一次 --> <button v-on:click.once ="doThis" > </button > <!-- 对象语法 --> <button v-on ="{ mousedown: doThis, mouseup: doThat }" > </button >
@click 众所周知,Jquery 很多方法都需要使用鼠标事件,如鼠标单击事件,而vue 在2.2.0版本中,也增加了一个鼠标按钮修饰符,还比 Jq 的更加简单便捷:
Name
Img
.left
.right
.middle
例如可以监听鼠标的 right
事件来返回一个消息,当然你也可以监听 .middle
滚轮中键点击等:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <ui id="app" > <button @click.right ="echo('hey,world!',$event)" > Add</button > </ui> <script > const app = Vue .createApp ({ data ( ) { return { } }, methods : { echo (message, event ) { alert (message) if (event) { alert ('v-on:' + event.target .tagName ) } } } }) const vm = app.mount ('#app' ) </script >
@keyup v-on 指令并不仅仅支持鼠标的事件操作,还支持按键,这在官方文档中也被称之为按键修饰符,通过监听键盘事件,在v-on
指令中共支持了 9 个按键修饰符:
Name
Img
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
通过 Vue 的按键修饰符可以监听目前常用的按键事件来执行对应的操作,例如监听 tab
按键从而返回消息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <ui id="app" > <button @keyup.tab ="echo('hey,world!',$event)" > Add</button > </ui> <script > const app = Vue .createApp ({ data ( ) { return { } }, methods : { echo (message, event ) { alert (message) if (event) { alert ('v-on:' + event.target .tagName ) } } } }) const vm = app.mount ('#app' ) </script >
系统修饰符 当然,vue的v-on
指令还不仅仅以上这些,自然而然的还支持了系统修饰符,我们可以通过按下响应的按键触发监听器:
ID
DA
.ctrl
.alt
.shift
.meta
Vue 对几个系统按键提供了多个支持,以及多个按键(@keyup
)或鼠标(@click
)之间的组合监听,需要注意的是在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。在 Symbolics 键盘上,meta 被标记为“META”或者“Meta”。
比如下述的实例中,通过 ctrl
和 @click
按键,当按下 ctrl
并点击该事件才会进行触发 echo
事件,或者通过 ctrl
+ enter
组合进行触发。
需要注意的是,修饰符键于常规的不同,当keyup
事件一起使用的时候,修饰符键必须处于按下的状态 ,只有当按住tab
的情况下释放其他案件,才能被触发,所以如果需要实现那种行为,可以尝试下使用 KeyCodes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <ui id="app" > <button @click.ctrl ="echo('hey,world!',$event)" > A</button > <input @keyup.ctrl.enter ="echo('hey,world!',$event)" /> </ui> <script > const app = Vue .createApp ({ data ( ) { return { } }, methods : { echo (message, event ) { alert (message) if (event) { alert ('v-on:' + event.target .tagName ) } } } }) const vm = app.mount ('#app' ) </script >
为了增强修饰符之间的组合使用,在 Vue 2.5.0 中还提供了 .exact
属性用于精准控制系统修饰符组合并合并触发事件:
1 2 3 4 5 6 7 8 <!-- 即使 Alt 或 Shift 被一同按下时也会触发 --> <button v-on:click.ctrl ="onClick" > A</button > <!-- 有且只有 Ctrl 被按下的时候才触发 --> <button v-on:click.ctrl.exact ="onCtrlClick" > A</button > <!-- 没有任何系统修饰符被按下的时候才触发 --> <button v-on:click.exact ="onClick" > A</button >
array Vue 的循环就是通过 v-for
指令得以实现,通常可以通过循环的方式来渲染一个列表对象。同样 v-for
指令还需使用 item in items
形式的特殊语法进行渲染:
通常 item 是被迭代数组的别名,而 items 则是数组的元数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <ui id="app" > <li v-for ="item in items" > {{item.message}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { items : [ {message : 'This is one' }, {message : 'This is two' } ] } } }) const vm = app.mount ('#app' ) </script >
父作用域属性 在 v-for
指令中,我们所有可以访问的父作用域属还支持可选的第二参数,主要用于索引和加入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <ui id="app" > <li v-for ="(item, index) in items" > {{index}}-{{item.message}}——{{message}}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { message : 'Hey,v-for' , items : [ {message : 'This is one' }, {message : 'This is two' } ] } } }) const vm = app.mount ('#app' ) </script >
Object 除数组以外,v-for
指令同样支持对象的循环渲染以及父作用域属性的使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <ui id="app" > <li v-for ="item in items" > {{item}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { items : { title : 'Start Vue 3.0' , author : 'lk.sun' } } } }) const vm = app.mount ('#app' ) </script >
父作用域 需要注意的是父作用域中的第二参数的格式和位置需要按照 value、name、index
的形式进行排序,否则在数据渲染的时候将会出现混乱。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <ui id="app" > <li v-for ="(value, name, index) in items" > index: {{index}} - name: {{name}} - value: {{value}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { items : { title : 'Start Vue 3.0' , author : 'lk.sun' } } } }) const vm = app.mount ('#app' ) </script >
维护状态 当 v-for
渲染的元素列表发生改变时,会默认使用 就地更新 测罗,如果数据被改变 vue 将不会移动 DOM 元素来匹配数据项的顺序,为了确保他们每个需渲染后索引位置正确,在节点中加入一个唯一的 key
属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <ui id="app" > <li v-for ="item in items" :key ="item.id" > {{item}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { items : { title : 'Start Vue 3.0' , author : 'lk.sun' } } } }) const vm = app.mount ('#app' ) </script >
在官方文档中建议我们尽可能的时候 v-for
时可以提供 key
属性,除非遍历输出的 DOM 内容非常简单,或是希望可以减少性能上的提升。
数组的更新检测 变更方法
Id
Name
Info
1
push()
增加一个方法
2
pop()
从下往上突然的删除一个方法
3
shift()
从上往下删除一个方法
4
unshift()
从上方新加入一个方法
5
splice()
splice()
方法可用于添加、删除、替换 数组内的值
6
sort()
用于排序方法
7
reverse()
主要用于排序倒序
8
filter()
过滤器或筛选
9
slice()
切片
假设我们需要增加一个新的数组,可以通过使用 push()
变更方法在控制台中直接使用 vm.items.push({message: 'A4TECH'})
进行加入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <ui id="app" > <li v-for ="item in items" > {{item.message}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { items : [ {message : 'LG' } ] } } }) const vm = app.mount ('#app' ) </script >
过滤和排序 filter() 在 Vue 3.0 中,将 filters
属性移除并向变更方法中新增了一个 filter()
方法作为过滤器进行使用,在 Vue 2.x 中,开发者可以使用 filters
来处理通用的文本格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <template> <h1 > Bank Account Balance</h1 > <p > {{ accountBalance | currencyUSD }}</p > </template> <script > export default { props : { accountBalance : { type : Number , required : true } }, filters : { currencyUSD (value ) { return '$' + value } } } </script >
在 Vue 3.x 中可以通过使用 fliter()
来处理数组来进行过滤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <ui id="app" > <li v-for ="item in evenNumbers" :key ="item" > {{item}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { numbers : [1 , 2 , 3 , 4 , 5 , 6 ] } }, computed : { evenNumbers ( ) { return this .numbers .filter (number => number % 2 === 0 ) } } }) const vm = app.mount ('#app' ) </script >
sort() 除了 filter()
可以通过表达式进行过滤,还可以通过 sort
来对数组进行排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <ui id="app" > <li v-for ="item in evenNumbers" :key ="item" > {{item}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { numbers : [1 , 20 , 2 , 3 , 4 , 100 ] } }, computed : { evenNumbers ( ) { return this .numbers .sort (sortNumbers) } } }) function sortNumbers (a,b ){ return a-b; } const vm = app.mount ('#app' ) </script >
slice().reverse() Vue 不仅提供了一个排序的 sort()
方法,还提供了 reverse()
方法来进行逆转,但这需要 slice()
切片后重新进行排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 <ui id="app" > <li v-for ="item in numbers.slice().reverse()" :key ="item" > {{item}}</li > </ui> <script > const app = Vue .createApp ({ data ( ) { return { numbers : [1 , 2 , 3 , 4 , 5 ] } } }) const vm = app.mount ('#app' ) </script >
template at value template 是一个字符串模板,用于组件的实例标记,木板将会替换所挂载元素的源 HTML,挂在的任何元素所有标记都会被忽略,因此通常可以使用 template 作为指令块进行使用,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <ui id="app" > <template v-for ="item in 10" :key ="item" > <li > {{item}}</li > </template > </ui> <script > const app = Vue .createApp ({ data ( ) { return { } } }) const vm = app.mount ('#app' ) </script >
这将会被渲染为以下 HTML 表达式:
1 2 3 4 <ul > <li > ...</li > ... </ul >
v-if and v-else Vue.js 为条件渲染提供了 v-if
以及 v-else
指令,其中 v-if
指令用于条件渲染一块内容,内容的表达式根据 truthy 值进行决定是否被渲染:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <div id="app" > <p v-if ="isMessage" > {{message}}</p > <p v-else ="isMessage" > This is v-else</p > </div> <script > const app = Vue .createApp ({ data ( ) { return { message : 'This is v-bind:style' , isMessage : false } } }) const vm = app.mount ('#app' ) </script >
当 isMessage
属性的 truthy 值为 false 时,则会使用 v-else
进行代替,但为了之后适用与更加复杂的结构中 v-else
需要指定属性。
template template 是一个字符串模板,用作组件(component) 实例标记,模板将会替代所挂载的元素内部 HTML(innerHTML)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <style> .error { border : 1px solid red; padding : 0. 5em; color : red; } </style> <div id ="app" > <template v-if ="isMessage" > <p v-if ="isMessage" > {{message}}</p > <p > hey,v-if</p > </template > <div v-else ="isMessage" :class ="{error: isErr}" > <p > This is v-else="isMessage"</p > </div > </div > <script > const app = Vue .createApp ({ data ( ) { return { message : 'This is v-bind:style' , isMessage : false , isErr : true } } }) const vm = app.mount ('#app' ) </script >
v-show 除 v-show
之外,Vue 还提供了另一条用于展示元素的 v-show
指令,他于 v-if
相差甚微:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <style> .error { border : 1px solid red; padding : 0. 5em; color : red; } .warn { border : 1px solid #ffaa00; padding : 0. 5em; color : #ffaa00; } </style> <div id ="app" > <div v-if ="isMessage" > <p > hey,v-if is "true"</p > </div > <div v-else-if ="isMessage === null" :class ="{error: isErr}" > <p > This is isMessage ="null"</p > </div > <div v-else-if ="isMessage === undefined" :class ="{error: isErr}" > <p > This is isMessage ="undefined"</p > </div > <div v-else :class ="{warn: isWarn}" > <p > hey,v-if is "false"</p > </div > <div v-show ="isMessage" > <p > Hey,world!</p > </div > </div > <script > const app = Vue .createApp ({ data ( ) { return { isMessage : false , isErr : true , isWarn : true } } }) const vm = app.mount ('#app' ) </script >
但不同的是 v-show
元素始终会被渲染并保留 DOM 中,因此 v-show
只是简单的切换元素的 display
属性。
与 v-if
的区别是他不支持 <template>
元素也不支持 v-else
指令
是 “真正” 的条件渲染,他会在切换的过程中,条件块内的事件监听器或子组件将会适当的被摧毁和更新。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 ## v-else-if 该指令可以充当 ```v-if``` 的 ```else-if``` 块且可林需的使用,但必须紧跟 ```v-if``` 或 ```v-else-if``` 的元素之后: ```js <style> .error { border: 1px solid red; padding: 0.5em; color: red; } .warn { border: 1px solid #ffaa00; padding: 0.5em; color: #ffaa00; } </style> <div id="app"> <div v-if="isMessage"> <p>hey,v-if is "true"</p> </div> <div v-else-if="isMessage === null" :class="{error: isErr}"> <p>This is isMessage ="null"</p> </div> <div v-else-if="isMessage === undefined" :class="{error: isErr}"> <p>This is isMessage ="undefined"</p> </div> <div v-else :class="{warn: isWarn}"> <p>hey,v-if is "false"</p> </div> </div> <script> const app = Vue.createApp ({ data() { return { isMessage: false, isErr: true, isWarn: true } } }) const vm = app.mount('#app') </script>
📖 more posts 📖