目录
<script src="https://unpkg.com/vue@next">script>
打开CDN链接,直接复制代码到本地js文件,再引入html
- <body>
- <div class="app">div>
-
- <script src="https://unpkg.com/vue@next">script>
- <script>
- const app = Vue.createApp({
- template:`
asdasdas
hehehe` - })
- //挂载
- app.mount(".app")
- script>
- body>
- <body>
- <div class="app">div>
-
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- template:`<h2>{{title}}h2><span>{{message}}span>`,
- data:function(){
- return {
- title:'hello word',
- message:'message'
- }
- }
- })
- //挂载
- app.mount(".app")
- script>
- body>app")
- <body>
- <div class="app">div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- template:`
- <h2>{{title}}h2>
- <ul>
- <li v-for="item in message">{{item}}li>
- ul>
- `,
- data:function(){
- return {
- message:['message','123','222']
- }
- }
- })
- app.mount(".app")
- script>
- body>
- <body>
- <div class="app">div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- template:`
-
计数器:{{counter}}
-
-
- `,
- data:function(){
- return {
- counter:0
- }
- },
- methods:{
- plus:function(){this.counter++},
- sub:function(){this.counter==0? this.counter=0:this.counter--},
- }
- })
- app.mount(".app")
- script>
- body>
上面的例子中,template都写的很别扭,因为是在··中写的,没有提示,可以改进为:
- <body>
- <div class="app">
- <h2>计数器:{{counter}}h2>
- <button @click='plus'>+1button>
- <button @click='sub'>-1button>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- counter:0
- }
- },
- methods:{
- plus:function(){this.counter++},
- sub:function(){this.counter==0? this.counter=0:this.counter--},
- }
- })
- app.mount(".app")
- script>
- body>
既将template内容直接写到div中,app.mount(".app")时会自动渲染这个div的内容
MVC和MVVM

在VUE中,VUE就是充当了viewmodel角色,他是一个桥梁,链接了model和view,能自己完成事件监听和数据展示,不需要人为写代码设置


methods中都是使用this.去调用变量,这里的this都是一个proxy对象,用于监听变量的改变,这里不能用箭头函数的原因也是这个,因为箭头函数没有this,当我们使用this时实际上是使用了window,这样就不能找到我们需要改变的变量了

上一章说了 {{}} 可以引入data函数中返回的变量,其实不仅仅是引入,甚至可以进行转换和计算
- <body>
- <div class="app">
- <h2>{{counter*2}}h2>
- <span>{{infos.split(' ')}}span>
- <h3>{{age>=18?'成年人':"未成年人"}}h3>
- <h2>{{gettime()}}h2>
-
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- counter:100,
- infos:'hello world',
- age:22
- }
- },
- methods:{
- gettime:function(){
- return '2022-12-1'
- }
- }
- })
- app.mount(".app")
- script>
- body>
可以在{{}}中进行计算和字符串变换,也就是说{{}}可以写表达式
上述例子中,在{{}}中完成了

对于{{counter}}
这个指令,如果在h2处增加v-once,变为:
<h2 v-once>{{counter}}h2>
这个v-once的意思是是只渲染一次,那么后期如果counter这个值改变了,那么h2显示的内容也不变
可以解析html命令字符串
- <div class="app">
- //解析字符串
- <h2 v-html="infos">h2>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- infos:`hhhhh`,
- }
- },
可以跳过解析过程,也就是说{{}} 直接当成大括号字符串处理
<h2 v-pre>{{counter}}h2>
结果就直接是{{counter}}
- <style>
- [v-cloak]{
- display: none;
- }
- style>
- head>
- <body>
- <div class="app">
- <h2 v-cloak>{{counter}}h2>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- counter:11,
- }
- },
- })
- setTimeout(()=>{
- app.mount(".app")
- },1000)
- script>
- body>
- html>
如果我给 app.mount(".app")设置间隔时间,1s之后再挂载div,也就是说1s之后h2中的counter才会变渲染变为11
正常情况下,前1s,浏览器显示的是 {{counter}} 1s之后显示 11
很显然这样是不好的,因为我们不希望用户看见代码内容,那么就可以使用v-cloak ,在没有渲染完毕时先隐藏这个内容,注意这里还需要在style中设置其作用
缓存一个模板的子树。在元素和组件上都可以使用。为了实现缓存,该指令需要传入一个固定长度的依赖值数组进行比较。如果数组里的每个值都与最后一次的渲染相同,那么整个子树的更新将被跳过
- <body>
- <div class="app">
- <div v-memo="[name]">
- <h2>{{name}}h2>
- <h2>{{age}}h2>
- <h2>{{gender}}h2>
- div>
- <button @click="update">button>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- name:'kobe',
- age:18,
- gender:'male'
- }
- },
- methods:{
- update:function(){
- this.gender='why'
- }
- }
- })
- app.mount(".app")
- script>
只有当我name变量发生更新时,别的变量才会更新,反之异然
也就是说上面的例子,点击按钮,gender不能更新
动态的绑定一个或多个 attribute,也可以是组件的 prop。
之前说的方法都是对 标签的内容 起作用,这个可以对 标签属性 进行赋值等操作
- class="app">
- <a v-bind:href="baidu">baidua>
-
- <script src="./lib/vue.js">script>
-
- const app = Vue.createApp({
- data:function(){
- return {
- baidu:'https://www.baidu.com'
- }
省略写法
<a :href="baidu">baidua>
例子:点击按钮改变颜色
- <style>
- .btnred{
- color: red;
- }
- style>
- head>
- <body>
- <div class="app">
- <button @click="update" :class="{btnred:isred}">btnnnbutton>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- isred:true
- }
- },
- methods:{
- update:function(){
- this.isred = !this.isred
- }
- }
- })
:class="{btnred:isred}"指的是,如果isred==true,则class =‘ btnred’,如果isred==false,则class = ‘’
这个地方按钮绑定函数,直接改变isred的值
相似的,如果要改变style内部的属性
- <div class="app">
- <button :style="{color: fontcolor}">btnnnbutton>
- div>
- data:function(){
- return {
- fontcolor :'red'
- }
- },
这个地方属性的名字,如果是类似于background-color这种属性,则需要使用 驼峰命名法 或者 加引号
- <body>
- <div class="app">
- <button v-bind = obj>btnnnbutton>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- obj:{name:'kobe',age:15,gender:'male'}
- }
- },
- })
- app.mount(".app")
- script>
- body>
可以直接用v-bind= obj 遍历obj里面的值键对 ,然后赋值给属性
![]()
对事件的绑定
- <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>
v-on修饰符

.stop 阻止冒泡,相当于在函数中写 event.stopPropagation()
- <button @click.stop="doThis">button>
当 name 里面有值时渲染 ul li 当没有值的时候渲染 h2
直接在 v-if = '判断语句' 在后面还可以使用 v-else v-else-if='判断语句'
- <body>
- <div class="app">
- <ul v-if="name.length>0">
- <li v-for = 'item in name'>{{item}}li>
- ul>
- <h2 v-else>无数据h2>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- name:[1,2,3]
- }
- },
- })
- app.mount(".app")
- script>
- body>

也就是说 v-if 如果为 false,那么这个内容将会直接被销毁
v-if 可以作为隐藏或者显示组件的依据,例如下面可以通过isshow变量控制div的隐藏
- <div v-if="isshow">
- <img src='https://game.gtimg.cn/images/yxzj/web201706/images/comm/floatwindow/wzry_qrcode.jpg'alt="">
- div>
这里也可以使用 v-show 效果是一样的
- <div v-show="isshow">
- <img src='https://game.gtimg.cn/images/yxzj/web201706/images/comm/floatwindow/wzry_qrcode.jpg'alt="">
- div>
v-show 和 v-if 区别

使用 “item in xxx”的格式遍历xxx,以获取内容item
- <body>
- <div class="app">
- <ul>
- <li v-for="item in name">{{item}}li>
- ul>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- name:[111,222,333,444]
- }
- },
- })
- app.mount(".app")
- script>
- body>
当然不仅仅是内容,也可以获取索引,注意是内容在前,索引在后
<li v-for="(item,index) in name">{{index}}:{{item}}li>
当然对于 对象,也可以采用这种方法
- <body>
- <div class="app">
- <ul>
- <li v-for="(item,key) in products">{{key}}:{{item}}li>
- ul>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- products:{name:'aaa',price:999}
- }
- },
- })
- app.mount(".app")
- script>
- body>

- <body>
- <div class="app">
- <ul>
- <li v-for="(item,index) in products">{{index}}:{{item}}li>
- ul>
- <button @click = 'deleteItem'>deleteItembutton>
- div>
- <script src="./lib/vue.js">script>
- <script>
-
- const app = Vue.createApp({
- data:function(){
- return {
- products:[111,222,333,444,555,666]
- }
- },
- methods:{
- deleteItem:function(){
- this.products.pop()
- }
- }
- })
- app.mount(".app")
- script>
- body>
点击按钮时,可以监听到数组的变化,并实时反馈到页面上


VNode
也就是说,我们之前使用
虚拟DOM
如果不是一个简单的div,而是一堆的元素,会形成一个VNode Tree,也就是虚拟DOM

为了理解 key属性的作用,这里看一个案例
- <body>
- <div class="app">
- <ul>
- <li v-for="item in products" :key="'item">{{item}}li>
- ul>
- <button @click = 'insert'>insertbutton>
- div>
- <script src="./lib/vue.js">script>
- <script>
-
- const app = Vue.createApp({
- data:function(){
- return {
- products:['a','b','c','d','e']
- }
- },
- methods:{
- insert:function(){
- this.products.splice(2,0,'f')
- }
- }
- })
- app.mount(".app")
- script>
- body>
这里遍历 数组,产生li ,按钮可以在 c 和 d中间插入一个f
在没有key属性时
a和b节点会只能复制,然后将c改为f,d改为c,最后增加一个节点放d

有key属性时
直接复用之前的c 和d,新增f插入

实际上有key属性时,所有操作都会遵循 “能复用就复用”的原则,大大增加了效率

这里通过一个小案例实现 双向绑定
- <body>
- <div class="app">
- <input type="text" :value="message" @input="messageChange">
- <h1>{{message}}h1>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- message:'hhhhh'
- }
- },
- methods:{
- messageChange(e){
- this.message = e.target.value
- }
- }
- })
- app.mount(".app")
- script>
- body>
将input输入框的内容与 massage变量双向绑定,message的值可以影响到input输入框的初始值,而输入之后也可以反过来影响message的值
现在使用v-model实现双向绑定
- <body>
- <div class="app">
- <input type="text" v-model="message">
- <h1>{{message}}h1>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- message:'hhhhh'
- }
- },
- })
- app.mount(".app")
- script>
- body>

对于单选框,返回值就是 true或者false
- <body>
- <div class="app">
- <input type="checkbox" v-model="message">aaa
- <h1>{{message}}h1>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- message:''
- }
- },
- })
- app.mount(".app")
- script>
- body>
对于多选框,返回应该是一个数组,且必须明确value值
- <body>
- <div class="app">
- <label for="aaa">
- <input id="aaa" type="checkbox" v-model="message" value="aaa">aaa
- label>
- <label for="bbb">
- <input id="bbb" type="checkbox" v-model="message" value="bbb">bbb
- label>
- <label for="ccc">
- <input id="ccc" type="checkbox" v-model="message" value="ccc">ccc
- label>
- <label for="ddd">
- <input id="ddd" type="checkbox" v-model="message" value="ddd">ddd
- label>
-
- <h1>{{message}}h1>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- message:[]
- }
- },
- })
- app.mount(".app")
- script>
- body>
对于rdiao,如果其使用v-model绑定相同的值,那么默认可以互斥
- <body>
- <div class="app">
- <label for="aaa">
- <input id="aaa" type="radio" v-model="message" value="male">male
- label>
- <label for="bbb">
- <input id="bbb" type="radio" v-model="message" value="womale">womale
- label>
- <h1>{{message}}h1>
- div>
- <script src="./lib/vue.js">script>
- <script>
- const app = Vue.createApp({
- data:function(){
- return {
- message:''
- }
- },
- })
- app.mount(".app")
- script>
- body>
如果在data中给message设置默认,例如‘womale’,那么radio初始会自动选择womale
之前的input都是在输入时,就实时的改变了message,加入lazy修饰符之后,只有在发生改变时才会改变message, 例如打回车键,鼠标点别的地方

- <div class="app">
- <input type="text" v-model.lazy="message">
- <h1>{{message}}h1>
- div>
如果message是数字类型,那么可以使用这个修饰符将变量保持为数字类型
- <div class="app">
- <input type="text" v-model.number="message">
- <h1>{{message}}{{typeof message}}h1>
- div>
去除首位空格
- <div class="app">
- <input type="text" v-model.trim="message">
- <h1>{{message}}h1>
- div>