Vue初识 朱雀 2021-11-23 00:32 314阅读 0赞 # 一. Vue的简单介绍 # 前端、django的重点简单描述: """ 1、BBS:前后台不分离的web项目 前台页面主要是通过后台逻辑完成渲染 2、Django:Python Web 框架 HttpResponse | ORM | 模板语言 | Forms | Auth 3、前端:HTML5 CSS3 JavaScript jQuery Bootstrap HTML5:页面架构 CSS3:选择器 样式 布局 JS:ES DOM BOM => 选择器拿到标签,操作标签,标签事件完成交互 DOM驱动 => Vue数据驱动 """ 前后端不分离值得是前端的数据都是由后端用语法渲染出来的,比如Django的render、redirect等,前端页面都是由它们渲染好然后返回的。前后端分离值得是前端后端服务器不同,各写各的,仅仅只进行数据的交互。前后端分离对于Django来说稍微麻烦一点,因为csrf跨站请求伪造的存在,Django无法从不是它渲染的页面中拿到csrf\_token,这就意味着前后端分离时,Django需要注释掉csrf中间件,然后需要我们自己写对应的验证。 vue框架: # Angular React Vue # js渐进式框架:一个页面小到一个变量,大到整个页面,均可以有vue控制,vue也可以控制整个项目 # 思考:vue如何做到一次引入控制整个项目 => 单页面应用 => vue基于组件的开发 # vue的工作原理:vue如何渲染一个页面 # vue的组件概念 # vue路由的概念 # vue的ajax概念 # 学习曲线:vue的指令 vue的实例成员 vue组件 vue项目开发 vue的优点: """ 1.单页面:高效 2.虚拟DOM:页面缓存 3.数据的双向绑定:数据是具有监听机制 4.数据驱动:从数据出发,不是从DOM出发 """ ## 1.1 vue的使用 ## """ 1.下载vue.js:https://vuejs.org/js/vue.js 2.在要使用vue的html页面通过script标签引入 3.在html中书写挂载点的页面结构,用id表示 4.在自定义的script标签实例化Vue对象,传入一个大字典 5.在字典中通过 el与挂载点页面结构绑定,data为其通过数据 """ 当然可以使用cdn,也可以直接在官网将vue的代码复制下来, 然后新建一个js文件黏贴即可。具体步骤如下: * 访问官网:[https://cn.vuejs.org/][https_cn.vuejs.org],点击教程 ![1635189-20190626230952383-1367414099.png][] * 按住ctrl + 鼠标左键 点击开发版本 ![1635189-20190626231201819-1553078509.png][] * 然后将其中的代码复制后在项目中新建一个js文件保存,后面直接再要使用的项目中script标签导入即可。 # 二. vue的简单使用 # 无论在使用一个框架还是一门开发语言,最重要的就是要学会看官方的文档,建议每天学习一下英语,达到能够阅读英语文档的能力。vue文档链接:[https://cn.vuejs.org/v2/guide/index.html][https_cn.vuejs.org_v2_guide_index.html] ## 2.1 vue初识 ## vue是通过new来实例化一个对象,然后该对象里面通过el来添加挂载点,data来给变量提供数据,methods来给挂载点提供事件。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue初始</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- { { vue变量 }} 插值表达式 里面的大括号最好在前面加个空格,增加浏览器的兼容性 --> <h1>{ { msg1 }}</h1> <h2>{ { msg2 }}</h2> </div> <!-- vue挂载点一次只能挂载一个,比如很多标签都继承同一个类,使用类选择器时, vue只会挂载找到的第一个标签,所以最好都使用标签选择挂载点 --> <!--<div class="app">--> <!--<h1>{ { msg1 }}</h1>--> <!--<h2>{ { msg2 }}</h2>--> <!--</div>--> </body> <!--将script写在body下面比较保险,可以不用考虑加载时从上往下执行可能发生的问题--> <script src="vue.js"></script> <script> // Vue new Vue({ el: '#app', //挂载点 data: { // 给各变量提供数据 变量名:变量的值 //vue的实例data中键值对,其实 键 都是字符串,只是省略了引号 msg1: 'h1的内容', msg2: 'h2的内容', }, methods:{ //为挂载点提供事件 函数名: function(){} } }) </script> </html> ## 2.2 vue完成简单的事件 ## vue是通过以下方式来给标签绑定事件: <!--绑定事件语法 v-on:事件名='函数名' --> <p v-on:click="clickMe">点我</p> <!--绑定事件语法简写 @事件名='函数名' --> <p @click="clickMe2">你也点我一下</p> 然后在vue对象的methods中写函数名与对应实现体的逻辑即可,具体代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue完成简单的事件</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!--绑定事件语法 v-on:事件名='函数名' --> <p v-on:click="clickMe">点我</p> <!--绑定事件语法简写 @事件名='函数名' --> <p @click="clickMe2">你也点我一下</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', methods: { // 为挂载点提供事件 clickMe : function () { alert(1111) }, clickMe2: function () { alert(2222) } } }) </script> </html> ## 2.3 vue简单操作样式 ## vue操作样式是通过控制标签的属性来实现的,控制样式通过以下方式: <!-- 属性指令:用vue绑定属性,将属性内容交给vue处理 --> <!-- 语法:v-bind:属性名="变量" (v-bind: 可以简写为 :) --> <p @click="clickMe" v-bind:style="col">点击当场变绿</p> 当然还可以给样式写成字典的形式,通过不同变量控制不同的样式: <!-- 一个{}:{}内一个个属性有一个个变量单独控制 --> <!--这里只需在data中定义col与fs两个变量的值即可--> <p @click="clickMe" v-bind:style="{color: col,'font-size': fs}">点击当场变绿</p> 注意,以上font-size不加引号时需要写为驼峰体:**fontSize。** ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue操作样式</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <p @click="clickMe" v-bind:style="col">点击当场变绿</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { // 需要以字典的形式改值,因为style是color:red;的形式 col: {color: 'green'} }, methods: { clickMe: function () { //this代表的是整个vue对象 this.col = {color: 'red'} } } }) </script> </html> 小例子一 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>操作样式</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- 一个{}:{}内一个个属性有一个个变量单独控制 --> <p @click="clickMe" v-bind:style="{color: col,'font-size': fs}">点击当场变绿</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { fs: '20px', col: 'green', }, methods: { clickMe: function () { this.col = 'red'; this.fs = '25px'; } } }) </script> </html> 小例子二 ## 2.4 文本指令 ## vue通过以下方式来实现文本指令: <!-- 插值表达式就是 v-text --> <p>{ { msg1 }}</p> <p v-text="msg2"></p> <!-- 可以解析html标签 --> <p v-html="msg3"></p> <!-- 必须赋初值,渲染的结果永远不会发生改变 --> <p v-once="msg3" @click="clickMe">{ { msg3 }}</p> ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文本指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- 插值表达式就是 v-text --> <p>{ { msg1 }}</p> <p v-text="msg2"></p> <!-- 可以解析html标签 --> <p v-html="msg3"></p> <!-- 必须赋初值,渲染的结果永远不会发生改变 --> <p v-once="msg3" @click="clickMe">{ { msg3 }}</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { msg1:'**msg1**', msg2:'<h2>msg2</h2>', msg3:'<h2>msg3</h2>', }, methods:{ clickMe:function () { // var msg = this.$data.msg3; // 实例中要访问一阶变量比如el、data等,需要加$,this.$el, // 一般要访问二阶的直接this.二阶变量 即可 this.msg3 = '<h2>msg3666</h2>' } } }) </script> </html> 小例子 ## 2.5 事件指令 ## 前面稍微提了以下vue简单的事件绑定,这里再来看看: <!-- v-on:事件名="函数名" 可以简写为 @事件名="函数名" (v-on: => @)--> <p v-on:click="action1">{ { msgs[0] }}</p> <p @click="action2">{ { msgs[1] }}</p> 实际上,当绑定事件的时候是可以给函数传参的,在函数名后面加个括号表示传参,而且默认是有一个event对象传过去的,当加了括号之后,无论你传多少参数,都需要加一个参数$event,不然event对象就会失效。 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <ul id="app"> <!-- v-on:事件名="函数名" 可以简写为 @事件名="函数名" (v-on: => @)--> <!-- 事件的传参 --> <li @click="action(111)">列表项1</li> <li @click="action(222)">列表项2</li> <li @click="action(333)">列表项3</li> <li @click="actionMouse">列表项4</li> <!-- 鼠标事件的对象:直接写函数名,默认将鼠标事件对象传入 --> <div @click="func1">func1</div> <!-- 鼠标事件的对象:一旦添加(),就必须手动传参,$event就代表鼠标事件对象 --> <div @click="func2($event, 'abc')">func2</div> </ul> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', methods:{ action:function (num) { alert(num) }, actionMouse:function (event) { console.log(event) }, func1: function (ev) { console.log(ev) }, func2: function (ev, msg) { console.log(ev); console.log(msg) } } }) </script> </html> 小例子 ## 2.6 属性指令 ## vue属性指令通过以下方式实现: <!-- 属性指令:用vue绑定属性,将属性内容交给vue处理 --> <!-- 语法:v-bind:属性名="变量" (v-bind: 可以简写为 :) --> <p class="" style="" v-bind:owen="oo" :jason="jj"></p> 当“”中再以''将变量放在里面是,变量就不再时变量,而是常量: <!-- br'是变量 --> <p :class="[c1, 'br']"></p> <!-- 'br' 固定写死的数据,不再是变量 --> <p :class="[c1, 'br']"></p> ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>属性指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> div { width: 100px; height: 100px; } .gDiv { background-color: green; } .rDiv { background-color: red; } .br { border-radius: 50%; } </style> </head> <body> <div id="app"> <div @click="clickMe" :class="c1"></div> <!-- 属性指令:用vue绑定属性,将属性内容交给vue处理 --> <!-- 语法:v-bind:属性名="变量" (v-bind: 可以简写为 :) --> <div :class="[c1, c2]"></div> <!-- 'br' 固定写死的数据,不再是变量 --> <div :class="[c1, 'br']"></div> </div> </body> <script src="vue.js"></script> <script> new Vue({ el:'#app', data:{ c1: 'rDiv', c2: 'br' }, methods:{ clickMe:function () { if(this.c1=='rDiv'){ this.c1='gDiv' }else { this.c1 = 'rDiv' } } } }) </script> </html> 小例子 ## 2.7 表单指令 ## 属性指令是通过on-bind或者是简写:来实现,但是在form表单中,value属性要使用on-model来实现控制: <!-- 表单指令:v-model="变量" --> <input type="text" v-model="val"> <!-- 单选框 v-model绑定的变量是单选框中某一个input的value --> <p> 男: <input v-model="r_val" value="male" type="radio" name="sex"> 女: <input v-model="r_val" value="female" type="radio" name="sex"> </p> ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表单指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <!-- 表单指令:v-model="变量" --> <form id="app"> <p>username<input v-model="val" type="text" name="username"></p> <p>re_username<input v-model="val" type="text" name="re_username"></p> <div> <!-- 单选框 v-model绑定的变量是单选框中某一个input的value --> 男<input v-model="sex" type="radio" name="sex" value="male"> 女<input v-model="sex" type="radio" name="sex" value="female"> </div> <div> <!-- 复选框 v-model绑定的变量是一个列表,列表存存放0到任意个复选框的value --> 男<input v-model="hobby" type="checkbox" name="hobby" value="male"> 女<input v-model="hobby" type="checkbox" name="hobby" value="female"> 哇塞<input v-model="hobby" type="checkbox" name="hobby" value="ws"> </div> <button>提交</button> </form> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data:{ val:'', sex:'male', hobby:['male', 'female'], } }) </script> </html> 表单指令的小例子 ## 2.8 条件指令 ## 条件指令分为两种: <!-- 条件指令 v-show | v-if--> <!-- v-show:消失是以 display: none渲染 当v-show的值为false时触发 --> <div v-show="s1"></div> <!-- v-if:消失时不会被渲染渲染,所以建议建立缓存, 用key属性 --> <div class="wrap red" v-if="tag==0" :key="0"></div> <div class="wrap green" v-else-if="tag==1" :key="1"></div> <div class="wrap blue" v-else key="2" :key="'2"></div> <!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 --> <!-- 通过key全局属性操作后,渲染过的分支会建立key对应的缓存,提高下一次渲染速度 --> 条件指令中v-show和v-if的循环,里面是可以直接写false或true的,他们会自动解析为布尔值,不会将它们当做变量。 v-show不写条件默认是false,即display:none隐藏标签。 v-else会默认与v-if等有条件的分支绑定。 v-else-if必须有条件才和有条件v-if分支绑定。 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>模板</title> </head> <body> <div id="app"> <p v-if="r1" key="p_r1">if条件</p> <p v-show="r2">show条件</p> <!--{ { num + 1 - 5 * 2 + '好的' }}--> <ul> <!--v-else会默认与v-if等有条件的分支绑定--> <!--v-else-if必须由条件才和有条件v-if分支绑定--> <!--可以删除各分支的条件来进行验证--> <li v-if="tag == 1">111</li> <li v-else-if="tag == 2">222</li> <li v-else>333</li> </ul> <ul> <li @click="action('a')">a</li> <li @click="action('b')">b</li> <li @click="action('c')">c</li> </ul> <ul> <li v-show="flag == 'a'">aaa</li> <li v-show="flag == 'b'">bbb</li> <li v-show="flag == 'c'">ccc</li> </ul> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { num: 10, r1: false, r2: false, tag: 2, flag: 'a' }, methods: { action: function (s) { this.flag = s } } }) </script> </html> 分支绑定验证 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>条件指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> .wrap { width: 300px; height: 100px; } .red { background-color: red;} .green { background-color: green;} .blue { background-color: blue;} </style> </head> <body> <div id="app"> <!-- 条件指令 v-show | v-if--> <!-- v-show:消失是以 display: none渲染 当v-show的值为false时触发 --> <div v-show="s1"></div> <ul> <li @click="action(0)" style="float: left">red</li> <li @click="action(1)" style="float: left">green</li> <li @click="action(2)" style="float: left">blue</li> </ul> <!-- v-if:消失时不会被渲染渲染,所以建议建立缓存, 用key属性 --> <div class="wrap red" v-if="tag==0" key="0"></div> <div class="wrap green" v-else-if="tag==1" key="1"></div> <div class="wrap blue" v-else key="2" key="'2"></div> <!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 --> <!-- 通过key全局属性操作后,渲染过的分支会建立key对应的缓存,提高下一次渲染速度 --> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data:{ tag:0, s1:false }, methods:{ action:function (tag) { this.tag=tag } } }) </script> </html> 小例子 ## 2.9 循环指令 ## 循环指令语法如下: <!-- v-for="item in items" --> <!-- 遍历的对象: 数组[] 对象(字典){} --> 当遍历数组时,可以用两个参数来获取值与索引: <!-- n为遍历的元素值 --> <ul> <li v-for="n in list">{ { n }}</li> </ul> <!-- n为遍历的元素值, index为索引 --> <ul> <li v-for="(n, index) in list">{ { n }}{ { index }}</li> </ul> 当遍历自定义对象\{\}时,可以有三个参数: <!-- v-for变量对象{}时,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引 --> <ul> <li v-for="(v, k, i) in dic" :key="k">value:{ { v }} | key:{ { k }} | index: { { i }}</li> </ul> 在很多时候,为了增加渲染的速度,需要建立缓存: <!-- 一般列表渲染需要建立缓存 --> <!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind:处理 --> <!-- v-for变量数组[]时,接收两个值时,第一个为元素值,第二个为元素索引 --> <ul> <li v-for="(n, i) in list" :key="i">value:{ { n }} | index: { { i }}</li> </ul> ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>循环指令</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- v-for="item in items" --> <!-- 遍历的对象: 数组[] 对象(字典){} --> <ul> <!-- 只遍历数组的值 --> <li v-for="num in nums">{ { num }}</li> </ul> <ul> <!-- 遍历数组的值与索引 --> <li v-for="(num, index) in nums">{ { num }} { { index }}</li> </ul> <ul> <!-- 自定义对象(字典)的 值、键、索引 --> <li v-for="(v, k, index) in dic">{ { v }} { { k }} { { index }}</li> </ul> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data:{ nums:[5, 2, 3, 1, 4], dic:{ name: 'json', age: '18', gender: 'male' } }, }) </script> </html> 小例子 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <div id="app"> <h1>{ { msg }}</h1> <!-- v-for="item in items" --> <!-- 遍历的对象: 数组[] 对象(字典){} --> <ul> <li>{ { list[0] }}</li> <li>{ { list[1] }}</li> <li>{ { list[2] }}</li> <li>{ { list[3] }}</li> <li>{ { list[4] }}</li> </ul> <!-- n为遍历的元素值 --> <ul> <li v-for="n in list">{ { n }}</li> </ul> <!-- 一般列表渲染需要建立缓存 --> <!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind:处理 --> <!-- v-for变量数组[]时,接收两个值时,第一个为元素值,第二个为元素索引 --> <ul> <li v-for="(n, i) in list" :key="i">value:{ { n }} | index: { { i }}</li> </ul> <ul> <li>{ { dic['name'] }}</li> <li>{ { dic.age }}</li> <li>{ { dic.gender }}</li> </ul> <!-- v-for变量对象{}时,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引 --> <ul> <li v-for="(v, k, i) in dic" :key="k">value:{ { v }} | key:{ { k }} | index: { { i }}</li> </ul> <!-- 遍历的嵌套 --> <div v-for="(person, index) in persons" :key="index" style="height: 21px;"> <div v-for="(v, k) in person" :key="k" style="float: left;">{ { k }} : { { v }} </div> </div> </div> <script type="text/javascript"> new Vue({ el: "#app", data: { msg: "列表渲染", list: [1, 2, 3, 4, 5], dic: { name: 'zero', age: 88888, gender: 'god' }, persons: [ {name: "zero", age: 8}, {name: "egon", age: 78}, {name: "liuXX", age: 77}, {name: "yXX", age: 38} ] } }) </script> 内含循环的嵌套 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>发表评论示例</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> span { margin-left: 100px; } /*利用伪类选择器,鼠标悬浮是将字体颜色变为红色*/ span:hover { color: red; } </style> </head> <body> <div id="app"> <input type="text" v-model="val"> <button @click="action">提交评论</button> <ui> <!--将索引拿出当做事件函数的参数,方便删除--> <li v-for="(msg, index) in msgs">{ { msg }}<span @click="del(index)">X</span></li> </ui> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { val: '', //存放即将发表的评论内容 msgs: ['hello', 'world'], //存放评论 }, methods:{ action:function () { //其实splice可完成数组的增删改,他有三个参数,第一个是从哪个索引开始(不包含当前索引) //第二个参数是操作几个值,第三个参数是将操作的值替换为什么,不写则替换为空,相当于删除 this.msgs.splice(0,0,this.val); this.val = '' //输入评论框置空 }, del:function (index) { this.msgs.splice(index,1) //删除留言 } } }) </script> </html> 发表评论小例子 # 三. 实例成员computed、watch # 前面实例成员用到了el、data、methods,接下来再补充一下computed、watch,它们的作用都是监听,但是监听的对象是相反的,computed监听函数内的变量,watch监听函数外的变量。 ## 3.1 computed ## 监听方法内所有的变量,返回值给绑定的变量,该变量无需在data中声明,只要里面监听的变量值发生变化,就会马上执行一次该函数。 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>实例成员之computed</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> 姓:<input type="text" v-model="first_name"> 名:<input type="text" v-model="last_name"> <p style="margin-top: 5px">姓名:<input type="text" v-model="full_name"></p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el:'#app', data:{ first_name: '', last_name: '', }, /* 计算 -- 监听方法内所有的变量,返回值给绑定的变量,该变量无需在data中声明, 只要里面监听的变量值发生变化,就会马上执行一次该函数 */ computed:{ full_name:function () { return this.first_name + this.last_name } } }) </script> </html> 小例子 ## 3.2 watch ## 监听绑定的变量,绑定的变量必须在data中声明,只要监听的变量值发生变化,就会立马执行该函数,该函数的返回值是没有任何意义的,所以不需要return。 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>实例成员之watch</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <p>姓名:<input type="text" v-model="full_name"></p> 姓:<input type="text" v-model="first_name"> 名:<input type="text" v-model="last_name"> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data:{ first_name:'', last_name:'', full_name:'' }, watch:{ /* 监听绑定的变量,绑定的变量必须在data中声明, 只要监听的变量值发生变化,就会立马执行该函数, 该函数的返回值是没有任何意义的,所以不需要return */ full_name:function () { //前端支持切分空 'abc' ->> ['a', 'b', 'c'] //python不支持切分空,会报错,不过可以通过list('abc')达到同样的效果 let name = this.full_name.split(''); this.first_name = name[0]; this.last_name = name[1]; } } }) </script> </html> 小例子 ## 3.3 delimiters ## 使用Django时,前往模板渲染语法用的是\{ \{ \}\},而vue的插值表达式也是一样,所以一起使用时会存在冲突的问题。这时候就需要用到delimiters来改变插值表达式的语法: // 为解决与前端模板语法的冲突,可以使用delimiters自定义插值表达式的语法 // delimiters:['插值表达式前半部分', '后半部分'] delimiters:['${', '}'] ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>解决插值表达式冲突</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <p>{ { msg }}</p> <p>${ msg }</p> </div> </body> <script src="vue.js"></script> <script> new Vue({ el: '#app', data: { msg: 'hello world' }, // 为解决与前端模板语法的冲突,可以使用delimiters自定义插值表达式的语法 delimiters:['${ ', '}'] }) </script> </html> 小例子 # 四. 组件 # **组件的概念**: * 每一个组件都是一个vue实例 * 每个组件均具有自身的模板template,根组件的模板就是挂载点 * 每个组件模板只能拥有一个根标签 * 子组件的数据具有作用域,以达到组件的复用 使用vue时,实际项目中大多使用局部组件。局部组件与全局组件都拥有各自的名称空间,这是通过将成员data的值赋予一个return 字典 的的function来实现的。 ## 4.1 根组件 ## 根组件就是我们使用挂载点生成的vue实例: <div id="app"> <h1>{ { msg }}</h1> </div> <script type="text/javascript"> // 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件) // 每个组件均拥有模板,template var app = new Vue({ // 根组件的模板就是挂载点 el: "#app", data : { msg: "根组件" }, // 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量 // 显式书写模块,就会替换挂载点,但根组件必须拥有挂载点 template: "<div>显式模板</div>" }) // app.$template </script> 其中html与body不能作为挂载点,因为显式书写模块会替换挂载点,而html与body是不能被替换,会报错。这里挂载点使用通用选择器时会从上往下,将找到的第一个标签作为挂载点,而第一个标签就是html标签,所以通用选择器\*不能使用。 ## 4.2 局部组件 ## 局部组件是通过定义变量,变量的值为一个大字典,而字典中书写的形式同vue实例中的书写形式相同。局部组件与全局组件的模板可以是是在template中书写的部分,而不会使用挂载点,挂载点用于根组件。 局部组件使用前要在父组件的components中注册,然后使用时当做一个自定义标签使用即可。 let localTag = { template:` <p @click="action">点了我{ { count }}下</p> `, // 1.data要达到组件的复用,必须为每个组件提供一个名称空间(作用域) // 2.data的值就是一个存放数据的字典 // 需要满足1和2,data值为一个可以产生名称空间的函数的返回值,返回值是字典 data:function () { return { count: 0 } }, methods:{ action:function () { this.count++ } } }; //父组件 new Vue({ el: '#app', // 局部组件必须在父组件的components中注册 components:{ // 注册局部组件的别名: 局部组件原名 //当取的名字与局部组件名字相同时可以这么简写 localTag: localTag // 简写:localTag } }) template中要书写多行html代码时,使用ESC键下面的 **\`\` **即可。 局部组件 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] let localTag = { template:` <p @click="action">点了我{ { count }}下</p> `, // 1.data要达到组件的复用,必须为每个组件提供一个名称空间(作用域) // 2.data的值就是一个存放数据的字典 // 需要满足1和2,data值为一个可以产生名称空间的函数的返回值,返回值是字典 data:function () { return { count: 0 } }, methods:{ action:function () { this.count++ } } }; 小例子 ## 4.3 全局组件 ## 全局组件通过通过Vue的一个方法来实现,使用时也是当自定义标签来使用,不需要去父组件中注册。 Vue.component(组件名, {组件主体}); 全局组件与局部组件的取名都采用驼峰体的形式,而html中是不区分大小写的,所以在标签中建议使用 - 语法命名,对应js中就是驼峰命名:即local-tag等于localTag。 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>全局组件</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> p { width: 100px; height: 100px; border: solid; } </style> </head> <body> <div id="app"> <!--在标签中建议使用 - 语法命名,对应js中就是驼峰命名--> <global-tag></global-tag> <global-tag></global-tag> </div> </body> <script src="vue.js"></script> <script> //全局组件 Vue.component(组件名, {组件主体}); // 全局组件无需注册 Vue.component('globalTag', { template:` <p @click="action">点了我{ { count }}下</p> `, data:function () { return { count: 0 } }, methods:{ action:function () { this.count++ //this.count += 1 } } }); //父组件 new Vue({ el:'#app', }) </script> </html> 小例子 ## 4.4 组件间的数据交互--父传子 ## 父组件向子组件传输数据时,是通过在自定义属性来实现的,如下: <global-tag :hello="msg"></global-tag> 子组件名为globalTag,在其中定义自定义属性hello,因为该标签是在父组件中,所以变量msg的值由父组件来提供,然后在子组件中通过**props:\['hello'\]**来然内部可以使用hello变量,而hello属性的值又来自于父组件的msg变量,这就实现了父组件传输数据给子组件。注意:props内部走的实际上是反射,所以它存储值的列表中必须都是字符串的形式。 ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- local-tag就可以理解为自定义标签,使用msg变量值由父组件提供 --> <!-- local-tag标签代表的是子组件,owen为标签的自定义属性 --> <!-- 在子组件内部能拿到owen,就可以拿到父组件的信息 --> <global-tag :hello="msg"></global-tag> </div> </body> <script src="vue.js"></script> <script> //全局组件,是Vue的子组件 Vue.component('globalTag', { // 子组件拿自定义属性 props:['hello'], template:` <p @click="action">{ { hello }}</p> `, }); //父组件 new Vue({ el:'#app', data:{ msg: '这是父组件的信息' } }) </script> </html> 小例子 ## 4.5 组件间的数据交互--子传父 ## 首先子组件向父组件传输数据时,要知道什么时候传,所以就需要使用事件。子组件中通过事件,在事件函数中使用**this.$emit('自定义事件名', 给父组件的数据),**而子组件是当做自定义标签的方式在父组件中使用的,所以自定义事件的函数需要父类提供,而此时自定义事件的函数就能结束子组件传输的参数,也就是emit中第二个参数携带的数据。 this.$emit('alter', this.msg) <!--通过@子组件自定义事件名,在父组件的事件函数中拿到子组件的传参--> <local-tag @alter="get_title"></local-tag> <!--父组件通过事件函数拿到子组件传输的数据--> get_title: function (msg) { this.msg = msg 具体事例如下: ![ContractedBlock.gif][] ![ExpandedBlockStart.gif][] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件间的交互-子传父</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!--通过@子组件自定义事件名,在父组件的事件函数中拿到子组件的传参--> <local-tag @alter="get_title"></local-tag> <p>{ { msg }}</p> </div> </body> <script src="vue.js"></script> <script> let localTag = { //template中只能有一个根标签 template:` <div> <input type="text" v-model="msg"> <button @click="action">修改父组件信息</button> </div> `, data: function(){ return { msg: '' } }, methods:{ action:function () { //$emit('自定义事件名', '参数') this.$emit('alter', this.msg) } }, // watch:{ // msg:function () { // this.$emit('alter', this.msg) // } // } }; new Vue({ el: '#app', data: { msg: '这是父组件的信息' }, methods: { get_title: function (msg) { this.msg = msg } }, components:{ localTag } }) </script> </html> 转载于:https://www.cnblogs.com/maoruqiang/p/11094593.html [https_cn.vuejs.org]: https://cn.vuejs.org/ [1635189-20190626230952383-1367414099.png]: /images/20211122/27961c02a39a4902a8526b7c6025479c.png [1635189-20190626231201819-1553078509.png]: /images/20211122/cbc7dda2e9304866b14dad23d7a5b8a5.png [https_cn.vuejs.org_v2_guide_index.html]: https://cn.vuejs.org/v2/guide/index.html [ContractedBlock.gif]: https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif [ExpandedBlockStart.gif]: /images/20211122/ba1563680b6c4109921455ef932b0219.png
相关 初识VUE 一、什么是VUE Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScr 谁践踏了优雅/ 2024年03月30日 16:24/ 0 赞/ 74 阅读
相关 Vue|初识Vue ![968f4c3a9001403aaa609f4e85ac2933.gif][] > Vue是一款用于构建用户界面的JavaScript框架。它基于标准HTML、CSS和J 比眉伴天荒/ 2023年09月24日 17:55/ 0 赞/ 60 阅读
相关 初识Vue 上一节搭建了vue的简单项目的开发环境,这一节来说说Vue的基本使用 > 初识Vue: 1. 想让程序运行,必须要创建一个Vue实例,且传入配置对象(el) 2. 我不是女神ヾ/ 2022年09月13日 15:22/ 0 赞/ 206 阅读
相关 Vue之初识Vue 前言 如果你之前已经习惯了用jQuery操作DOM,学习Vue.js时请先抛开手动操作DOM的思维, 因为Vue.js是数据驱动的,你无需手动操作DOM。它通过一些特 逃离我推掉我的手/ 2022年05月16日 05:53/ 0 赞/ 285 阅读
相关 初识vue vue 我们先认识一下什么是vue?其实就是用来构建用户界面的渐进式框架,vue指令就是操作DOM命令而准备的。安装或引用[vue][]你也可以查[开发文档][Link 小灰灰/ 2022年03月20日 13:00/ 0 赞/ 233 阅读
相关 初识VUE 一、什么是vue vue是一个渐进式的前端js框架。所谓渐进式框架,其实就是把框架分层。最核心的部分是视图层渲染,然后往外是组件机制,在这个基础上再加入路由机制、状态管理 深藏阁楼爱情的钟/ 2022年02月25日 12:50/ 0 赞/ 297 阅读
相关 Vue初识 渐进式JavaScript框架 通过对框架的了解与运用程度,来决定其在整个项目中的应用范围,最终可以独立以框架的形式完成整个web前端项目 什么是Vue vue可 清疚/ 2021年11月29日 10:42/ 0 赞/ 322 阅读
相关 Vue初识 一. Vue的简单介绍 前端、django的重点简单描述: """ 1、BBS:前后台不分离的web项目 前台页面主要是通过后台逻 朱雀/ 2021年11月23日 00:32/ 0 赞/ 315 阅读
还没有评论,来说两句吧...