项目初始化
基于 vue-cli 初始化 Vue2 模板的项目
初始化 vue-cli 的核心步骤:
- Manually select features
- (*) Choose Vue version(选择版本)
- (*) Babel(js编译器)
- ( ) TypeScript
- ( ) Progressive Web App (PWA) Support
- (*) Router(l路由)
- (*) Vuex
- (*) CSS Pre-processors(css预处理器)
- (*) Linter / Formatter(风格规范)
- ( ) Unit Testing
- ( ) E2E Testing
-
Choose a version of Vue.js that you want to start the project with (Use arrow keys)
- 2.x(vue2.0)
- 3.x
-
Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)
- n (路由不选择history模式)
-
Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
- Sass/SCSS (with dart-sass)
- Sass/SCSS (with node-sass)
- Less (css选择用less)
- Stylus
-
Pick a linter / formatter config: (Use arrow keys)
- ESLint + Airbnb config
- ESLint + Standard config (eslint标准规范)
- ESLint + Prettier
-
Pick additional lint features: (Press to select, to toggle all, to invert selection)
- (*) Lint on save (保存的时候)
- ( ) Lint and fix on commit (commit 提交的时候)
-
Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
- In dedicated config files (把东西另外放在专用的配置文件)
- In package.json ( 把东西都放package.json里)
-
Save this as a preset for future projects? (y/N)
- N (保存为未来项目的预置)
首次运行项目
目的:检查项目是否初始化成功。
- cd 项目根目录
- npm run serve
梳理项目结构
-
重置
src/router/index.js路由模块中的代码import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [] const router = new VueRouter({ routes }) export default router -
清空
src/components目录和src/views目录。 -
把资料目录下的 images 文件夹(项目中需要用到的图片)和 global.less(项目中用到的全局样式),复制粘贴到 src/assets 目录下。
配置 element-ui
目的:为了提高页面布局的开发效率,因为 element-ui 提供了很多常用的 UI 组件。
参照 element-ui 的官方文档,进行安装、配置、使用:element.eleme.io/#/zh-CN/com…
npm 安装
推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。
npm i element-ui -S
引入 Element
你可以引入整个 Element,或是根据需要仅引入部分组件。我们先介绍如何引入完整的 Element。
完整引入
在 main.js 中写入以下内容:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
配置 axios
目的:为后面请求数据做准备。
-
安装 axios
npm i axios -S -
在 main.js 中导入 axios
import axios from 'axios' -
设置 axios 的请求根路径
axios.defaults.baseURL = 'http://www.liulongbin.top:3008' -
把 axios 挂载到 Vue.prototype 上
Vue.prototype.$http = axios
把项目上传到码云仓库
目标:能够使用远程仓库管理本地项目
- 把本地项目的 master 分支进行 commit 提交
- 在码云中新建空白远程仓库
- 把本地仓库的 master 分支上传到码云仓库中
注册功能
创建登录分支并切换到登录分支上
git checkout -b reg
reg 分支的合并与提交
-
把 reg 分支进行本地的提交:
git add . git commit -m "完成了注册功能的开发" -
把本地的 reg 分支,推送到码云仓库:
git push -u origin reg -
把本地的 reg 分支,合并到本地的 master 分支:
git checkout master git merge reg -
把本地最新的 master 分支推送到码云的 master 分支:
git push -
删除本地的 reg 分支,并且新建 login 分支,准备开发登录功能:
git branch -d reg git checkout -b login
脚手架注意项
export default {
//eslint规定每个vue组件都要有name,并且要为两个单词组成
name: 'RegIndex',
data () {
return {
}
}
}
注册表单的校验
目标:在项目开发中,能够使用 Form 表单的必填项校验、正则验证和自定义校验规则。
注意:使用elementUI的表单验证必须设置以下几个属性
el-form: model rules
el-form-item: prop
el-input: v-model
-
定义用户名的校验规则:
username: [ { required: true, message: '请输入用户名', trigger: 'blur' }, { pattern: /^[a-zA-Z0-9]{1,10}$/, message: '用户名必须是1-10的字母数字', trigger: 'blur' } ], -
定义密码的校验规则:
password: [ { required: true, message: '请输入密码', trigger: 'blur' }, { pattern: /^\S{6,15}$/, message: '密码必须是6-15的非空字符', trigger: 'blur' } ], -
定义确认密码的校验规则:
repassword: [ { required: true, message: '请再次输入密码', trigger: 'blur' }, { pattern: /^\S{6,15}$/, message: '密码必须是6-15的非空字符', trigger: 'blur' }, { validator: samePwd, trigger: 'blur' } ]并在,在 data 函数中声明自定义校验规则
samePwd如下:data() { // 验证密码是否相同 const samePwd = (rule, value, callback) => { if (value !== this.regForm.password) { // 如果验证失败,则调用 回调函数时,指定一个 Error 对象。 callback(new Error('两次输入的密码不一致!')) } else { // 如果验证成功,则直接调用 callback 回调函数即可。 callback() } } return { ... } }
实现注册功能
目标:理解注册功能的实现步骤,今后在实际开发中,能够独自实现注册的功能
-
点击注册按钮时,进行表单的预验证:
<el-button type="primary" class="btn-reg" @click="regNewUser">注册</el-button>声明点击事件处理函数:
methods: { // 注册新用户 regNewUser() { // 进行表单预验证 this.$refs.form表单上自定义的值.validate(valid => { if (!valid) return console.log('ok') }) } } -
表单校验通过之后,发起注册用户的请求:
// 注册新用户 regNewUser() { // 进行表单预验证 this.$refs.regRef.validate(async valid => { if (!valid) return // 1. 发起注册请求 const { data: res } = await this.$http.post('链接', this.regForm) // 2. 注册失败,提示用户 if (res.code !== 0) return this.$message.error(res.message) // 3. 注册成功,提示用户 this.$message.success(res.message) // 4. 跳转到登录页面 this.$router.push('/login') }) }
把登录成功后的 token 记录到 vuex 中
目标:能够理解为什么要把 token 记录到 vuex 中,以及如何实现进行记录。
-
在
src/store/index.js中,定义token数据,以及更新 token 的updateTokenmutation 函数:export default new Vuex.Store({ state: { // 1. 用来存储登录成功之后,得到的 token token: '' }, mutations: { // 2. 更新 token 的 mutation 函数 updateToken(state, newToken) { state.token = newToken } } }) -
在
Login.vue组件中,也就是登录页面登录成功之后,调用 vuex 中的updateToken函数:// 把 token 记录到 vuex 中 this.$store.commit('updateToken', res.token)
持久化存储 vuex 中的数据
目标:能够理解为什么要持久化存储 vuex 中的数据,以及如何实现持久化存储。
-
运行如下的命令,安装持久化存储 vuex 中数据的第三方包:
npm install --save vuex-persistedstate@3.2.1 -
在
src/store/index.js模块中,导入并配置vuex-persistedstate包:import Vue from 'vue' import Vuex from 'vuex' // 1. 导入包 import createPersistedState from 'vuex-persistedstate' Vue.use(Vuex) export default new Vuex.Store({ // 2. 配置为 vuex 的插件 plugins: [createPersistedState()], state: { token: '' }, mutations: { updateToken(state, newToken) { state.token = newToken } } })
登录成功后跳转到后台主页
-
在
Login.vue组件中,登录成功时,通过编程式导航 API,跳转到后台主页:// 实现登录功能 login() { this.$refs.loginRef.validate(async valid => { if (!valid) return // 1. 发起登录的请求 const { data: res } = await this.$http.post('接口', this.loginForm) // 2. 登录失败 if (res.code !== 0) return this.$message.error(res.message) // 3. 登录成功 this.$message.success(res.message) // 4. 把 token 记录到 vuex 中 this.$store.commit('updateToken', res.token) // 5. 登录成功之后,跳转到后台主页 this.$router.push('/') })
退出登录
目标:在实际开发中,能够根据思路实现退出登录的功能
点击退出按钮时,提示用户是否退出登录:
<el-menu-item index="2" @click="logout"><i class="el-icon-switch-button"></i>退出</el-menu-item>
在 methods 中定义 logout 函数如下:
// 退出登录
logout() {
// 询问用户是否退出登录
async clickLogout () {
const res = await this.$confirm('您确认退出吗, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).catch(err => err)
if (res !== 'confirm') return false
//清空vuex里保存的token
this.$store.commit('updataToken', '')
//跳转到登录页
this.$router.push('/login')
},
}
渲染富文本编辑器
基于 vue-quill-editor 实现富文本编辑器:www.npmjs.com/package/vue…
-
运行如下的命令,在项目中安装富文本编辑器:
npm i vue-quill-editor@3.0.6 -S -
在项目入口文件
main.js中导入并全局注册富文本编辑器:// 导入富文本编辑器 import VueQuillEditor from 'vue-quill-editor' // 导入富文本编辑器的样式 import 'quill/dist/quill.core.css' import 'quill/dist/quill.snow.css' import 'quill/dist/quill.bubble.css' // 全局注册富文本编辑器 Vue.use(VueQuillEditor) -
在
ArtList.vue组件的 data 中,定义富文本编辑器对应的数据项:data() { return { // 表单的数据对象 pubForm: { title: '', cate_id: '', // 文章的内容 + content: '' }, } } -
在
ArtList.vue组件的模板结构中,添加富文本编辑器的 DOM 结构:<el-form-item label="文章内容"> <!-- 使用 v-model 进行双向的数据绑定 --> <quill-editor v-model="pubForm.content"></quill-editor> </el-form-item> -
美化富文本编辑器的样式:
// 设置富文本编辑器的默认最小高度 /deep/ .ql-editor { min-height: 300px; }
渲染用户选择的头像
目标:掌握如何使用 FileReader 把图片读取为 base64 格式的字符串。
-
基于 FileReader 把文件读取为 base64 的字符串:
onFileChange(e) { const files = e.target.files if (files.length === 0) { this.avatar = '' } else { // 1. 创建 FileReader 对象 const fr = new FileReader() // 2. 调用 readAsDataURL 函数,读取文件内容 fr.readAsDataURL(files[0]) // 3. 监听 fr 的 onload 事件 fr.onload = e => { // 4. 通过 e.target.result 获取到读取的结果,值是字符串(base64 格式的字符串) this.avatar = e.target.result } } }