Vue-Cli3 脚手架
Vue-Cli3 官网
https://cli.vuejs.org/zh/
vue-cli3 开发单文件组件
# js Vue.component({ }) new Vue({ })
### 缺点
- 全局定义组件的名字时 不能重复
- 字符串模板: es6提供模板字符串
- 不支持 CSS
- 没有构建步骤 Pug 、 Babel .vue
在Vue 中把 .vue 的文件成为,单文件组件,webpack等构建工具
单文件组件,可以获得:
- 完整语法高亮
- common JS模块
- 组件作用域的CSS
Vue CLI3 脚手架
基本配置
- 安装Nodejs
- https://nodejs.org/en/download
- 保证Node.js8.9 或者更高版本
- 终端中输入 `node -v ` , 保证已安装成功
安装淘宝镜像
https://npm.taobao.org/ npm install -g cnpm --registry=https://registry.npm.taobao.org // 以后的npm 可以用cnpm代替
安装Vue Cli3 脚手架
cnpm install -g @vue/cli
检查其他版本是否正确
vue --version
快速原型开发
使用 ` vue server ` 和 `vue build` 命令对单个 ` *.vue` 文件进行快速原型开发
不过这需要先额外安装一个全局的扩展:
cnpm install -g @vue/cli-service-global // -g 全局
vue serve // 的缺点就是它需要安装全局依赖
这使得它在不同机器上的一致性不能得到保证
因此这只适合于快速原型开发
需要的仅仅是一个 ` App.vue` 文件:
### vue ###
<template> <h3>{{msg}}</h3> </template> <script> export default { data(){ return{ msg:"我是你爸爸" }; }, } </script> <style scoped> h3{ color: red; } </style>
# scoped 表示注入的意思, 只对当前的h3 标签起作用
简单3步启动并访问
- npm init
- vue serve
- 访问 http://localhost:8080/
vue-cli3生成项目
vue-cli3官网 : https://cli.vuejs.org/zh/
在控制台创建 vue-cli3 项目
vue create <projectname> 1. vue create <projectname> 2. cd <projectname> 3. npm run serve
目录介绍
- node_modules : 包存储路径
- dependencies : 项目依赖
- devDependencies : 开发依赖
- public : 静态加载文件目录
- src : 一般开发目录
- assets : 当前项目的依赖
- components : 注入组件们
- main.js : 入口文件
- App.vue : app组件
购物车项目搭建
App.vue
<template>
<div id="app">
<h1>{{alltitle}}</h1>
<ul>
<li v-for="itme in cartList" :key="itme.id">
<h2>{{itme.title}}</h2>
<p>¥ {{itme.price}}</p>
</li>
</ul>
<mycart :cart="cartList" :alltitle="alltitle"></mycart>
</div>
</template>
<script>
import mycart from './components/Cart'
export default {
name: 'app',
data(){
return{
cartList:[
{id:1, title:'秘籍1', price: 999, action:true, count:1},
{id:2, title:'秘籍2', price: 1999, action:true, count:2},
{id:3, title:'秘籍3', price: 2999, action:true, count:3},
],
alltitle: "购物车",
}
},
components: {
mycart
}
}
</script>
./components/cart.vue
<template>
<div>
<h2>{{alltitle}}</h2>
<table border="1">
<tr>
<th>#</th>
<th>课程</th>
<th>单价</th>
<th>数量</th>
<th>总价</th>
</tr>
<tr v-for="c in cart" :key="c.id" >
<td><input type="checkbox" v-model="c.action"></td>
<td>{{c.title}}</td>
<td>¥{{c.price}}</td>
<td>
<button> - </button>
{{c.count}}
<button> + </button>
</td>
<td>¥{{c.price * c.count}}</td>
</tr>
</table>
</div>
</template>
<script>
export default {
name:'cart',
props:['alltitle','cart']
}
</script>
购物车项目操作
app.vue
<template>
<div id="app">
<h1>{{alltitle}}</h1>
<ul>
<li v-for="itme in cartList" :key="itme.id">
<h2>{{itme.title}}</h2>
<p>¥ {{itme.price}}</p>
</li>
</ul>
<mycart :cart="cartList" :alltitle="alltitle"></mycart>
</div>
</template>
<script>
// 导入文件
import mycart from './components/Cart'
export default {
name: 'app',
data(){
return{
cartList:[
{id:1, title:'秘籍1', price: 999, active:true, count:1},
{id:2, title:'秘籍2', price: 1999, active:true, count:2},
{id:3, title:'秘籍3', price: 2999, active:true, count:3},
],
alltitle: "购物车",
}
},
components: {
mycart
}
}
</script>
cart.vue
<template>
<div>
<h2>{{alltitle}}</h2>
<table border="1">
<tr>
<th>#</th>
<th>课程</th>
<th>单价</th>
<th>数量</th>
<th>总价</th>
</tr>
<tr v-for="(c, index) in cart" :key="c.id" >
<td><input type="checkbox" v-model="c.active"></td>
<td>{{c.title}}</td>
<td>¥{{c.price}}</td>
<td>
<button @click="sub(index)"> - </button>
{{c.count}}
<button @click="add(index)"> + </button>
</td>
<td>¥{{c.price * c.count}}</td>
</tr>
<tr>
<td></td>
<!-- colspan 合并 -->
<td colspan="2">{{activeCount}} / {{count}}</td>
<td colspan="2">¥ {{total}}</td>
</tr>
</table>
</div>
</template>
<script>
export default {
name:'cart',
props:['alltitle','cart'],
methods:{
remove(i){
if (window.confirm('是否确定删除')){
// 这个数组中 删除 那个索引的 1条数据
this.cart.splice(i,1);
}
},
sub(i){
// 取到当前的数量
let count = this.cart[i].count;
// 如果大于1 ,'?' 相当于then,则 则 -1, ':' = 否则 删除那一条数据
count > 1 ? this.cart[i].count -=1 : this.remove(i);
},
add(i){
// 取到当前的一条数据 +1
this.cart[i].count ++
},
},
computed:{
count(){
// cart的总数
return this.cart.length
},
activeCount(){
// 过滤参数 把active 是false 过滤掉
// 返回 v.active 为 true的对象
return this.cart.filter(v=>v.active).length
},
total(){
// let num = 0;
// this.cart.forEach(c=>{
// if(c.active){
// num += c.price * c.count;
// }
// });
// return num
// reduce 回调函数, 第一个参数是起始参数就是后面定义的0,第二个参数是数组遍历的对象
return this.cart.reduce((num,c)=>{
if (c.active){
num += c.price * c.count;
}
return num
},0)
}
},
}
</script>
Mock模拟数据
发起请求
安装
cnpm i axios -S # -S 保存
去入口文件 导入 axios对象 ,然后挂载到Vue 的原型上
import axios from 'axios' Vue.prototype.$http = axios;
可以在每个实例里 this.$http 拿到axios 对象
created(){ this.$http.get('/api/cartList') }
做数据持久化
入口文件 main.js
// 使用中央数据总线 创建一个bus,传递数据使用 Vue.prototype.$bus = new Vue;
App.vue
<template>
<div id="app">
<h1>{{alltitle}}</h1>
<ul>
<li v-for="(itme, index) in cartList" :key="itme.id">
<h2>{{itme.title}}</h2>
<p>¥ {{itme.price}}</p>
<button @click="addCart(index)">添加商品</button>
</li>
</ul>
<mycart :cart="cartList" :alltitle="alltitle"></mycart>
</div>
</template>
<script>
import mycart from './components/Cart'
export default {
name: 'app',
data(){
return{
cartList:[],
// cartList:[
// {id:1, title:'秘籍1', price: 999, active:true, count:1},
// {id:2, title:'秘籍2', price: 1999, active:true, count:2},
// {id:3, title:'秘籍3', price: 2999, active:true, count:3},
// ],
alltitle: "购物车",
}
},
methods:{
addCart(i){
const good = this.cartList[i];
// 使用中央数据总线 传递数据到 cart
this.$bus.$emit('addCart',good)
}
},
// created(){
// this.$http.get('/api/cartList')
// .then(res=>{
// this.cartList = res.data.result;
// }).catch(err=>{
// console.log(err);
// })
// },
async created(){
try{
const res = await this.$http.get('/api/cartList')
this.cartList = res.data.result
} catch (err) {
console.log(err)
}
},
components: {
mycart
},
}
</script>
cart.vue
<template>
<div>
<h2>{{alltitle}}</h2>
<table border="1">
<tr>
<th>#</th>
<th>课程</th>
<th>单价</th>
<th>数量</th>
<th>总价</th>
</tr>
<tr v-for="(c, index) in cart" :key="c.id" >
<td><input type="checkbox" v-model="c.active"></td>
<td>{{c.title}}</td>
<td>¥{{c.price}}</td>
<td>
<button @click="sub(index)"> - </button>
{{c.count}}
<button @click="add(index)"> + </button>
</td>
<td>¥{{c.price * c.count}}</td>
</tr>
<tr>
<td></td>
<!-- colspan 合并 -->
<td colspan="2">{{activeCount}} / {{count}}</td>
<td colspan="2">¥ {{total}}</td>
</tr>
</table>
</div>
</template>
<script>
export default {
name:'cart',
props:['alltitle',],
data(){
return{
// 初始一个空数组,存放添加或者删除的数据
// 刷新网页时 获取里面的数据,如果没有数据就是一个空数组
cart:JSON.parse(localStorage.getItem('cart')) || [],
}
},
watch:{
// 深度监听deep:true cart 数据
cart:{
handler(n){
this.setLocalData(n);
},
deep:true
}
},
created() {
// 从中央数据总线里把数据取出来,
this.$bus.$on('addCart',good=>{
// find查找那个 商品对应的ID
const ret = this.cart.find(v=>v.id===good.id);
// 如果购物车 没有数据 商品那一条数据, 则会添加进 那个列表里
if (!ret){
this.cart.push(good);
}else{
// 如果有 则会自加1
ret.count ++
}
})
},
methods:{
setLocalData(n){
// 可以计算总数量
localStorage.setItem('cart',JSON.stringify(n));
},
remove(i){
if (window.confirm('是否确定删除')){
// 这个数组中 删除 那个索引的 1条数据
this.cart.splice(i,1);
}
},
sub(i){
// 取到当前的数量
let count = this.cart[i].count;
// 如果大于1 ,'?' 相当于then,则 则 -1, ':' = 否则 删除那一条数据
count > 1 ? this.cart[i].count -=1 : this.remove(i);
},
add(i){
// 取到当前的一条数据 +1
this.cart[i].count ++
},
},
computed:{
count(){
// cart的总数
return this.cart.length
},
activeCount(){
// 过滤参数 把active 是false 过滤掉
// 返回 v.active 为 true的对象
return this.cart.filter(v=>v.active).length
},
total(){
// let num = 0;
// this.cart.forEach(c=>{
// if(c.active){
// num += c.price * c.count;
// }
// });
// return num
// reduce 回调函数, 第一个参数是起始参数就是后面定义的0,第二个参数是数组遍历的对象
return this.cart.reduce((num,c)=>{
if (c.active){
num += c.price * c.count;
}
return num
},0)
}
},
}
</script>
第三方组件(element-ui)
1. 通用组件
- 基础组件,大部分UI都是这种组件,比如表单,布局,弹窗等
2. 业务组件
- 与需求挂钩,会被复用,比如抽奖,摇一摇等
3. 页面组件
- 每个页面都是一个组件,不会复用
使用组件
安装 element-ui 插件库
npm install element-ui -S # -S 保存
修改main.js
import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css' import App from './App.vue'; Vue.use(ElementUI); new Vue({ el: '#app', render: h => h(App) });
按需引入
借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。
首先,安装 babel-plugin-component:
npm install babel-plugin-component -D
然后,将 .babelrc 修改为:
{ "presets": [["es2015", { "modules": false }]], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ] }
vue-cli 中可以使用 vue add element 安装
vue add element
选择按需导入
import on demand
安装之前注意提前提交当前工作内容, 脚手架会覆盖若干文件
发现项目发生了变化,打开App.vue , ctrl+z 撤回
饿了么UI 官网
https://element.eleme.cn/#/zh-CN/component/quickstart
main.js
import Vue from 'vue' import App from './App.vue' import axios from 'axios' // 加入UI import './plugins/element.js' // 提示警告信息 Vue.config.productionTip = false Vue.prototype.$http = axios; // 使用中央数据总线 创建一个bus,传递数据使用 Vue.prototype.$bus = new Vue; new Vue({ render: h => h(App), }).$mount('#app')
element.js
import Vue from 'vue' import { Button, Table ,TableColumn,InputNumber } from 'element-ui' Vue.use(Button) Vue.use(Table) Vue.use(TableColumn) Vue.use(InputNumber)
cart.vue
<template>
<div>
<h2>{{alltitle}}</h2>
<template>
<el-table
ref="multipleTable"
:data="cart"
border
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="title" label="课程" width="120"></el-table-column>
<el-table-column prop="price" label="单价" width="120"></el-table-column>
<el-table-column label="数量" width="200">
<template slot-scope="scope">
<el-input-number v-model="scope.row.count" :min="0" :max="100" ></el-input-number>
</template>
</el-table-column>
<el-table-column label="总价" width="120">
<template slot-scope="scope">
¥ {{scope.row.price * scope.row.count}}
</template>
</el-table-column>
</el-table>
<div style="margin-top: 20px">
<el-button @click="toggleSelection()">取消选择</el-button>
</div>
</template>
<table border="1">
<tr>
<th>#</th>
<th>课程</th>
<th>单价</th>
<th>数量</th>
<th>总价</th>
</tr>
<tr v-for="(c, index) in cart" :key="c.id" >
<td><input type="checkbox" v-model="c.active"></td>
<td>{{c.title}}</td>
<td>¥{{c.price}}</td>
<td>
<button @click="sub(index)"> - </button>
{{c.count}}
<button @click="add(index)"> + </button>
</td>
<td>¥{{c.price * c.count}}</td>
</tr>
<tr>
<td></td>
<!-- colspan 合并 -->
<td colspan="2">{{activeCount}} / {{count}}</td>
<td colspan="2">¥ {{total}}</td>
</tr>
</table>
</div>
</template>
<script>
export default {
name:'cart',
props:['alltitle',],
data(){
return{
// 初始一个空数组,存放添加或者删除的数据
// 刷新网页时 获取里面的数据,如果没有数据就是一个空数组
cart:JSON.parse(localStorage.getItem('cart')) || [],
multipleSelection: []
}
},
watch:{
// 深度监听deep:true cart 数据
cart:{
handler(n){
this.setLocalData(n);
},
deep:true
}
},
created() {
// 从中央数据总线里把数据取出来,
this.$bus.$on('addCart',good=>{
// find查找那个 商品对应的ID
const ret = this.cart.find(v=>v.id===good.id);
// 如果购物车 没有数据 商品那一条数据, 则会添加进 那个列表里
if (!ret){
this.cart.push(good);
}else{
// 如果有 则会自加1
ret.count ++
}
})
},
methods:{
// element UI
toggleSelection(rows) {
if (rows) {
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(row);
});
} else {
this.$refs.multipleTable.clearSelection();
}
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
setLocalData(n){
// 可以计算总数量
localStorage.setItem('cart',JSON.stringify(n));
},
remove(i){
if (window.confirm('是否确定删除')){
// 这个数组中 删除 那个索引的 1条数据
this.cart.splice(i,1);
}
},
sub(i){
// 取到当前的数量
let count = this.cart[i].count;
// 如果大于1 ,'?' 相当于then,则 则 -1, ':' = 否则 删除那一条数据
count > 1 ? this.cart[i].count -=1 : this.remove(i);
},
add(i){
// 取到当前的一条数据 +1
this.cart[i].count ++
},
},
computed:{
count(){
// cart的总数
return this.cart.length
},
activeCount(){
// 过滤参数 把active 是false 过滤掉
// 返回 v.active 为 true的对象
return this.multipleSelection.length;
// return this.multipleSelection.filter( v => v.active ).length;
},
total(){
// let num = 0;
// this.cart.forEach(c=>{
// if(c.active){
// num += c.price * c.count;
// }
// });
// return num
// reduce 回调函数, 第一个参数是起始参数就是后面定义的0,第二个参数是数组遍历的对象
return this.cart.reduce((num,c)=>{
if (c.active){
num += c.price * c.count;
}
return num
},0)
}
},
}
</script>
Element的表单组件分析
自定义校验 callback 必须被调用。 更多高级用法可参考 async-validator。
element.js import Vue from 'vue' import { Button, Table ,TableColumn,InputNumber,Form,FormItem,Input } from 'element-ui' Vue.use(Button) Vue.use(Table) Vue.use(TableColumn) Vue.use(InputNumber) Vue.use(Form) Vue.use(FormItem) Vue.use(Input)
App.vue
<template>
<div id="app">
<FormItem></FormItem>
</div>
</template>
<script>
// @ 相当于src 目录下
import FormItem from '@/components/FormItem.vue';
components: {
FormItem
},
}
</script>
FormItem.vue
<template>
<div>
<h3>element 表单</h3>
<el-form
:model="ruleForm"
status-icon
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm">
<el-form-item label="用户名" prop="name">
<el-input type="text" v-model="ruleForm.name" ></el-input>
</el-form-item>
<el-form-item label="密码" prop="pwd">
<el-input type="password" v-model="ruleForm.pwd" ></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
// 自定义校验 callback 必须被调用。 更多高级用法可参考 async-validator
// Form 定义数据 负责定义校验规则
// FormItem 负责显示错误信息
// Input 负责双向数据绑定
// provide inject 内部共享数据
export default {
data() {
return {
ruleForm: {
name: 'huige',
pwd: '123',
},
rules: {
name: [
{ required: true, message: '请输入名字' },
{ mix:6,max:10, message: '请输入6~10位用户名' },
],
pwd: [
{ required: true, message: '请输入密码' }
]
}
};
},
methods: {
//自定义校验 callback 必须被调用。 更多高级用法可参考 async-validator。
submitForm(name) {
this.$refs[name].validate((valid) => {
if (valid) {
alert('验证成功,可以提交!');
} else {
console.log('验证失败,不能提交!!');
return false;
}
});
},
resetForm(name) {
this.$refs[name].resetFields();
}
}
}
</script>
表单组件设计-Input实现双向数据绑定
Input.vue
<template>
<div>
<!-- 实现 v-model 是 v-bind:value 绑定值 ,v-on:input 绑定事件 -->
<input :type="type" :value="inputVal" @input="handleInput" >
</div>
</template>
<script>
export default {
props:{
type:{
type: String,
default: 'text',
},
value:{
type:String,
default:"",
}
},
data(){
return {
inputVal: this.value
}
},
methods:{
handleInput(e){
// 赋值, 实现双向数据绑定
this.inputVal = e.target.value;
this.$emit('input',this.inputVal)
// 通知父组件值的更新
}
}
}
</script>
FormElemtent.vue
<template>
<div>
{{ruleForm}}
<m-input v-model="ruleForm.name" ></m-input>
<m-input type='password' v-model="ruleForm.pwd" ></m-input>
</div>
</template>
<script>
import MInput from './Input'
export default {
components : {
MInput
},
}
</script>
表单组件-设计FormItem组件
0. label 和 prop 实行
1. 获取当前输入框的规则
2. 如果输入框和rule不匹配 ,显示错误信息
3. Input 组件中涌入输入内容时,通知FormItem做校验(校验方法)
4. 使用async-validator 做校验
Form.vue
<template>
<div>
<slot></slot>
</div>
</template>
<script>
// 1. 申明 props 获取数据模型(model) 和校验规则对象
export default {
// provide: {}
provide(){
return{
form: this
}
},
props:{
// 对象数据
model:{
type:Object,
required:true,
},
rules:{
type: Object
}
},
methods:{
validate(callback){
// 获取所有的验证结果 统一处理,只要有一个失败就失败
// tasks保存着验证之后的多个promise对象
const tasks = this.fileds.map(item=>item.validate())
let ret = true;
Promise.all(tasks).then(results=>{
results.forEach(valid=>{
if(!valid){
ret = false
}
})
})
callback(ret)
}
},
created() {
// 缓存需要校验的表单项
this.fileds = [];
this.$on('formItemAdd', item=>{
this.fileds.push(item);
})
},
}
</script>
FormItem.vue
<template>
<div>
<label v-if="label">{{label}} </label>
<!-- 槽作用 -->
<slot> </slot>
<!-- 显示错误信息 -->
<p v-if='validateState==="error"' class="error" >{{errorMessage}}</p>
</div>
</template>
<script>
import schema from 'async-validator'
export default {
// 0. label 和 prop 实行
// 1. 获取当前输入框的规则
// 2. 如果输入框和rule不匹配 ,显示错误信息
// 3. Input 组件中涌入输入内容时,通知FormItem做校验(校验方法)
// 4. 使用async-validator 做校验
// 需要安装 npm i async-validator -S
data(){
return{
validateState:'', // 显示校验值
errorMessage:'', // 显示错误信息
}
},
// 通过provide可以获取到全局的组件对象
inject:['form'], // 这个form 就是 Form.vue 里的 this
mounted() {
if (this.prop){
// 必须判断,form组件的子组件可能不是formitem
this.$parent.$emit('formItemAdd',this)
}
},
methods:{
validate(value){
return new Promise(resolve => {
// console.log(value); // 输入框的值
// 这个key 在es6里面 可以是一个动态的数组
const descriptor = {[this.prop] : this.form.rules[this.prop]}; //此对象要存储校验规则
// 获取检验对象 -> Form组件对象 -> rules[this.prop]
// console.log(this.form.rules[this.prop])
const validate = new schema(descriptor);
// 这个key 在es6里面 可以是一个动态的数组
validate.validate({[this.prop]: value},errors=>{
if (errors){
// 显示错误
this.validateState= "error";
this.errorMessage = errors[0].message;
resolve(false)
}else {
// 错误置空
this.validateState= "";
this.errorMessage ="";
resolve(true)
}
})
})
}
},
created(){
// 创建一个监听事件,监听 validate 函数
this.$on('validate',this.validate);
},
props:{
label: {
type:String,
default: "",
},
prop:{
// name 或者 pwd的规则
type: String,
default: "",
}
}
}
</script>
<style scoped>
.error{
color: red;
}
</style>
FormElement.vue
<template>
<div>
<h3>element 表单</h3>
{{ruleForm}}
<m-form :model="ruleForm" :rules="rules">
<m-form-item label="用户名" prop="name">
<m-input v-model="ruleForm.name" ></m-input>
</m-form-item>
<m-form-item label="密码" prop="pwd">
<m-input type='password' v-model="ruleForm.pwd" ></m-input>
</m-form-item>
<m-form-item>
<el-button type="primary" @click="submitForm2('ruleForm')">提交</el-button>
</m-form-item>
</m-form>
<el-form
:model="ruleForm"
status-icon
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm">
<el-form-item label="用户名" prop="name">
<el-input type="text" v-model="ruleForm.name" ></el-input>
</el-form-item>
<el-form-item label="密码" prop="pwd">
<el-input type="password" v-model="ruleForm.pwd" ></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
// 自定义校验 callback 必须被调用。 更多高级用法可参考 async-validator
// Form 定义数据 负责定义校验规则
// FormItem 负责显示错误信息
// Input 负责双向数据绑定
// provide inject 内部共享数据
import MInput from './Input'
import MFormItem from './FormItem'
import MForm from './Form'
export default {
components : {
MInput,
MFormItem,
MForm
},
data() {
return {
ruleForm: {
name: 'huige',
pwd: '123',
},
rules: {
name: [
{ required: true, message: '请输入名字' },
{ min:6,max:10, message: '请输入6~10位用户名' },
],
pwd: [
{ required: true, message: '请输入密码' }
]
}
};
},
methods: {
//自定义校验 callback 必须被调用。 更多高级用法可参考 async-validator。
submitForm(name) {
this.$refs[name].validate((valid) => {
if (valid) {
alert('验证成功,可以提交!');
} else {
alert('验证失败,不能提交!!');
return false;
}
});
},
// 自己写的校验事件
submitForm2(name) {
this.$refs[name].validate((valid) => {
if (valid) {
alert('验证成功,可以提交!');
} else {
alert('验证失败,不能提交!!');
return false;
}
});
},
resetForm(name) {
this.$refs[name].resetFields();
}
}
}
</script>

浙公网安备 33010602011771号