首页 > 技术文章 > vue3.0 创建/登录

moguzi12345 2021-04-13 17:47 原文

vue3.0,可以在ui界面自定义安装:

  新建一个空文件夹,cmd运行: vue ui,回车:

 创建项目:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-------------------------------------------   至此,带有 ts 的项目创建完成   -------------------------------------------

 


-------------------------------------------   以下是没有 ts 的项目   -------------------------------------------

 

 

1、安装element-plus:

  main.js:

//安装 element-plus
npm install element-plus --save

//引入 element-plus import ElementPlus from 'element-plus'; import 'element-plus/lib/theme-chalk/index.css';

//调用
const app = createApp(App) app.use(store) app.use(router) app.use(ElementPlus) app.mount('#app')

 

 

2、路由管理:

  router / index.js:

//引入路由:
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
//调用路由 const router = createRouter({ history: createWebHistory(process.env.BASE_URL),// History 路由 history: createWebHashHistory(), // Hash 路由 routes })

 

3、配置代理端口等( vue.config.js ),src 同级根目录下,创建 vue.config.js 文件:

const port = process.env.port || process.env.npm_config_port || 3020 // dev port
module.exports = {
    publicPath: './',
    outputDir: 'dist_vue3_3',
    assetsDir: 'static',
    lintOnSave: false,
    productionSourceMap: false,
    devServer: {
        host: '0.0.0.0',
        port: port,
        open: true,
        overlay: {
            warnings: false,
            errors: true
        },
        proxy: {
            [process.env.VUE_APP_BASE_API]: {
                target: process.env.VUE_APP_URL_API,
                changeOrigin: true,
                ws: true,
                pathRewrite: {
                    ['^' + process.env.VUE_APP_BASE_API]: ''
                }
            }
        }
    },
}

 

4、配置请求接口地址:

  根目录下,创建 .env.development 和 .env.production:

  .env.development:

ENV = 'development'

VUE_APP_BASE_API = '/api'
VUE_APP_URL_API = 'http://192.168.1.81:7001'
VUE_CLI_BABEL_TRANSPILE_MODULES = true

  .env.production:

ENV = 'production'

VUE_APP_BASE_API = '/api'
VUE_APP_URL_API = 'http://XXXXXX.com'

 

 

5、接口请求( axios ):

  src 里面,创建 utils 文件夹,新建 https.js 和 auth.js,

  https.js( 封装 axios 接口请求 ):

//安装axios
npm install axios --save

import Vue from 'vue'

//引入axios import axios from 'axios' import { ElMessage } from 'element-plus' import { getToken } from '@/utils/auth' import Cookies from 'js-cookie' import router, { resetRouter } from '@/router'
//创建新的 axios 实例 const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, withCredentials: true, // send cookies when cross-domain requests timeout: 15000 // request timeout })
//请求拦截 service.interceptors.request.use( config
=> { config.headers['X-Token'] = getToken(); //设置请求头 return config }, error => { return Promise.reject(error) } )

//响应 response 拦截器 service.interceptors.response.use(response
=> { if (response.status === 200) { const data = response.data; return data; } else if (response.code === 302) {
     //响应超时,跳转到登录页 router.replace({ path: '/login', query: {} }) ElMessage.error({ message: '请求异常!', type: 'error', duration: 5 * 1000, }); } return response; }); export default service

  auth.js:

//安装js-cookie
npm install js-cookie --save

//引入js-cookie

import Cookies from 'js-cookie' const token = 'token' export function getToken() { return Cookies.get(token) } export function setToken(tokens) { return Cookies.set(token, tokens, { expires: 3 // 设置token过期时间: 3天 }) } export function removeToken() { return Cookies.remove(token) }

  src 里面,创建 api 文件夹,新建 user.js,

import request from '@/utils/https'
// 登录
export function login(data) {
    return request({
        url: '/user/login',
        method: 'post',
        data
    })
}

6、登录:

<template>
  <div class="dashboard-container">
    <el-row :gutter="24" class="login_from">
        <el-col class="login_tit">登录</el-col>
        <el-col :span="12" :offset="6">
            <el-form label-position="right" label-width="90px" :model="formLabelAlign">
                <el-form-item label="用户名">
                    <el-input v-model="formLabelAlign.userName"></el-input>
                </el-form-item>
                <el-form-item label="密码">
                    <el-input v-model="formLabelAlign.passWord"></el-input>
                </el-form-item>
                <el-button type="primary" @click="getUserRepositories">登录</el-button>
            </el-form>
        </el-col>
    </el-row>
  </div>
</template>

<script>
import { onMounted, ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { setToken } from '@/utils/auth'
import { login } from '@/api/user' //引入接口
    export default {
        name: 'Home',
        setup() {
            const formLabelAlign = reactive({
                userName: '',
                passWord: '',
            })//定义登录的用户名和密码
            const getUserRepositories = () => {// 定义一个方法( 登录事件 )
                if(formLabelAlign.userName == null || formLabelAlign.userName.length == 0 || formLabelAlign.userName == '') {
                    ElMessage.warning({
                        message: '用户名不能为空!',
                        type: 'warning'
                    });
                    return false
                }
                if(formLabelAlign.passWord == null || formLabelAlign.passWord.length == 0 || formLabelAlign.passWord == '') {
                    ElMessage.warning({
                        message: '密码不能为空!',
                        type: 'warning'
                    });
                    return false
                }
          //登录接口请求
login(formLabelAlign).then(res => { console.log(res); }).catch(err => { }) }
       //get请求
       const fetchData = (id) => {
          fetchArticle(id).then(res => {
            postForm = res.data;
          }).catch(err => {

          })
       }
return {
                formLabelAlign,
                getUserRepositories,
          etchData } } }
</script>

reactive:取得一个对象并返回原始对象的响应式代理。

ref:接受一个值并返回一个响应式且可变的 ref 对象。ref 对象具有 .value 指向内部值的单个属式。

return:setup() 定义的变量必须 return 返回出去,这样才能在 template 中渲染出来。

 其余定义方法参考:

const cityS = ref([]); // 定义空数组
const contact = ref(""); //定义空对象
const timer = ref(null); // 定义null
const osTop = ref(0); // 定义数据0
const show = ref(false); // 定义是否显示

7、顶部导航栏吸顶:

  template:

  <div class="app-wrapper">
     <!-- 头部 --> <div v-if="$route.name!=='login'" :class="navBarFixed == true ? 'navBarWrap nav-container' :'nav-container'"> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> </div>

  css:

  .nav-container{
        border-bottom: 1px solid rgb(218, 218, 218);
        width: 100%;
        height: 45px;
        line-height: 45px;
  }
  .navBarWrap{
        position: fixed;
        top: 0;
        background: #fff;
        z-index: 9;
        -webkit-box-shadow: 0 7px 6px -6px rgb(218, 218, 218);
        -moz-box-shadow: 0 7px 6px -6px rgb(218, 218, 218);
        box-shadow: 0 7px 6px -6px rgb(218, 218, 218);
  }

  script:

  import { onMounted, onUnmounted, ref } from 'vue'
    export default {
        name: 'app',
        setup() {//导航栏吸顶悬浮
            const navBarFixed = ref(false);
            const watchScroll = () => {
                const osTop = document.documentElement.scrollTop || document.body.scrollTop;
          //滚动超过49px,添加吸顶class
if (osTop > 49) { navBarFixed.value = true; } else { navBarFixed.value = false; } }; onMounted(()=>{ window.addEventListener("scroll", watchScroll, true); }); onUnmounted(() => { window.addEventListener("scroll", watchScroll); }); return { navBarFixed, watchScroll, } } }

    

 

 

 

 

 

 

8、页面滚动超出后,回到顶部:

  template:

    <div class="app-wrapper">
     <!-- 中间部分 --> <div class="main-container">
       <!-- 路由页面展示内容 --> <router-view/>
       <!-- 吸顶按钮 --> <a href="javascript:;" id="return_top" v-if="show" @click="up()">
          <!-- element-plus icon控件,详情见:https://element-plus.gitee.io/#/zh-CN/component/icon --> <i class="el-icon-upload2"></i> </a> </div> </div>

  css:

    #return_top{
        position: fixed;
        right: 2.5rem;
        bottom: 1.5rem;
    }
    #return_top i{
        font-size: 30px;
    }
    #return_top i.el-icon-upload2:before{
        color: #999;
    }
    #return_top img{
        width: 100%;
        height: 100%;
    }

  script:

    import { onMounted, onUnmounted, ref } from 'vue'
    export default {
        name: 'app',
        setup() {
            const clientHeight = document.documentElement.clientHeight;
            const show = ref(false);
            const isTop = ref(true);
            const timer = ref();
            const handleScroll = () => {
                //获取滚动条的滚动高度
                const osTop = document.documentElement.scrollTop || document.body.scrollTop;
                if (osTop >= clientHeight) {
                    //如果滚动高度大于可视区域高度,则显示回到顶部按钮
                    show.value = true;
                } else {
                    //否则隐藏
                    show.value = false;
                }
                //主要用于判断当 点击回到顶部按钮后 滚动条在回滚过程中,若手动滚动滚动条,则清除定时器
                if (!isTop.value) {
                    clearInterval(timer.value);
                }
                isTop.value = false;
            };
            const up = () => {
                //设置一个定时器
                timer.value = setInterval(function() {
                    //获取滚动条的滚动高度
                    const osTop = document.documentElement.scrollTop || document.body.scrollTop;
                    //用于设置速度差,产生缓动的效果
                    const speed = Math.floor(-osTop / 6);
                    document.documentElement.scrollTop = document.body.scrollTop = osTop + speed;
                    isTop.value = true //用于阻止滚动事件清除定时器
                    if (osTop == 0) {
                        clearInterval(timer.value);
                    }
                }, 20);
            };
            onMounted(()=>{
                window.addEventListener("scroll", handleScroll, true);
            });
            onUnmounted(() => {
                window.removeEventListener("scroll", handleScroll);
            });
            return {
                show,
                up,
            }
        }
    }

 

推荐阅读