Thank you for correcting me. I didn’t know whether VUe3 meant vue3 or VUE-CLI3. I did say vuE-cli3 here, let me correct it here. The previous router code is posted wrong, thank you for your correction, it has been revised.
As for the comments I spray, I declare, this article is only suitable for sincere study of communication to watch, silly force please skip.
—- split line —-
Here is the text
It is a shame to say that I have been using VUE for a long time, but how to configure a VUE project from 0, still need Baidu every time. This time, I decided to write a blog to strengthen my memory. If I can’t remember it again, I will broadcast my girlfriend taking a shower.
The following is an example of creating a library management project. I use VUe3 to create new projects, and vue3 is really much easier to create a project than VUe2.
1. Initialize the project
1.1 Global Installation using the CLI
To create a VUE project, first ensure that the VUE command-line tools are installed globally.
I use YARN instead of NPM because IT is much easier to use than NPM. Yarn is highly recommended. If you are not familiar with YARN, I will give you my yarn tutorial for free. Click to check it out.
yarn add global @vue/cli
Copy the code
1.2 New Project
Vue-cli3 projects can be developed using graphical interfaces, command lines, or based on prototypes. I’ll use common command-line development as an example.
I want to create a new library management project named Book under the Test folder in my D drive. Run the following command.
D:\test>vue create book
Copy the code
Here we can choose preset, the preprocessor we need to install. We can save a lot of trouble by simply choosing the first option in the figure below. But for purposes of illustration, we’ll go with the default (bable+ ESLint). We’ll talk about how to install other preset manually later. I highly recommend that you choose the first option. It can really save you a lot of trouble.
After the program is executed, the project structure is as follows:
.
|-book
|-babel.config.js
|-package.json
|-public
| |-favicon.ico
| |-index.html
|-README.md
|-src
| |-App.vue
| |-assets
| | |-logo.png
| |-components
| | |-HelloWorld.vue
| |-main.js
|-yarn.lock
Copy the code
Set the command line path to the path where the book project resides
D:\test>cd book
Copy the code
Start the project
yarn serve
Copy the code
After execution, THERE is no error on my side, indicating that there is no problem with the installation.
2. Project structure
Vue has created an initial project structure for us, but it is not complete. We need to create some new directories. The newly created directories are created in the SRC directory.
- Views users store our pages
- Store places the Vuex program
- The API places all the interface programs
- Utils placement utility functions (optional)
- Router Places routing information
- Styles Places global styles (optional)
- Components is already there to store the components in our page. We can create components directly in the Components directory, but this is not very clear, I like to create a new folder for each page in the Components directory, and put the components of each page in the corresponding file
- Assets is also available, which is used to store our resource files, videos, audio, pictures, etc.
The directory structure is as follows:
|-book
|-babel.config.js
|-package.json
|-public
| |-favicon.ico
| |-index.html
|-README.md
|-src
| |-api
| |-App.vue
| |-assets
| | |-logo.png
| |-components
| | |-HelloWorld.vue
| |-main.js
| |-router
| |-store
| | |-index.js
| |-utils
| |-views
|-yarn.lock
Copy the code
3. Project introduction
We are going to explain the use of VUE, take a project to practice. I’ll be a product manager for a virtual library management project. We have 2 pages. Respectively as follows
- Login page, user input account admin and password admin, jump to our home page
- On the front page, show some book information (I won’t show it to save trouble).
What operations will this project involve:
- Click the jump
- request
- show
So, in addition to the components that VUE provides us, we need to manually add them
- Routing component: VUe-router
- Request component: Axios Mock
- UI component: element- UI sass
- Form validation component: vee-validate
- Status: vuex Js-cookie
Now let’s develop our page step by step according to our requirements.
4. Development projects
4.1 the login page
- Create login. vue and index. vue in the views folder. The code for all three pages is pretty much the same, basic code for now, and will need to be changed later.
<template>
<! -- This is login page -->
<div>Here is the login page</div>
<! -- This is the index page -->
<div>Here is the Index page</div>
</template>
<style>
</style>
<script>
export default {
name: 'Login',
data() {
return{}}},</script>
Copy the code
- Modify the app. vue file in the SRC directory. Delete the contents of the #app file and replace it with
, where the other components are displayed. Delete the contents of script. The modified app. vue code is as follows:
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Copy the code
5.vue-router
Developing any project using VUE involves routing, so we’ll start with routing. The component to be installed is vue-Router
D:\test\book>yarn add vue-router
Copy the code
Create a new index.js file in the router folder we just created
import Vue from 'vue'
import Router from 'vue-router'
import Login from '.. /views/Login.vue'
import Index from '.. /views/Index.vue'
import Detail from '.. /views/Detail.vue'
Vue.use(Router)
const router = new Router({
routes: [{
path: '/'.redirect: '/index'
}, {
path: '/login'.name: 'Login'.component: Login
}, {
path: '/index'.name: 'Index'.component: Index
}, {
path: '/detail'.name: 'Detail'.component: Detail
}]
})
export default router
Copy the code
Modify main.js to import our route. In line 3 I import the route, and I need to add the router to the new Vue so that the route can be used properly.
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
router,
render: h= > h(App),
}).$mount('#app')
Copy the code
Now we can access our page, ignore the port number on the link, vue will automatically select a suitable port number based on the port usage of your computer, so my port number may be different from yours.
- http://localhost:8081/#/ index page, this is because I use redirect in routing
- http://localhost:8081/#/index or index page
- The http://localhost:8081/#/login login page
Ok Our route configuration is successful. I have no problem accessing the page. If you have any problem, you can find out where your mistake is.
6.element-ui
Now enter our page development mode, first we want to develop is the login page. We could use native HTML development, but it’s inefficient, so we’ll use the VUE component instead. I’ll use element-UI as an example
The installation
D:\test\book>yarn add element-ui
Copy the code
Configuration: Introduce Element in main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
/ / introduce element - the UI
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
router,
render: h= > h(App),
}).$mount('#app')
Copy the code
Modify the Login. Vue.
After modifying the code to look like this, our form is complete. Open the page. We found that we had the page functionality, but it was too ugly, the form took up the entire width of the page, so we had to change the style. We’re going to use sass here
<template>
<div class="login">
<div class="l-form">
<div class="l-tip">Library Management System</div>
<el-form ref="form" :model="form">
<el-form-item>
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="form.password" type="password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">The login</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
name: 'Login',
data() {
return {
form: {
name: ' '.password: ' '}}},methods: {
onSubmit() {
},
},
}
</script>
<style>
</style>
Copy the code
7.sass
We can use CSS directly, but I don’t recommend it because native is ugly. We’re going to use the CSS preprocessor to write CSS styles. CSS preprocessors are SASS and Less, and there are others that I haven’t used. I do not recommend using less, because it is not powerful and has no functions like custom functions. It is very awkward to write code. I recommend sass.
Install the sass
D:\test\book>yarn add node-sass sass-loader
Copy the code
Vue-cli3 is a 0 configuration for SASS. After installing the processor above, we can use Sass directly by adding lang=” SCSS “on the style tag.
Change the style in login. vue
<style lang="scss">.login { width: 100%; height: 100%; background: #000; .l-form { position: fixed; top: 50%; left: 50%; transform: translateY(-50%) translateX(-50%); width: 300px; margin: auto; border-radius: 8px; background: #fff; padding: 20px; .l-tip { text-align: center; font-size: 24px; font-weight: bold; } .el-form { width: 100%; margin: auto; margin-top: 20px; .el-form-item { button { width: 100%; } } } } }</style>
Copy the code
The style is a little different from what we want. This is due to the style problem of the parent element. Change the style in app.vue. The main thing is to set the width and height and margins for HTML, body, and #app elements.
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<style lang="scss">
html.body.#app{
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
</style>
Copy the code
Open your browser again, and look at our page, which is already pretty good. The page length goes like this.
8.normalize.css
Normalize.css can be installed with or without it, but I’m obsessive-compulsive.
The installation
yarn add normalize.css
Copy the code
Modify main.js to introduce normalize.css.
configuration
import 'normalize.css'
Copy the code
9.axios
We need to log in on the login page, which involves making an Ajax request, which we use axios
The installation
D:\test\book>yarn add axios
Copy the code
use
Create a new config.js file under the API folder to configure some common options for the request, while also further encapsulating geI and POST requests. In fact, packaging is not packaging does not matter, I personally feel that packaging will save a little trouble. The code is as follows:
import axios from "axios"
import { Message } from "element-ui"
// This baseUrl should be changed according to the actual situation
axios.defaults.baseURL = "/"
axios.defaults.headers.common["Content-Type"] =
"application/json; charset=UTF-8"
axios.defaults.headers.common["Access-Control-Allow-Origin"] = "*"
// Request interceptor to add token
axios.interceptors.request.use(
config= > {
return config
},
error => {
return Promise.reject(error)
}
)
// Response interceptor is exception handling
axios.interceptors.response.use(
response= > {
return response
},
error => {
Message({
message: error.message,
type: "error".duration: 5000,})return Promise.resolve(error)
}
)
export default {
/ / get request
get(url, param) {
return new Promise((resolve, reject) = > {
axios({
method: "get",
url,
params: param,
})
.then(res= > {
resolve(res)
})
.catch(error= > {
Message({
message: error,
type: "error".duration: 5000,
})
reject(error)
})
})
},
/ / post request
post(url, param) {
return new Promise((resolve, reject) = > {
axios({
method: "post",
url,
data: param,
})
.then(res= > {
resolve(res)
})
.catch(error= > {
Message({
message: error,
type: "error".duration: 5000,
})
reject(error)
})
})
},
// all get
allGet(fnArr) {
return axios.all(fnArr)
},
}
Copy the code
Create a login.js file in the API folder. This function requests the login interface in the background.
The code is as follows:
import service from './config'
class Login {
login(params) {
return service.post('login', params)
}
}
export default new Login()
Copy the code
Axios doesn’t have to be specially configured to work with imports. Now the problem is, we have an interface, but we don’t have a background. We can’t do the login function. But don’t worry, our front end is pretty strong right now. Without a back end, we can mock it.
10. Set eslint
Before we install the mock, we have a small problem setting rules for ESLint. The default ESLint rules are so strict that we can’t even use console.log() on the page, which makes debugging difficult. So we’re going to disable some ESLint rules.
Open package.json, locate the eslintConfig TAB, and then locate the rules under it. Set “no-console” to “off”. You can turn off esLint’s console restrictions.
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {
"no-console": "off"
},
"parserOptions": {
"parser": "babel-eslint"
}
},
Copy the code
Ok, now we can happily write Console in vue.
11. mock
What is a mock? Mock is a testing tool. Mocks intercept Ajax requests and can return data according to certain rules. We can mock back data that was previously returned to us from the background. Mock is powerful enough to simulate the add, delete, alter, and view functions on the back end. Very convenient for our front-end testing.
The installation
D:\test\book>yarn add mockjs
Copy the code
use
Create mock. Js in the parent directory of main.js. In mock.js we define the login interface we just needed. The code is as follows:
import Mock from 'mockjs'
Mock.mock('/login'.'post', (options) => {
// console.log('options:', options)
let data = JSON.parse(options.body)
let name = data.name
let password = data.password
if (name === 'admin' && password === 'admin') {
return {
status: 1.message: 'Login successful'}}else {
return {
status: 0.message: 'Wrong account or password'}}})Copy the code
If the user name and password are admin, the request is successful. If the user name and password are admin, the request is successful. If the user name and password are admin, the request is successful.
Now the question is, right? Now that we’ve written the program, how to mock it is so simple that I can’t believe it. We can just import mock.js directly into our main.js file.
configuration
Add the following code to main.js.
// introduce mock import './mock.js'Copy the code
Ok, now open our login page again. Enter your account and password. If it is not admin, an error is displayed.
If the account password is correct, the INDEX page is displayed.
Since then, the work is mostly done, and we continue to finish the project (very tired).
12.vee-validate
Another problem with our login form is how to add authentication. Forms are not validated because they are not easy to detect problems and often annoy the back end. You can also write your own validation, but the keyboard can’t handle the repetition of so much code each time. So, I’m going to use components, and I’m going to use vee-validate.
Installation:
yarn add vee-validate
Copy the code
Configuration:
Introduce vee-validate in main.js
Import VeeValidate, {Validator} from 'vee-validate' vue. use(VeeValidate, {fieldsBagName: Import zhCN from 'vee-validate/dist/locale/zh_CN' validator. localize('zh_CN', zhCN) import zhCN from 'vee-validate/dist/locale/zh_CN' validator. localize('zh_CN', zhCN)Copy the code
Modify login.vue to add form authentication. Take the user name as an example. My requirement is that the user name cannot be empty.
<el-input
v-model="form.name"
v-validate="{required:true}"
name="name"
:class="{'is-danger':errors.has('name')}"
data-vv-as="Username"
placeholder="Please enter user name"
></el-input>
Copy the code
- The VALIDATION rules are configured in v-validate
- Name is the field name, which is optional
- Is-danger is a class name that I configured for the field that reported an error. If erros.has(field name) is not empty, the authentication failed and the class is added.
The IS-Danger style is shown below, and the border of the error form is set to red to highlight the error message. The reason for the /deep/ prefix is because the el-Input component is an Element component, and the style we set in the style is local and cannot be applied to element children, so we need to add /deep/. Whether you need to add it depends on the situation.
/deep/ .is-danger input {
border-color: #ff3860;
}
Copy the code
Next, we need to consider how the error message is displayed. What I do is I just display the error message under the form, but the downside is if you have a lot of error messages, an error message in every input field, the form gets really tall.
Since each input box has to display error messages, I thought it would be better to make the function of displaying error messages into components, which can be used in general and save a lot of repetitive code.
Create the Common folder under components and the FormErrorMessage.vue component under Commen
The code is as follows:
<template>
<div class="help is-danger">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'FormErrorMessage'
}
</script>
<style scoped>
.help {
font-size: 0.75 rem;
margin-top: 0.25 rem;
line-height: 0.75 rem;
}
.help.is-danger {
color: #ff3860;
}
</style>
Copy the code
Introduced in login. vue
import FormErrorMessage from '.. /components/common/FormErrorMessage.vue'
Copy the code
Configure in Components
name: 'Login',
components: {
FormErrorMessage
},
data() {
return {
form: {
name: '',
password: ''
}
}
},
Copy the code
use
<el-form-item>
<el-input
v-model="form.name"
v-validate="{required:true}"
name="name"
:class="{'is-danger':errors.has('name')}"
data-vv-as="Username"
placeholder="Please enter user name"
></el-input>
</el-form-item>
<el-form-item>
<FormErrorMessage v-if="errors.has('name')">{{ errors.first('name') }}</FormErrorMessage>
</el-form-item>
Copy the code
Form validation has been added, error display components have been added, and now it’s just a matter of how to trigger form validation. If result is true, the form is validated. Otherwise, there is an error.
onSubmit() {
this.$validator.validate().then(result= > {
if (result) {
login.submit(this.form).then(res= > {
// console.log('res:', res);
if (res.data.status === 1) {
// If the login succeeds, the index page will be redirected
this.$router.push('/index')}else {
// Use the message component of element-UI to display a login error message
this.$message({
message: res.data.message,
type: 'error'.duration: 5000
})
}
}).catch(error= > {
this.$message({
message: error,
type: 'error'.duration: 5000})})}})},Copy the code
After the error message was added, the form style needed to be adjusted, so I left it as follows:
The complete login. vue code is as follows:
<template>
<div class="login">
<div class="l-form">
<div class="l-tip">Library Management System</div>
<el-form ref="form" :model="form">
<el-form-item>
<el-input
v-model="form.name"
v-validate="{required:true}"
name="name"
:class="{'is-danger':errors.has('name')}"
data-vv-as="Username"
placeholder="Please enter user name"
></el-input>
</el-form-item>
<el-form-item>
<FormErrorMessage v-if="errors.has('name')">{{ errors.first('name') }}</FormErrorMessage>
</el-form-item>
<el-form-item>
<el-input
v-model="form.password"
type="password"
v-validate="{required:true}"
name="password"
:class="{'is-danger':errors.has('password')}"
data-vv-as="Password"
placeholder="Please enter your password"
></el-input>
</el-form-item>
<el-form-item>
<FormErrorMessage v-if="errors.has('password')">{{ errors.first('password') }}</FormErrorMessage>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">The login</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import login from '.. /api/login.js'
import FormErrorMessage from '.. /components/common/FormErrorMessage.vue'
export default {
name: 'Login'.components: {
FormErrorMessage
},
data() {
return {
form: {
name: ' '.password: ' '}}},methods: {
onSubmit() {
this.$validator.validate().then(result= > {
if (result) {
login.submit(this.form).then(res= > {
// console.log('res:', res);
if (res.data.status === 1) {
// If the login succeeds, the index page will be redirected
this.$router.push('/index')}else {
// Use the message component of element-UI to display a login error message
this.$message({
message: res.data.message,
type: 'error'.duration: 5000
})
}
}).catch(error= > {
this.$message({
message: error,
type: 'error'.duration: 5000})})}},},}</script>
<style lang="scss" scoped>.login { width: 100%; height: 100%; background: #000; .l-form { position: fixed; top: 50%; left: 50%; transform: translateY(-50%) translateX(-50%); width: 300px; margin: auto; border-radius: 8px; background: #fff; padding: 20px; .l-tip { text-align: center; font-size: 24px; font-weight: bold; } .el-form { width: 100%; margin: auto; margin-top: 20px; .el-form-item { button { width: 100%; } } } } } .is-danger input { border-color: #ff3860; }</style>
Copy the code
13. js-cookie
It was time to talk about vuex, where a component jS-cookie was inserted
Address: js – cookies
The installation
yarn add js-cookie
Copy the code
We’ll talk about how this works later when we talk about vuex.
14.vuex
First, we finally get to the last point vuex. Why vuex? In this project, vuex was used to keep the website logged in. For example, the index page requires users to log in to access it, so vuex is used here. When vuex is instantiated, it is called store.
Address: vuex
The installation
D:\test\book>yarn add vuex
Copy the code
In the Store folder, create the index.js file
The code is as follows:
import Vue from 'vue'
import Vuex from 'vuex'
/ / introduction of js - cookies
import Cookies from 'js-cookie'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
name: ' '
},
mutations: {
loginIn(state, name) {
state.name = name
// Set the expiration time to 1 day
Cookies.set('name', name, {
expires: 1
})
},
loginOut(state) {
state.name = ' '
Cookies.remove('name')}}})export default store
Copy the code
We define a loginIn method that can store user names in a store, as well as in cookies, with a validity period of 1 day.
configuration
Modify main.js to add store to main.js and configure it in the new Vue function
import store from './store/index.js'...new Vue({
router,
store,
render: h= > h(App),
}).$mount('#app')
Copy the code
Ok, now we can use store happily.
Modify the onSubmit method of login. vue. After the user logs in successfully, the user information is saved in store.
if (res.data.status === 1) {
// Store user information in vuEX
this.$store.commit('loginIn'.this.form.name)
// If the login succeeds, the index page will be redirected
this.$router.push('/index')}else {
……
}
Copy the code
By modifying the index. vue page, we can get the username of the login user from this page.
The code for index.vue is as follows:
<template>
<div>{{userName}}</div>
</template>
<style>
</style>
<script>
export default {
name: 'Index',
data() {
return{}},computed: {
userName() {
return this.$store.state.name
}
},
}
</script>
Copy the code
At this point, a common VUE project is basically configured. Of course, different projects and different components need to be installed, and you can decide according to the situation.
Finally, there is the issue of route interception.
15. Route interception
Our project now has login functionality, but there are no restrictions on users. For example, my index.vue page requires that only logged-in users be able to access it. What should I do? This will be used to intercept the route, whenever the user is not logged in to access index.vue, uniformly redirect him to the Login page, let him Login.
Modify the main js. Add the following code:
// Set route interception
router.beforeEach((to, from, next) = > {
let name = Cookies.get('name') || store.state.name
// If the cookie is not expired or the store has a name value, access is allowed through. Otherwise, let the user log in
if (name) {
store.commit('loginIn', name)
next()
} else {
if (to.path == '/login') {
next()
} else {
next({
name: 'Login'
})
store.commit('loginOut')
}
}
})
router.afterEach((a)= > {})
Copy the code
Ok, we now require the user to be logged in when accessing the Index page.
Finally, we’re done with configuring a vue.3.0 project. Before writing this blog, I was struggling with how to say so much. Did not expect a little bit of talk, finally want to talk about all finished.
Of course, I’m talking about simple use, just getting started. If you’re actually working on a project, you also need to know a lot about each component, like Element and mock and vee-validate. Do your own research.
I uploaded the entire project to Githubl for easy viewing of the code. The github address for the entire project is: book