Vue基础学习
1.vue基础
1.1 Vue下载安装
1.1.1js文件安装
进入网站:https://cn.vuejs.org
下载:学习--教程--左侧的安装---下载开发版,点击进入,复制---到项目中创建vue.js文件,将内容复制即可,用script引入
<script type="text/javascript" src="Vue/vue.js" ></script>1
<script type="text/javascript" src="Vue/vue.js" ></script>3.或者可以直接引入
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>1
1
1
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>1.1.2 win下安装node.js
- 下载安装:
- http://nodejs.cn/
- 下载msi的版本,安装即可
- 测试:
- 打开cmd,输入node进入,然后就可以测试了
- 退出:两次Ctrl+c
- 查看版本号: npm -v
若是没有版本号,需要修改环境变量:在用户变量的path中加上:C:\Users\jsy\AppData\Roaming\npm
1.1.3安装命令行工具MobaXterm
打开即可使用;
配置:打开Settings

- 安装cnpm
- 方法1:
npm install -g cnpm --registry=https://registry.npm.taobao.org
//但是这样版本可能会不一致x
1
npm install -g cnpm --registry=https://registry.npm.taobao.org2
//但是这样版本可能会不一致- 方法2:
或者你直接通过添加 npm 参数 alias 一个新命令:
alias cnpm="npm --registry=https://registry.npm.taobao.org \
--cache=$HOME/.npm/.cache/cnpm \
--disturl=https://npm.taobao.org/dist \
--userconfig=$HOME/.cnpmrc"5
5
1
或者你直接通过添加 npm 参数 alias 一个新命令:2
alias cnpm="npm --registry=https://registry.npm.taobao.org \3
--cache=$HOME/.npm/.cache/cnpm \4
--disturl=https://npm.taobao.org/dist \5
--userconfig=$HOME/.cnpmrc"1.1.3vue-cli下载和安装
使用node.js(MobaXterm )安装vue-cli
- 安装vue-cli: cnpm install vue-cli -g
- 初始化项目: vue init webpack my-project
- 安装项目依赖 cnpm install
- 在locallot启动测试服务器 : npm run dev
- 生成上线日录(部署) : npm run build
- 具体使用
具体使用

vue版本2.9.6,输入 vue --help 有一下内容

- 查看版本
vue -V111vue -V
- 查看官方提供的模板
vue list //速度回有点慢111vue list //速度回有点慢

- 使用webpack搭建项目
vue init webpack my-project //搭建项目
接下来是配置:
项目名
描述
作者
安装vue-router y
代码校验ESLint n
测试工具tests 看个人需要 n
e2s tests 测试工具 n
生成项目;
启动项目:
1.安装依赖:
进入项目文件夹my-project
cnpm install //安装依赖 node_modules
npm run dev //启动项目
生成部署用的文件:
npm run build //运行之后,会有一个dist目录17
17
1
vue init webpack my-project //搭建项目2
接下来是配置:3
项目名4
描述5
作者6
安装vue-router y7
代码校验ESLint n8
测试工具tests 看个人需要 n9
e2s tests 测试工具 n10
生成项目;11
启动项目:12
1.安装依赖:13
进入项目文件夹my-project14
cnpm install //安装依赖 node_modules15
npm run dev //启动项目16
生成部署用的文件:17
npm run build //运行之后,会有一个dist目录1.1.4 sublime text 添加vue高亮
1.准备语法高亮插件vue-syntax-highlight。
下载zip并解压;
2.进入sublime,首选项--浏览插件目录,在打开的文件夹中创建“Vue”文件夹。
3.在Vue文件夹中,将vue-syntax-highlight-master压缩包解压后的所有文件考入
4.按下快捷键“ctrl+shift+p”,在打开的packages输入框中输入vue,选择“Set Syntax:Vue Component”进行加载。

加载后重启sublime,重新打开.vue文件,即能看到语法高亮
1.1.5 安装vuex
在项目中安装
cnpm install vuex --save
//若是重启了工具,要重新把上面的npm转cnpm的代码运行一下,
安装完之后,重新运行项目
npm run dev5
5
1
在项目中安装2
cnpm install vuex --save3
//若是重启了工具,要重新把上面的npm转cnpm的代码运行一下,4
安装完之后,重新运行项目5
npm run dev
1.1.6 安装vue-resource
cnpm install vue-resource1
1
1
cnpm install vue-resource1.1.7 json-server 虚拟的后端(只能get)
cnpm install json-server --save
打开项目,进入build 打开dev-server.js文件,
在第四行express下:
var jsonServer=require('json-server')
在第16行var app = express()之下写
var jsonServer=new jsonServer()
在最底下module.exports之前设置:
var jsonServer=require('json-server')
var apiserver=jsonServer.create()
var apirouter=jsonServer.router('db.json')//此目录是项目的目录,放置此文件到项目文件夹中
var middlewares=jsonServer.defaults()
apiserver.use(middlewares)
apiserver.use('/api',apirouter)
apiserver.listen(3000,function () {//监听的接口,
console.log('JSON Server is running')
})
19
19
1
cnpm install json-server --save2
打开项目,进入build 打开dev-server.js文件,3
在第四行express下:4
var jsonServer=require('json-server')5
在第16行var app = express()之下写6
var jsonServer=new jsonServer()7
在最底下module.exports之前设置:8
9
10
var jsonServer=require('json-server')11
var apiserver=jsonServer.create()12
var apirouter=jsonServer.router('db.json')//此目录是项目的目录,放置此文件到项目文件夹中13
var middlewares=jsonServer.defaults()14
apiserver.use(middlewares)15
apiserver.use('/api',apirouter)16
apiserver.listen(3000,function () {//监听的接口,17
console.log('JSON Server is running')18
})19
配置后端接口路径
打开config中的index.js文件,其中配置的就是后端1
1
1
打开config中的index.js文件,其中配置的就是后端1.1.8虚拟后端接口
var apiServer = express()
var bodyParser = require('body-parser')
apiServer.use(bodyParser.urlencoded({ extended: true }))
apiServer.use(bodyParser.json())
var apiRouter = express.Router()
var fs = require('fs')
apiRouter.route('/:apiName')//动态设置路由接口
.all(function (req, res) {
fs.readFile('./db.json', 'utf8', function (err, data) {
if (err) throw err
var data = JSON.parse(data)
if (data[req.params.apiName]) {//判断是否有这个接口
res.json(data[req.params.apiName])//设置返回值
}
else {
res.send('no such api name')
}
})
})
apiServer.use('/api', apiRouter);
apiServer.listen(port + 1, function (err) {
if (err) {
console.log(err)
return
}
console.log('Listening at http://localhost:' + (port + 1) + '\n')
})30
30
1
var apiServer = express()2
var bodyParser = require('body-parser')3
apiServer.use(bodyParser.urlencoded({ extended: true }))4
apiServer.use(bodyParser.json())5
var apiRouter = express.Router()6
var fs = require('fs')7
apiRouter.route('/:apiName')//动态设置路由接口8
.all(function (req, res) {9
fs.readFile('./db.json', 'utf8', function (err, data) {10
if (err) throw err11
var data = JSON.parse(data)12
if (data[req.params.apiName]) {//判断是否有这个接口13
res.json(data[req.params.apiName])//设置返回值14
}15
else {16
res.send('no such api name')17
}18
19
})20
})21
22
23
apiServer.use('/api', apiRouter);24
apiServer.listen(port + 1, function (err) {25
if (err) {26
console.log(err)27
return28
}29
console.log('Listening at http://localhost:' + (port + 1) + '\n')30
})1.2 vue概述
生命周期
1.2.1 挂载点、模板、实例的关系
挂载点:就是页面的标签,vue只会处理挂载点下面的内容
<div id="root"></div>1
1
1
<div id="root"></div>模板:挂载点内部的内容,都是模板内容,可以写在挂载点(标签中),也可以写在template中.
显示的时候,显示的是template中定义的内容,页面本身的内容会去掉
<body>
<div id="root">{{msg}}</div><!--显示msg中内容-->
</body>
<script>
/*创建一个vue实例,让这个实例接管页面上的id为root的标签*/
new Vue({
el:"#root", /*绑定:id为root的*/
template:'<h1>你好,{{msg}}</h1>',/*在root内部设置内容*/
data:{
msg:"hello world"
}
})
</script>13
13
1
<body>2
<div id="root">{{msg}}</div><!--显示msg中内容-->3
</body>4
<script>5
/*创建一个vue实例,让这个实例接管页面上的id为root的标签*/6
new Vue({7
el:"#root", /*绑定:id为root的*/8
template:'<h1>你好,{{msg}}</h1>',/*在root内部设置内容*/9
data:{10
msg:"hello world"11
}12
})13
</script>实例: 在vue实例中的data中,可以设置任意的名字,只要用{{ }}就可以显示
1.2.1 vue实例显示方法(html,text)
1.用{{ }}显示
{{msg}}1
1
1
{{msg}}2.在标签上使用v-text显示:(若是HTML格式的内容,会直接将标签显示)
<h1 v-text='msg'></h1>1
1
1
<h1 v-text='msg'></h1>3.在标签上使用v-html显示:(会将标签转义,显示处理后的页面样式)
<h1 v-html='msg'></h1>1
1
1
<h1 v-html='msg'></h1>1.2.2 vue点击事件
点击标题,将标题的内容改为123
- 点击标题时,调用root的vue中的handleClick方法,将vue的data中的msg改为123;
绑定点击事件的方法:
1.使用 v-on:click='handleClick'
2.使用 @click='handleClick'
注意:写方法的时候,方法要写在vue的methods中
<body> <div id="root"> <h1 v-on:click='handleClick'>{{msg}}</h1> <!--设置点击方法--> </div> <!--显示msg中内容--> </body> <script> new Vue({ el : "#root", /*绑定:id为root的*/ data : { msg : "hello world" }, methods : { handleClick : function() { his.msg = "123" } } }) </script> |
1.2.3 Vue中的属性绑定
(1)属性绑定
使用:
(1)v-bind:
(2):3
3
1
使用:2
(1)v-bind:3
(2):<!--使用v-bind对title中的内容绑定,绑定为data中title中的内容--> <div v-bind:title="title">hello world</div><!--v-bind可以省略--> ------------- new Vue({ el:"#root", /*绑定:id为root的*/ data:{ title:"this is hello world", } }) | ![]() |
| <div v-bind:title="'123 '+title">hello world</div> | 则页面上提示内容为:123 this is hello world |
简化:
| <div :title="title">hello world</div> |
(2):绑定class
这种class绑定不会冲突,页面上回自动整合未一个class的两个样式
| <div :class="link" class="aaa"></div> 在data中: link:'class1' |
- 绑定多个class(class对象)
link:{ 'class1':true, 'class2':false }//true的class会在页面显示 |
- 数组形式class
| link:['class1','class2'] |
或者:
| <div :class="[classA,classB]" class="aaa"></div> ---------------------- classA:'cla1', classB:'cla2', |
- 混合使用:
| <div :class="[classA,{'classB':iferror}]" class="aaa"></div> ****************** classA:'cla1', classB:'cla2', iferror:true |
1.2.4 双向数据绑定 v-model
v-model双向绑定,当INPUT中的内容变的时候,下面div中的内容也会变
<input v-model="content"/> <!--v-model双向绑定,当INPUT中的内容变的时候,下面div中的内容也会变--> <div>{{content}}</div> | ![]() |
(1)绑定表达式
- 支持三元表达式
{{content?content:"你好"}}
当content有值的时候显示值,没有的时候显示"你好"2
2
1
{{content?content:"你好"}}2
当content有值的时候显示值,没有的时候显示"你好"(2)lazy修改器:延迟修改
只有当修改完之后,点击了enter或者失去焦点的时候,才会修改,input必须定义type为text
<input type="text" v-model.lazy="myVlaue" /><!--延迟-->
{{myVlaue}}2
2
1
<input type="text" v-model.lazy="myVlaue" /><!--延迟-->2
{{myVlaue}}(3)number数字转为number格式
<input type="text" v-model.number="myVlaue" /><!--延迟-->
{{typeof myVlaue}} 输出的是类型2
2
1
<input type="text" v-model.number="myVlaue" /><!--延迟-->2
{{typeof myVlaue}} 输出的是类型
注意:是数字格式的会转化为number,但是字符串的不会影响
(4)trim去掉前后空格
<input type="text" v-model.trim="myVlaue" /><!--延迟-->
{{myVlaue}}2
2
1
<input type="text" v-model.trim="myVlaue" /><!--延迟-->2
{{myVlaue}}1.2.5 Vue中的计算属性(多个属性)
姓:<input v-model="firstName"/> 名:<input v-model="lastName"/> <div>{{firstName}}{{lastName}}</div> | ![]() |
| 整合之后: 姓:<input v-model="firstName"/> 名:<input v-model="lastName"/> <div>{{fullName}}</div> -------------- new Vue({ el:"#root", /*绑定:id为root的*/ data:{ firstName:"", lastName:"" }, computed:{/*计算属性,表示一个属性通过另一个属性计算而来*/ fullName:function(){ return this.firstName+' '+this.lastName; } } }) | ![]() |
(1)案例:获取输入中的数据,将数字清掉,只显示其他部分
- 方法1:使用计算属性
<input type="text" v-model.trim="myVlaue" /><!--延迟--> {{myVlaueNoNumber}} |
computed:{ myVlaueNoNumber:function (){ return this.myVlaue.replace(/\d/g,'') } |
- 方法2:添加事件:
定义方法: getValue:function(){ return this.myVlaue.replace(/\d/g,'') }调用: {{getValue()}} 显示: ![]() |
- 区别:
- 计算属性只会根据其中调用的值改变(只有这个值改变的时候,他才会变);
- 方法只要调用就会进行数据处理
1.2.6 Vue中的侦听器,监听: watch
watch监听的属性的方法可以有两个值,一个新值,一个旧值
watch:{
myVlaue:function(val,oldVal){}
}3
3
1
watch:{2
myVlaue:function(val,oldVal){}3
}()
当姓或名做了改变的时候,count+1,使用watch监听器
姓:<input v-model="firstName"/> <!--v-model双向绑定,当INPUT中的内容变的时候,下面div中的内容也会变--> 名:<input v-model="lastName"/> <div>{{fullName}}</div> <div>{{count}}</div> ------------- new Vue({ el:"#root", /*绑定:id为root的*/ data:{ firstName:"", lastName:"", count:0 }, computed:{/*计算属性*/ fullName:function(){ return this.firstName+' '+this.lastName; } }, watch:{ /*监听firstName*/ firstName:function () { this.count++; }, lastName:function () { this.count++; } } }) |
![]() |
此处监听的是firstName和lastName,也可以监听fullName,只要fullName改变,就count++
1.2.7 v-if, v-show与v-for指令
(1)案例:点击按钮,标签显示、隐藏
- v-if
<div id="root"> <!--只有show是true的时候,标签才会存在--> <div v-if='show'>hello world</div> <button @click='handleClick'>toggle</button> </div> -------------- new Vue({ el:"#root", data:{ show:true, }, methods:{ handleClick:function(){ this.show=!this.show;//将show的值取反 } } }) |
- v-show
| 上述代码,直接将v-if换为v-show即可,使用时,结果相同 |
![]() |
- v-else
<a v-if="isshow">456</a> <a v-else>123</a> |
(2)v-for 案例:将list中的内容,循环展示出来
遍历的时候,item of list ,用in或of都可以
<ul> <!--遍历list中的内容,定义Wieitem,将他显示--> <li v-for="item of list":key="item">{{item}}</li> </ul> ------------- data:{ show:true, list:[1,2,3] }, | ![]() |
注意:,使用了key,要求item中的内容不能相同,(list中的内容不能相同)
若是list中有相同的内容,使用index:
<!--item放的是内容,index放的是下标,用index作为key值,就不会重复了--> <li v-for="(item,index) of list":key="index">{{item}}</li> |
- 对象列表
list:[ { name:'apple', price:323 },{ name:'aaa', price:1123 } ] | ![]() |
| <div v-for="(item,index) in list":key="index">{{item.name}}---{{item.price}}--{{index}}</div> | |
| 也可以直接在标签中引用: <div v-for="(item,index) in list":key="index" v-text="item.name+'---'+item.price+'---'+index"></div> | |
- 遍历对象
<div v-for="(value,key) in objlist" >{{value}}---{{key}}</div>
objlist:{
name:'app',
price:123,
color:'red'
}6
6
1
<div v-for="(value,key) in objlist" >{{value}}---{{key}}</div>2
objlist:{3
name:'app',4
price:123,5
color:'red'6
}(3)v-if, v-show区别
v-if:当为false的时候,会之间将代码移除;
v-show:当为false的时候,会display为隐藏none;
当需要频繁的显示隐藏的时候,v-show更好,它不需要重新创建,性能更高;只需要一次的话,v-if更好;
(4)v-for 操作class
<div v-for="(item,index) in list" :class="{odd:index%2}">{{index}}</div>1
1
1
<div v-for="(item,index) in list" :class="{odd:index%2}">{{index}}</div>当index%2有余数的时候odd显示
(5)案例:当点击提交的时候,input的内容显示在list中,在页面显示(同步更新)
<!--当点击提交的时候,input的内容显示在list中,在页面显示--> <div id="root"> <div> <input v-model="inputValue"/> <button @click="handleSubmit">提交</button> </div> <ul> <li v-for="(item,index) of list":key="index">{{item}}</li> </ul> </div> </body> <script> new Vue({ el:"#root", data:{ inputValue:'', list:[] }, methods:{ handleSubmit:function(){ //点击提交的时候,将input的值放到list中 this.list.push(this.inputValue) this.inputValue=''//将inputValue设置W为空,这样输入框就会自动为空了 } } }) </script> |
(5)数据列表修改数据
为列表中某一项修改数据
- 直接修改----不会自动更新
- 使用vue的setfnagfa
<button @click="changelist">changelist</button>
-----------------
methods:{
changelist:function (){
Vue.set(this.list,1,123)
}
}7
7
1
<button @click="changelist">changelist</button>2
-----------------3
methods:{4
changelist:function (){5
Vue.set(this.list,1,123)6
}7
}1.2.8 组件
组件:指页面的某些部分
(1)全局组件
//将页面显示的ul部分作为一个组件, //Vue.component创建的是全局组件 Vue.component('todo-item',{ template:'<li>item</li>' //模板(其中的HTML代码) }) -----------调用: <ul> <!--使用组件--> <todo-item></todo-item> </ul> |
(2)局部组件
- 局部组件声明
var TodoIrem={
template:'<li>item</li>'
}3
3
1
var TodoIrem={2
template:'<li>item</li>' 3
}由于是局部的,需要在要使用的实例哪里声明
new Vue({
el:"#root",
components:{ //做组件声明
'todo-item':TodoItem
//若是左右相同,可以只写一边的 TodoItem
},6
6
1
new Vue({2
el:"#root",3
components:{ //做组件声明4
'todo-item':TodoItem5
//若是左右相同,可以只写一边的 TodoItem 6
},- 组件使用:
- 方法1:
<todo-item></todo-item> <!--一样-->1
1
1
<todo-item></todo-item> <!--一样-->- 方法2:使用is引入
<p is='todo-irem'></p>1
1
1
<p is='todo-irem'></p>方法2优势,可以动态的使用组件,使用:is 的时候,可以引用变量
动态引入:
<p :is='getTodo'></p>
data中: getTodo:'todo-irem'3
3
1
动态引入:2
<p :is='getTodo'></p>3
data中: getTodo:'todo-irem'(3)子组件多级调用
var my2={ template:'<div>123456</div>', } //创建一个子组件 var my1={ template:'<div><my2></my2></div>',//多级调用,要在这里 components:{ //my1 'my2':my2 } } new Vue({//根组件 el: '#app', data: { content: 'Hello' }, components:{ 'my':my1 } }) |
(4)子组件data赋值
子组件要避免引用赋值,
//创建一个子组件 var my1={ template:'<div>{{f}}<my2></my2></div>', components:{ //my1 'my2':my2 }, data :function(){//也可以使用 data (){ return{ f:2 } } }![]() |
(3)组件与实例的关系
每一个组件,就是一个实例,每一个组件上都可以定制方法等内容

(4)父组件向子组件传递数据组件通信
- 父组件向子组件传递数据,属性:
- 父组件调用的时候,设置:key=value,(key是父组件的数据的key)
- 子组件接收参数:使用props接收参数,就可以正常调用了
- 子组件方法中可以用this.xxx调用数据
- 注意,key值设置的时候大小写不敏感,要使用-,props中也是,当时子组件调用的时候,使用的是驼峰的样式.
- 使用全局组件完成input提交显示,
<!--使用组件--> <todo-item v-for="(item,index) of list" :key="index" :content="item" > <!--设置key值,1.传参--> </todo-item> |
| 设置全局组件,接收参数,显示内容 Vue.component('todo-item',{ props:['content'],//2.接收参数content template:'<li>{{content}}</li>' //3.设置显示模板(其中的HTML代码)也可以在页面中调用 }) |
(5)props接收参数
接收参数可以是list格式,也可以是对象格式:
| props:['aaa','bbb'] |
对象格式:
props:{ 'aaa':[Number,String,Object]//指定参数运行的格式 } |
(6)子组件向父组件传递事件
1.子组件的模板中添加时间(vue事件);
2.在事件中,通过 this.$emit('delete-a',this.index) 创建自定义的事件,并传递参数,自定义的事件不支持驼峰形式.
3.在父组件中调用子组件的时候,在标签中用@...调用这个事件,@...='父组件中的方法名',
4.在父组件中编写方法,
5.调用子组件的事件的时候,调用的就会是父组件的方法了.
- 案例:下方的删除功能
(7)插槽:子组件显示父组件定义的标签
在父组件中调用子组件,再向子组件的标签中添加内容的时候,不会显示,只会显示子组件本身的内容
<todo-irem><!--调用子组件,子组件中有内容<li>i123131132tem</li>-->
<p>123</p>
</todo-irem>3
3
1
<todo-irem><!--调用子组件,子组件中有内容<li>i123131132tem</li>-->2
<p>123</p>3
</todo-irem>只会显示:
子组件本身定义的内容
想要这部分内容显示,可以在子组件的模板中使用标签
| template:'<div><li>i123131132tem</li><slot></slot></div>' 在子组件中加上这个标签,就会把父组件调用的时候添加的内容显示 ![]() 注意:子组件必须在一个大标签之下, |
- 插槽设置默认内容
当插槽没有设置的时候,默认显示内容
| template:'<div><li>i123131132tem</li><slot>没有内容</slot></div>' , |

- 插槽设置名字
<todo-irem><!--调用子组件,子组件中有内容<li>i123131132tem</li>--> <p slot='header'>header插的内容 </p> <!--<p slot='footer'> footer插的内容</p>--> </todo-irem> |
| template:'<div><li>i123131132tem</li><slot name="header">header没有内容</slot><slot name="footer">footer没有内容</slot></div>', |
(8)动态组件is
在父组件中声明子组件之后,在页面中:
| <p :is='getTodo'></p> |
这样就可以动态设置了,getTodo是data中的属性,通过改变它的值改变绑定的子组件
| getTodo:'todo-irem' |
(9)组件缓存:<keep-alive>
<keep-alive> <p :is='getTodo'></p> </keep-alive> |
当组件从a切换到b,的时候,a就会缓存起来,从b切换回a的时候,直接读缓存
1.2.9案例: 删除功能(子组件向父组件传递事件)
- 已有功能:
点击提交,会将input中的内容保存到list,子组件会遍历list,设置为item,以content传递到props,在template中显示.
- 需要实现:
要想删除子组件,在每一条上加上click方法,删除的时候,要删除的是父组件list中的内容.调用的是子组件的方法,删除父组件的数据,需要两个组件之间进行通信(此时需要子组件中,这一条的下标,来和父组件中对应).
- 传递顺序:
1.点击子组件(显示的内容中)的方法handleClick(click方法),调用方法, this.$emit创建在父组件中显示的名(@...自定义事件)和参数,在父组件中调用@...(<xxx调用子组件)之后的方法注意,自定义事件不支持驼峰形式
<body> <!--当点击提交的时候,input的内容显示在list中,在页面显示--> <div id="root"> <div> <input v-model="inputValue"/> <button @click="handleSubmit">提交</button> </div> <ul> <!--在父组件中调用子组件----使用组件--> <todo-item v-for="(item,index) of list" :key="index" :content="item" :index="index" @delete-a="handleDelete" > <!--设置key值,1.传参,下标,--> <!--监听子组件的delete事件,当子组件触发了delete事件的时候,调用方法handleDelete(父组件的方法)--> </todo-item> </ul> </div> </body> <script> //将页面显示的ul部分作为一个组件, //Vue.component创建的是全局组件 Vue.component('todo-item',{ props:['content',"index"],//2.接收参数content template:'<li @click="handleClick">{{content}}</li>', //3.设置显示模板(其中的HTML代码) methods:{ handleClick:function(){ //调用$emit,调用自定义的事件,传入接收的下标值 this.$emit('delete-a',this.index) } } }) //局部组件 //var TodoItem={ // template:'<li>item</li>' //} new Vue({ el:"#root", // components:{//做组件声明 // 'todo-item':TodoItem // }, data:{ inputValue:'', list:[] }, methods:{ handleSubmit:function(){ //点击提交的时候,将input的值放到list中 this.list.push(this.inputValue) this.inputValue=''//将inputValue设置W为空,这样输入框就会自动为空了 }, handleDelete:function (index) { //删除list中对应下标的内容,即可删除页面中的数据 //从下标位置,删除一项 this.list.splice(index,1) } } }) </script> </html> |
1.3vue事件和表单
1.3.1全局api
实例对象创建完之后,还可以进行操作
实例对象有一个对象名root
var root=new Vue({
el: '#app',
data: {
content: 'Hello'
}
})7
7
1
实例对象有一个对象名root2
var root=new Vue({3
el: '#app',4
data: {5
content: 'Hello'6
}7
})| root.$data | 可以获取data数据 |
| root.$on('emit',function () {}) | 可以绑定方法 |
1.3.1事件绑定
除了click之外,还常用的方法是keydown方法,一般监听的键盘是enter
| 当按键为回车的时候,进行的操作: <input @keydown.enter="tokeydown" /> 也可以指定其他的按键,比如: @keydown.13 |
1.3.2多选框/单选框,数据绑定
将多选框中的数据绑定到数组中
(1)单选框数据绑定
<input v-model="myBox" type="radio" value="111" />
<input v-model="myBox" type="radio" value="222" />
<input v-model="myBox" type="radio" value="333" />
{{myBox}}
--------------
myBox:[]6
6
1
<input v-model="myBox" type="radio" value="111" />2
<input v-model="myBox" type="radio" value="222" />3
<input v-model="myBox" type="radio" value="333" />4
{{myBox}}5
--------------6
myBox:[](2)多选框数据绑定
<input v-model="myBox" type="checkbox" value="111" />
<input v-model="myBox" type="checkbox" value="222" />
<input v-model="myBox" type="checkbox" value="333" />3
3
1
<input v-model="myBox" type="checkbox" value="111" />2
<input v-model="myBox" type="checkbox" value="222" />3
<input v-model="myBox" type="checkbox" value="333" />(3)select下拉框绑定
<select v-model="sel">
<option value="1">11</option>
<option value="2">22</option>
<option value="3">33</option>
</select>
{{sel}}
------------
sel:null8
8
1
<select v-model="sel">2
<option value="1">11</option>3
<option value="2">22</option>4
<option value="3">33</option>5
</select>6
{{sel}}7
------------8
sel:null(4)v-for 遍历下拉绑定
<select v-model="sel">
<option v-for="item in seloption" :value="item.value">{{item.text}}</option>
</select>
{{sel}}
------------
sel:null,
seloption:[
{text:'app1',value:1},
{text:'app2',value:2},
{text:'app3',value:3},
]11
11
1
<select v-model="sel">2
<option v-for="item in seloption" :value="item.value">{{item.text}}</option>3
</select>4
{{sel}}5
------------6
sel:null,7
seloption:[8
{text:'app1',value:1},9
{text:'app2',value:2},10
{text:'app3',value:3},11
]一般情况,这种下拉会创建一个组件,直接调用组件:
<vSelect @onSelect='' :list="seloption"></vSelect>1
1
1
<vSelect @onSelect='' :list="seloption"></vSelect>1.4 vue高级功能
1.4.1过渡(动画效果)
要与v-show,v-if 动态组件结合
1.给需要过渡的元素外层加transition ,并用name命名
| show:true, --------------------- <button @click="show=!show">button</button> <transition name='fade'> <p v-show="show">456</p> </transition> |
(1)css过渡

- 淡入淡出
| show:true, --------------------- <button @click="show=!show">button</button> <transition name='fade'> <p v-show="show">456</p> </transition> -------------------- 在style中定义样式 <style> .fade-enter-active,.fade-leave-active{ transition:/*opacity*/ all .5s ;/*属性,时长,还可以加上ease-out,代表变化的曲线*/ /*指定当前样式有过渡效果,opacity代表透明度*/ } .fade-enter,.fade-leave-active{ opacity:0; /*进入和出去的时候透明度是0*/ } </style> |
- 上下左右滑入滑出
/*激活阶段,动画控制,*/ .my-trans-enter-active,.my-trans-leave-active{ transition: all .5s ease-out;/*属性,时长,还可以加上,代表变化的曲线*/ } /*控制动画具体怎么变*/ /*进入动画控制*/ .my-trans-enter{ /*进入从上方滑入*/ transform: translateY(-500px); opacity: 0; } .my-trans-leave-active{ /*出去,向下滑出*/ transform: translateY(500px); opacity:0; /*进入和出去的时候透明度是0*/ /*指定当前样式有过渡效果,opacity代表透明度*/ } |
组件设置过渡
<transition name='my-trans'>
<div :is='getTodo'></div>
</transition>
<button @click="getTodoFun">button</button>
---------------
getTodo:'todo-irem'
------------
getTodoFun:function(){
if(this.getTodo==='todo-irem'){
this.getTodo='todo-irem2'
}else{
this.getTodo='todo-irem'
}
}14
14
1
<transition name='my-trans'>2
<div :is='getTodo'></div>3
</transition>4
<button @click="getTodoFun">button</button>5
---------------6
getTodo:'todo-irem'7
------------8
getTodoFun:function(){9
if(this.getTodo==='todo-irem'){10
this.getTodo='todo-irem2'11
}else{12
this.getTodo='todo-irem'13
}14
}多元素过渡
多个元素切换,是将新的在下方显示,在将旧的隐藏,有同时出现的机会,默认是in-out
使用out-in,会先将就的去掉,再显示新的 <transition name='my-trans' mode='out-in'> <p v-show="show">456</p> </transition> |
注意,多个元素的时候,过渡动画会消失,需要定义key区分每一个元素
<button @click="show=!show">button</button> <transition name='fade' mode='out-in'> <p v-if="show" key='1'>456</p> <p v-else key='2'>11178911</p> </transition> |
(2)JS过渡
- js控制动画,是通过v-on事件控制的.
- 使用js过渡的时候,要在transition中绑定 v-bind:css='false' 防止css样式的影响
<!--进入前,进入过程中,离开--> <transition @before-enter='beforeEnter' @enter='enter' @leave='leave' :css='false'> <p class='js-class' v-show="show" >456</p> </transition> |
.js-class{ position: absolute; top: 50px; left: 50px; color: red; } |
使用js操作动画: beforeEnter:function(el){ $(el).css({ left:'-500px', opacity:0 }) }, enter:function(el,done){ $(el).animate({ left:'50px',/*进入的时候,跑到left到50位置*/ opacity:1 },{ duration:1500,/*执行的ms数*/ complete:done /*完成的之后*/ }); }, leave:function(el,done){ $(el).animate({ left:'500px',/*离开的时候,向右移动500px后消失*/ opacity:0 },{ duration:1500,/*离开时间*/ complete:done }) } |
动画会在左右动作,没有定义的top不会有影响 |
1.4.2 自定义指令
使用的v-if等是内置的指令,
(1)局部自定义指令
在一个组件中定义的,只能在这一个组件中使用
定义自定义指令,使用
directives:{ //自定义指令color,binding是传入的值 color:function(el,binding){ el.style.color=binding.value } } |
使用自定义指令:
| <p v-color="'red'">hello123</p> 传入的值使用"' '"包裹着 ![]() |
(2)全局自定义指令
只需要把自定义的指令放到根节点的组件中定义即可
(3)更细致定义
一个自定义对象可以定义几个钩子函数,
没有声明的时候,默认是bind和update
| bind: | 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 |
| inserted | 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。 |
| update | 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。 |
| componentUpdated | 指令所在组件的 VNode 及其子 VNode 全部更新后调用 |
| unbind | 只调用一次,指令与元素解绑时调用。 |
//自定义指令color color:{ bind:function(el,binding){ el.style.color=binding.value }, inserted:function(el){ } } |
(4)案例:input获取光标
focus:{ inserted:function(el,binding){ el.focus() } } |
| <input type="text" v-focus /> |
1.4.3插件
在vue项目的package.json文件中,就可以看到项目的依赖
- 安装插件
- 使用node.js,进入项目包,输入: cnpm install vue-router --save
- 再次打开package.json可以看到这插件
- 引用插件
- 在要调用的vue文件中进行引用,若是所有的页面都会用到的,可以在main.js中引用
- import VueRouter from 'VueRouter '
- 也可以 import VueRouter from ' vue-router'
- 也可以 var VueRouter =require( ' vue-router' )
- 注册使用
- Vue.use(VueRouter )
- 正式引入
- 方法1:
- 定义: let router=new VueRouter ()
- 在组建中引入router,
- 方法2: 若是已经引入了vueresource,可以直接在组建中定义
- this.$http.get('')

2.vue-cli
2.1vue-cli概述
Vue-cli-vue 官方提供的脚手架工具
- 作用:初始化一个Vue项目
- 优势:
- 成熟的vue项目架构设计
- 本地测试服务器
- 集成打包上线方案
- 要求:
- Node.js(>=4.x)
- Git
- 一个能使用node的命令行终端
启动项目:
npm run start1
1
1
npm run start一个template中只能有一个根元素,
定义参数data要用function



style可以加上scoped使样式局部
2.1.1es6语法
- 导出:
- 将Hello.vue导出
- 方法1:

- 方法2:

- 导入:

- 声明变量
- 在当前作用域下:let
- 本文件都可以取到var
- 常量:const router=new VueRouter
- 引入数据
在组建中使用data,要使用return的方式
<script> export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } } } </script> |
2.1.2 vue-rouer 路由
(1)安装/配置:
进入项目目录:(在搭建项目的时候安装了)
cnpm install vue-router --save
项目中载入,一般在main.js中载入:
import VueRouter from 'vue-router'
Vue.use(VueRouter)
let router = new VueRouter({}) //其中配置路径和地址
在Vue中引入:
new Vue({
el: '#app',
router,
template: '<APP/>',
components: { APP }
})14
14
1
进入项目目录:(在搭建项目的时候安装了)2
cnpm install vue-router --save3
4
项目中载入,一般在main.js中载入:5
import VueRouter from 'vue-router'6
Vue.use(VueRouter)7
let router = new VueRouter({}) //其中配置路径和地址8
在Vue中引入:9
new Vue({10
el: '#app',11
router,12
template: '<APP/>',13
components: { APP }14
})(2)基础案例:路径访问(映射表)
路径:http://localhost:8080/apple/ ,访问一个页面
- 定义一个vue页面Apple:
<template> <div class="apple">213124</div> </template> <script> export default { name: 'Apple' } </script> <style scoped> </style> |
- 在new VueRouter({})所在页面引入:
| import Apple from '@/components/Apple' |
- 在new VueRouter({}) 中引入:
routes: [ mode:'history', { path:'/apple', component:Apple }, { path:'/apple2', component:Apple2 } |
- 在APP.vue中引入(会在这里显示)
<router-view></router-view>![]() |
(3)页面内跳转
要在 mode:'history', 之下
<router-link :to="{path:'apple'}">to apple</router-link> <router-link :to="{path:'apple2'}">to apple2</router-link> |
(4)路由参数

路由参数在映射表中进行
设置参数:
path:'/apple/:color',
页面:
http://localhost:8080/apple/red
获取参数:
在Apple.vue获取:
<div >{{$route.params}}</div> { "color": "red" }
<div >{{$route.params.color}}</div> red
在Apple.vue方法中获取:this.$route.params9
9
1
设置参数:2
path:'/apple/:color',3
页面:4
http://localhost:8080/apple/red5
获取参数:6
在Apple.vue获取:7
<div >{{$route.params}}</div> { "color": "red" }8
<div >{{$route.params.color}}</div> red9
在Apple.vue方法中获取:this.$route.params
点击按钮,显示参数:{ "color": "red" }这种情况下,路径上若是没有参数,将会不能进入这个页面
多个参数:
path:'/apple/:color/deee/:aa',
其中:color和:aa是用户可以自定义的参数,可以是任何内容;
deee是路径,不能修改
可以的访问路径为:http://localhost:8080/apple/red/deee/asas
只有带: 的参数才会在$route.params中5
5
1
path:'/apple/:color/deee/:aa',2
其中:color和:aa是用户可以自定义的参数,可以是任何内容;3
deee是路径,不能修改4
可以的访问路径为:http://localhost:8080/apple/red/deee/asas5
只有带: 的参数才会在$route.params中(5)路由嵌套(子路由)
{ path:'/apple', component:Apple, childdren:[ { path:'/childapple/', component:ChildApple } ] }, |
| 在这个页面import引入 |
内容要在Apple.vue中添加
| <router-view></router-view> |
页面跳转:

(6)router-link,页面内跳转,声明试导航
普通页面跳转
<router-link :to="{path:'apple'}">to apple</router-link>
基于当前路径跳转
<router-link :to="'apple'">to apple</router-link>
根目录:
<router-link :to="'/apple'">to apple</router-link>
动态设置:
<router-link :to="apple">to apple</router-link>
在data中:
data(){
reurn{
apple:'apple'
}
}
传递参数:
<router-link :to="{path:'apple',param:{color:'red'}}">to apple</router-link>
可以访问 apple/red(参数)
改变router-link显示样式:
<router-link :to="'apple'" tag="li">to apple</router-link>18
18
1
<router-link :to="{path:'apple'}">to apple</router-link>2
基于当前路径跳转3
<router-link :to="'apple'">to apple</router-link>4
根目录:5
<router-link :to="'/apple'">to apple</router-link>6
动态设置:7
<router-link :to="apple">to apple</router-link>8
在data中:9
data(){10
reurn{11
apple:'apple'12
}13
}14
传递参数:15
<router-link :to="{path:'apple',param:{color:'red'}}">to apple</router-link>16
可以访问 apple/red(参数)17
改变router-link显示样式:18
<router-link :to="'apple'" tag="li">to apple</router-link>(7)js中定义导航,跳转
router.push('apple') //或 {path:'apple'}
或
this.$router.push('/login');3
3
1
router.push('apple') //或 {path:'apple'}2
或3
this.$router.push('/login');(8)路由命名
{
path:'/apple',
component:Apple,
name:'applePage'
}
访问:
<router-link :to="{name:'applePage'}">to apple</router-link>8
8
1
{2
path:'/apple',3
component:Apple,4
name:'applePage'5
6
}7
访问:8
<router-link :to="{name:'applePage'}">to apple</router-link>- 命名路由视图
在router-view 上添加name
<router-view name='viewA '></router-view>1
1
1
<router-view name='viewA '></router-view>路由表中可以根据name定义页面
{
path:'/apple',
component:{
viewA:Apple,
viewB:OtherApple,
},
name:'applePage'
}8
8
1
{2
path:'/apple',3
component:{4
viewA:Apple,5
viewB:OtherApple,6
},7
name:'applePage'8
}(9)路由重定向
比如默认页面是具体的某一个页面,比如访问根目录,会自动跳转到Apple.vue目录
{ path:"/", redirect:'/apple' }, |
(10)页面跳转--过渡
<transition name='fff'>
<keep-alive><!--缓存-->
<router-view></router-view>
</keep-alive>
</transition>5
5
1
<transition name='fff'>2
<keep-alive><!--缓存-->3
<router-view></router-view>4
</keep-alive>5
</transition>2.2vuex 状态管理
2.2.1引入
在全局中引用:(在main.js中的vue中引用)
import Vuex from 'vuex' /*引入*/
Vue.use(Vuex) /*使用*/
let store=new Vuex.Store({ /*调用*/
state:{/*数据中心的数据*/
totalPrice:0
},
mutations: {/*动作*/
increment(state, price) {/*增加*/
state.totalPrice += price
},
decrement(state, price) {/*减*/
state.totalPrice -= price
}
}
})
new Vue({ |
其他文件调用:
在上面引用之后,每个组件都可以使用:
this.$store.state.totalPrice |
(1)案例:全局加减
创建Apple和Banana两个vue文件,在APP.vue中引入
方法1:
<template> |
每一个vue组件都有一个+1和-1的按钮
<template> |
方法2:
let store=new Vuex.Store({ /*调用*/ |
addOne(){ |
- 在Store中还可以设置getters获取数据
getters:{/*获取数据*/ |
可以定义多个状态集,最后汇总



2.3 vue-resource:整合ajax
在main.js中
import VueResource from 'vue-resource'
Vue.use(VueResource)
每一个页面都可以使用this.$http 4
4
1
在main.js中2
import VueResource from 'vue-resource'3
Vue.use(VueResource)4
每一个页面都可以使用this.$http 2.3.1 ajax案例
- get:
/*ajax请求 */
this.$http.get('api/getNewsList')
.then((res) => {/*成功回调*/
this.newsList = res.data //赋值
}, (err) => {/*失败回调*/
console.log(err)
})7
7
1
/*ajax请求 */2
this.$http.get('api/getNewsList')3
.then((res) => {/*成功回调*/4
this.newsList = res.data //赋值5
}, (err) => {/*失败回调*/6
console.log(err)7
})- post
this.$http.post(this.GLOBAL.urlHead+'manager/login',{managerUserName:this.ruleForm.username,managerPass:this.ruleForm.password},{emulateJSON:true})
.then((res) => {/*成功回调*/
if (res.data.state==1) {
alert(res.data.msg)
localStorage.setItem('managerName',res.data.data.managerName);//ms_username
localStorage.setItem('managerId',res.data.data.managerId);//ms_username
this.$router.push('/index');
}else {
alert(res.data.msg)
}
}, (err) => {/*失败回调*/
console.log(err)
alert("登录失败!")
});14
14
1
this.$http.post(this.GLOBAL.urlHead+'manager/login',{managerUserName:this.ruleForm.username,managerPass:this.ruleForm.password},{emulateJSON:true})2
.then((res) => {/*成功回调*/3
if (res.data.state==1) {4
alert(res.data.msg)5
localStorage.setItem('managerName',res.data.data.managerName);//ms_username6
localStorage.setItem('managerId',res.data.data.managerId);//ms_username7
this.$router.push('/index');8
}else {9
alert(res.data.msg)10
}11
}, (err) => {/*失败回调*/12
console.log(err)13
alert("登录失败!")14
});2.3.2 页面加载
/*在组建创建完之后加载:页面加载*/
created: function () {
/*ajax请求 */
this.$http.get('api/getNewsList')
//post参数:.post('api/getNewsList',{userId:123,aa:44})
.then((res) => {/*成功回调*/
this.newsList = res.data //赋值
}, (err) => {/*失败回调*/
console.log(err)
})
},11
11
1
/*在组建创建完之后加载:页面加载*/2
created: function () {3
/*ajax请求 */4
this.$http.get('api/getNewsList')5
//post参数:.post('api/getNewsList',{userId:123,aa:44})6
.then((res) => {/*成功回调*/7
this.newsList = res.data //赋值8
}, (err) => {/*失败回调*/9
console.log(err)10
})11
},2.3.3页面初次加载判断
使用一个没有定义的参数进行判断,默认为false,只需要判断完设置为true即可
if (!this.userFlag) {
errorText = ''
this.userFlag = true
}4
4
1
if (!this.userFlag) {2
errorText = ''3
this.userFlag = true4
}2.4 vue的UI组件
- GitHub地址:https://github.com/vuejs/awesome-vue
2.3.3 轮播图组件
2.3.4显示项目图片
使用js设置的图片
数据:src: require('../assets/slideShow/pic1.jpg')
3
3
1
使用js设置的图片2
数据:src: require('../assets/slideShow/pic1.jpg')3
3.vue具体组件
使用vue搭建项目的时候,一般的目结构为:
3.1 侧边栏
<template>
<div class="left-nav">
<ul>
<li>
<i class="icon iconfont icon-wodezichan"></i>
<div>收银</div>
</li>
<li>
<i class="icon iconfont icon-dianpu"></i>
<div>店铺</div>
</li>
<li>
<i class="icon iconfont icon-hanbao"></i>
<div>商品</div>
</li>
<li>
<i class="icon iconfont icon-huiyuanqia"></i>
<div>会员</div>
</li>
<li>
<i class="icon iconfont icon-shijian"></i>
<div>抢购</div>
</li>
<li>
<i class="icon iconfont icon-tongji"></i>
<div>统计</div>
</li>
·
</ul>
</div>
</template>
<script>
export default {
name: 'Main',
data () {
return {
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.left-nav{
color:#fff;
font-size:10px;
height:100%;
background-color: #1D8ce0;
float:left;
width:5%;
}
.iconfont{/*设置图标大小*/
font-size:24px;
}
.left-nav ul{
padding:0px;
margin: 0px;
}
.left-nav li{
list-style: none;
text-align: center;
border-bottom:1px solid #20a0ff;
padding:10px;
}
</style>73
73
1
<template>2
<div class="left-nav">3
<ul>4
<li>5
<i class="icon iconfont icon-wodezichan"></i>6
<div>收银</div>7
</li>8
9
<li>10
<i class="icon iconfont icon-dianpu"></i>11
<div>店铺</div>12
</li>13
14
<li>15
<i class="icon iconfont icon-hanbao"></i>16
<div>商品</div>17
</li>18
19
<li>20
<i class="icon iconfont icon-huiyuanqia"></i>21
<div>会员</div>22
</li>23
24
<li>25
<i class="icon iconfont icon-shijian"></i>26
<div>抢购</div>27
</li>28
29
<li>30
<i class="icon iconfont icon-tongji"></i>31
<div>统计</div>32
</li>33
34
·35
</ul>36
</div>37
</template>38
39
<script>40
export default {41
name: 'Main',42
data () {43
return {44
45
}46
}47
}48
</script>49
50
<!-- Add "scoped" attribute to limit CSS to this component only -->51
<style>52
.left-nav{53
color:#fff;54
font-size:10px;55
height:100%;56
background-color: #1D8ce0;57
float:left;58
width:5%;59
}60
.iconfont{/*设置图标大小*/61
font-size:24px;62
}63
.left-nav ul{64
padding:0px;65
margin: 0px;66
}67
.left-nav li{68
list-style: none;69
text-align: center;70
border-bottom:1px solid #20a0ff;71
padding:10px;72
}73
</style>- APP.vue中引用:
<leftNav></leftNav>
import leftNav from '@/components/common/leftNav'
components:{
leftNav
}
同时要调整APP的样式(比如#APP的margin-top)6
6
1
<leftNav></leftNav>2
import leftNav from '@/components/common/leftNav'3
components:{4
leftNav5
}6
同时要调整APP的样式(比如#APP的margin-top)复制,赋值不绑定

vue表单校验
vue.js校验
给定一个表单,包含三个字段,其中两个是必填项
<form
id="app"
@submit="checkForm"
action="https://vuejs.org/"
method="post"
>
解释:
id 确认vue的
submit 处理函数
action 跳转路径10
10
1
<form2
id="app"3
@submit="checkForm"4
action="https://vuejs.org/"5
method="post"6
>7
解释:8
id 确认vue的9
submit 处理函数10
action 跳转路径<form
id="app"
@submit="checkForm"
action="https://vuejs.org/"
method="post"
>
<p v-if="errors.length">
<b>Please correct the following error(s):</b>
<ul>
<li v-for="error in errors">{{ error }}</li>
</ul>
</p>
<p>
<label for="name">Name</label>
<input
id="name"
v-model="name"
type="text"
name="name"
>
</p>
<p>
<label for="age">Age</label>
<input
id="age"
v-model="age"
type="number"
name="age"
min="0">
</p>
<p>
<label for="movie">Favorite Movie</label>
<select
id="movie"
v-model="movie"
name="movie"
>
<option>Star Wars</option>
<option>Vanilla Sky</option>
<option>Atomic Blonde</option>
</select>
</p>
<p>
<input type="submit" value="Submit">
</p>
</form>52
52
1
<form2
id="app"3
@submit="checkForm"4
action="https://vuejs.org/"5
method="post"6
>7
8
<p v-if="errors.length">9
<b>Please correct the following error(s):</b>10
<ul>11
<li v-for="error in errors">{{ error }}</li>12
</ul>13
</p>14
15
<p>16
<label for="name">Name</label>17
<input18
id="name"19
v-model="name"20
type="text"21
name="name"22
>23
</p>24
25
<p>26
<label for="age">Age</label>27
<input28
id="age"29
v-model="age"30
type="number"31
name="age"32
min="0">33
</p>34
35
<p>36
<label for="movie">Favorite Movie</label>37
<select38
id="movie"39
v-model="movie"40
name="movie"41
>42
<option>Star Wars</option>43
<option>Vanilla Sky</option>44
<option>Atomic Blonde</option>45
</select>46
</p>47
48
<p>49
<input type="submit" value="Submit">50
</p>51
52
</form>const app = new Vue({
el: '#app',
data: {
errors: [],
name: null,
age: null,
movie: null
},
methods:{
checkForm: function (e) {
if (this.name && this.age) {
return true;
}
this.errors = [];
if (!this.name) {
this.errors.push('Name required.');
}
if (!this.age) {
this.errors.push('Age required.');
}
e.preventDefault();
}
}
})27
27
1
const app = new Vue({2
el: '#app',3
data: {4
errors: [],5
name: null,6
age: null,7
movie: null8
},9
methods:{10
checkForm: function (e) {11
if (this.name && this.age) {12
return true;13
}14
15
this.errors = [];16
17
if (!this.name) {18
this.errors.push('Name required.');19
}20
if (!this.age) {21
this.errors.push('Age required.');22
}23
24
e.preventDefault();25
}26
}27
})

vue.js自定义校验
<form
id="app"
@submit="checkForm"
action="https://vuejs.org/"
method="post"
novalidate="true"
>
<p>
<label for="email">Email</label>
<input
id="email"
v-model="email"
type="email"
name="email"
>
</p>
19
19
1
<form2
id="app"3
@submit="checkForm"4
action="https://vuejs.org/"5
method="post"6
novalidate="true"7
>8
9
<p>10
<label for="email">Email</label>11
<input12
id="email"13
v-model="email"14
type="email"15
name="email"16
>17
</p> 18
19
注意顶端的 novalidate="true"
浏览器会尝试在 type="email" 的字端校验邮件地址
const app = new Vue({
el: '#app',
data: {
errors: [],
name: null,
email: null,
movie: null
},
methods: {
checkForm: function (e) {
this.errors = [];
if (!this.name) {
this.errors.push("Name required.");
}
if (!this.email) {
this.errors.push('Email required.');
} else if (!this.validEmail(this.email)) {
this.errors.push('Valid email required.');
}
if (!this.errors.length) {
return true;
}
e.preventDefault();
},
validEmail: function (email) {//自定义校验规则
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
}
})x
33
1
const app = new Vue({2
el: '#app',3
data: {4
errors: [],5
name: null,6
email: null,7
movie: null8
},9
methods: {10
checkForm: function (e) {11
this.errors = [];12
13
if (!this.name) {14
this.errors.push("Name required.");15
}16
if (!this.email) {17
this.errors.push('Email required.');18
} else if (!this.validEmail(this.email)) {19
this.errors.push('Valid email required.');20
}21
22
if (!this.errors.length) {23
return true;24
}25
26
e.preventDefault();27
},28
validEmail: function (email) {//自定义校验规则29
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;30
return re.test(email);31
}32
}33
})























动画会在左右动作,没有定义的top不会有影响


浙公网安备 33010602011771号