一、图片懒加载
https://www.npmjs.com/package/vue-lazyload
1、安装
cnpm i vue-lazyload
2、在main.js 中使用插件
//引入插件
import VueLazyload from 'vue-lazyload'
//引入未加载时,显示的图片
import lazy from '@/assets/images/lazyload.gif'
//注册插件
Vue.use(VueLazyload, {
//图片没加载出来前默认的图片
loading: lazy,
})
3、在要应用到懒加载的地方这样做
<!-- 不使用图片懒加载: <img :src="good.defaultImg" /> -->
<!-- 使用懒加载 --> <img v-lazy="good.defaultImg" />
二、表单验证 —— vee-validate(vue2.x只能安装2~3版本)
https://www.npmjs.com/package/vee-validate
1、安装
cnpm i vee-validate
2、为了不让 main.js 太杂乱,把表单验证的工作放在 src/plugins/validate.js中
//vee-validate插件:表单验证
import Vue from "vue";
import VeeValidate from "vee-validate";
//引入中文提示信息
import zh_CN from 'vee-validate/dist/locale/zh_CN';
Vue.use(VeeValidate);
//表单验证
VeeValidate.Validator.localize('zh_CN', {
messages: {
...zh_CN.messages,
is: (field) => `${field}必须与密码相同` //修改内置规则的 message,让确认密码和密码相同
},
attributes: {
//给校验的 field 属性名映射中文名称,需要验证的字段
phone: '手机号',
code: '验证码',
password: '密码',
password1: '确认密码',
agree: '协议'
}
})
//自定义校验规则
VeeValidate.Validator.extend('agree', {
validate: value => {
return value
},
getMessage: feild => field + '必须同意'
})
3、基本使用:注册.vue
<!-- 注册内容 -->
<div class="register">
......
<!-- 手机号验证 -->
<div class="content">
<label>手机号:</label>
<input
type="text"
placeholder="请输入你的手机号"
v-model="phone"
name="phone"
v-validate="{ required: true, regex: /^1\d{10}$/ }"
:class="{ invalid: errors.has('phone') }"
/>
<span class="error-msg">{{ errors.first("phone") }}</span>
</div>
<!-- 验证码验证 -->
<div class="content">
<label>验证码:</label>
<input
type="text"
placeholder="请输入验证码"
v-model="code"
name="code"
v-validate="{ required: true, regex: /^\d{6}$/ }"
:class="{ invalid: errors.has('code') }"
/>
<span class="error-msg">{{ errors.first("code") }}</span>
</div>
<!-- 密码验证 -->
<div class="content">
<label>登录密码:</label>
<input
type="password"
placeholder="请输入你的登录密码"
v-model="password"
name="password"
v-validate="{ required: true, regex: /^[0-9A-Za-z]{8,20}$/ }"
:class="{ invalid: errors.has('password') }"
/>
<span class="error-msg">{{ errors.first("password") }}</span>
</div>
<!-- 确认密码验证 -->
<div class="content">
<label>确认密码:</label>
<input
type="password"
placeholder="请输入确认密码"
v-model="password1"
name="password1"
v-validate="{ required: true, is: password }"
:class="{ invalid: errors.has('password1') }"
/>
<span class="error-msg">{{ errors.first("password1") }}</span>
</div>
<!-- 协议验证 -->
<div class="controls">
<input
type="checkbox"
:checked="agree"
name="agree"
v-validate="{ required: true, agree: true }"
:class="{ invalid: errors.has('agree') }"
/>
<span>同意协议并注册《尚品汇用户协议》</span>
<span class="error-msg">{{ errors.first("agree") }}</span>
</div>
<div class="btn">
<button @click="userRegister">完成注册</button>
</div>
</div>
......
</div>
<script>
......
//用户注册回调函数
async userRegister() {
//判断验证是否全部通过
const success = await this.$validator.validateAll();
const { phone, code, password, password1 } = this;
//全部表单验证成功才能向服务器发请求
if (success) {
try {
//发请求注册
await this.$store.dispatch("userRegister", { phone, code, password, });
//如果成功,路由跳转
this.$router.push("/login");
} catch (error) {
alert(error.message);
}
}
},
......
</script>
三、路由懒加载
//路由配置信息
//优化: 路由懒加载:把路由变成按需引入方式。
export default [
//home
{
path: "/home",
component: ()=>import("@/pages/Home"),
meta: {
showFooter: true
}
},
//center
{
path: "/center",
component: ()=>import("@/pages/Center"),
meta: {
showFooter: true
},
//注册二级路由
children: [
{
path: "myOrder",
component: ()=>import("@/pages/Center/MyOrder"),
},
{
path: "groupOrder",
component: ()=>import("@/pages/Center/GroupOrder"),
},
{
path:'/center',
//首次访问个人中心时,重定向到/center/myOrder
redirect:'/center/myOrder'
}
]
},
//paysuccess,只有pay才能进来
{
path: "/paysuccess",
component: ()=>import("@/pages/PaySuccess"),
meta: {
showFooter: true
},
//路由独享守卫
beforeEnter:(to,from,next)=>{
if(from.path == "/pay"){
next()
}else{
//从其他路由而来,不跳转,停留在当前
next(false)
}
}
},
//pay,只有trade才能进来
{
path: "/pay",
component: ()=>import("@/pages/Pay"),
meta: {
showFooter: true
},
//路由独享守卫
beforeEnter:(to,from,next)=>{
if(from.path == "/trade"){
next()
}else{
//从其他路由而来,不跳转,停留在当前
next(false)
}
}
},
//trade,只有购物车才能进来
{
path: "/trade",
component: ()=>import("@/pages/Trade"),
meta: {
showFooter: true
},
//路由独享守卫
beforeEnter:(to,from,next)=>{
if(from.path == "/shopCart"){
next()
}else{
//从其他路由而来,不跳转,停留在当前
next(false)
}
}
},
//shopCart
{
name: "shopCart",
path: "/shopCart",
component: ()=>import("@/pages/ShopCart"),
meta: {
showFooter: true
}
},
//addCartSuccess
{
path: "/addCartSuccess",
name: "addCartSuccess",
component: ()=>import("@/pages/AddCartSuccess"),
meta: {
showFooter: true
}
},
//search
{
//parms 方式接收参数,占位符,已经 name 属性
name: "search",
// :keyword? 加问号表示 keyword 可传可不传
// :keyword 不加加问号表示 keyword 必须传,不然URL路径会出现问题
path: "/search/:keyword?",
component: ()=>import("@/pages/Search"),
meta: {
showFooter: true
},
//传递 props 数据,函数写法最常见,可以将 params参数、query参数传递给路由组件
props($route) {
return {
keyword: $route.params.keyword,
Bigkeyword: $route.query.Bigkeyword
}
}
},
//register
{
path: "/register",
component: ()=>import("@/pages/Register"),
meta: {
showFooter: false
}
},
//login
{
path: "/login",
component: ()=>import("@/pages/Login"),
meta: {
showFooter: false
}
},
//detail(带 RestFul 路径记得占位)
{
path: "/detail/:skuId",
component: ()=>import("@/pages/Detail"),
meta: { showFooter: true }
},
//重定向,在项目跑起来的时候,访问/,立马定位到首页
{
path: '*',
redirect: "/home"
}
]