首页 > 编程学习 > Vue做项目必备(节省80%时间,持久更新,不讲武德)

目录

1.iconfont

2. sass版本问题

3.屏幕高宽度自适应

4. 跨域

5. 拦截器

 6.项目插件安装

7.登录鉴权(单路由)

8.插件引入、持久化、字体图标、富文本、时间戳

9. 跳转、返回、前进和后退

10.echarts图表的使用

11. vue组件中引入js文件(放script中)

 12.vue组件中引入css文件(放style中)

 13.插槽

 14.vue六种传值方式(属性传值、$refs、$parent、通知传值(广播传值)、本地传值、路由传值)

 15.增删改查

 16.登录+验证规则+重置

17.模拟数据

 18.电话邮箱正则验证

19.dialog弹框(可用于增删改查)

 20.登录的盒子居中

21.api封装


Vue脚手架中盒子高度设置问题:height:100vh;      //es6语法

1.iconfont

<template><div><ul><!-- 方法一: --><li><span class="iconfont">&#xe62f;&#xe644;&#xe616;</span></li><br><li><span class="iconfont">&#xe644;</span></li><li><span class="iconfont">&#xe616;</span></li><!-- 方法二 --><i class="iconfont icon-caidan"></i><i class="iconfont icon-jiazai1"></i><i class="iconfont icon-shangchuan"></i></ul></div>
</template><script>import iconfont from '../myicon/icon-font/download/font_20dtp1i3pv6/iconfont.css'export default {}
</script><style scoped>li>span{width: 50px;height: 50px;float: left;}
</style>

2. sass版本问题

1、vue中sass安装使用============================================================
方法一:我本地是将    "sass-loader": "^8.0.0",更换成了 "sass-loader": "^7.3.1",卸载当前版本   npm uninstall sass-loader
安装     npm install sass-loader@7.3.1 --save-dev方法二:如若不行,此时运行按照提示执行  npm rebuild node-sass  命令(如若还不行,则先运行npm install node-sass命令执行)

3.屏幕高宽度自适应

mounted() {// 调用自动调节this.fc_height();},methods: {// 获取屏幕宽高自动调节fc_height() {let html = document.documentElement || document.body;let height = html.clientHeight - 60;let aside = document.querySelector('.el-aside');aside.style.height = height + 'px';}}

4. 跨域

proxyTable: {'/admin': { //代理apitarget: 'http://ceshi5.dishait.cn/admin', //服务器api地址ws: true, // proxy websocketschangeOrigin: true, //是否跨域pathRewrite: { //重写路径'^/admin': ''}}},

5. 拦截器

//添加请求拦截器
axios.interceptors.request.use(config => {console.log(config)// 从sessionStorage获取token值,然后设置给请求头config.headers.Authorization = window.sessionStorage.getItem('token')// 在最后必须 return configreturn config
})

 6.项目插件安装

npm i element-ui -S                
npm install axios --save      
npm install echarts --save        
npm install vant --save   
npm install vuex -s
cnpm install node-sass@4.14.1 sass-loader@7.3.1 -s

7.登录鉴权(单路由)

		beforeEnter(to,from,next){if(sessionStorage.getItem("token")){next()}else {alert("请先登录");next('/')}},

8.插件引入、持久化、字体图标、富文本、时间戳

// 引入vuex
import Vuex from 'vuex';// 持久化=====================================================================
import VuexPersistence from 'vuex-persist'         //store中引入
const vuexLocal = new VuexPersistence({            //store中引入storage: window.localStorage
})plugins: [vuexLocal.plugin]                    //store中引入cnpm install --save vuex-persist               //下载// 引入vant组件====================================================================
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);// 引入第三方控件[分类参数]===============================================
npm i vue-table-with-tree-grid -S     //下载import TreeTable from 'vue-table-with-tree-grid'    //在main.js中使用
Vue.config.productionTip = false               //在main.js中使用
//全局注册组件===============================================
Vue.component("tree-table", TreeTable)// 导入字体图标===============================================
import './assets/fonts/iconfont.css'
// 导入富文本编辑器(用法)===============================================
import VueQuillEditor from 'vue-quill-editor'
// require styles 导入富文本编辑器对应的样式
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'// 将富文本编辑器,注册为全局可用的组件===============================================
Vue.use(VueQuillEditor)// 时间戳转换===============================================
Vue.filter('dateFormat', function(originVal) {const dt = new Date(originVal)const y = dt.getFullYear()const m = (dt.getMonth() + 1 + '').padStart(2, '0')const d = (dt.getDate() + '').padStart(2, '0')const hh = (dt.getHours() + '').padStart(2, '0')const mm = (dt.getMinutes() + '').padStart(2, '0')const ss = (dt.getSeconds() + '').padStart(2, '0')return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
})// 引入ElementUI组件===============================================
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);//Echarts图表引入===============================================
import echarts from 'echarts'
Vue.prototype.$echarts = echarts//引入axios和配置请求根路径===============================================
import axios from 'axios' 
axios.defaults.baseURL = 'https://www.liulongbin.top:8888/api/private/v1'
// 添加请求拦截器===============================================
axios.interceptors.request.use(config => {console.log(config)// 从sessionStorage获取token值,然后设置给请求头config.headers.Authorization = window.sessionStorage.getItem('token')// 在最后必须 return configreturn config
})
Vue.prototype.$http = axios

9. 跳转、返回、前进和后退

编程导航  我们可以用在渲染完元素不方便添加router-link的使用
编程导航提供的方法:
this.$router.push(路径) 跳转到哪个路由
this.$router.go(-1) 返回上一级
vue还提供一种方式 来实现导航  编程式导航 在事件中通过this.$router的方法来实现
我们主要掌握的方法
push()  进入到哪个页面
想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
go(-num) 返回哪个页面
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)
replace()
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。 没有办法使用go()返回了this.$route 和this.$router的区别:
this.$route 路由信息对象 可以获取参数列表
this.$router路由实例对象 可以实现页面的转换

10.echarts图表的使用

<template><div class="data_report"><div id="main" style="width: 600px;height:400px;"></div></div></template><script>
let echarts = require('echarts');
export default {mounted() {this.fc_echarts();},methods: {fc_echarts() {// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));console.log(myChart);// 绘制图表// 指定图表的配置项和数据let option = {// title: {//     text: '堆叠区域图'// },tooltip: {trigger: 'axis',axisPointer: {type: 'cross',label: {backgroundColor: '#6a7985'}}},legend: {data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']},toolbox: {feature: {saveAsImage: {}}},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},xAxis: [{type: 'category',boundaryGap: false,data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']}],yAxis: [{type: 'value'}],series: [{name: '邮件营销',type: 'line',stack: '总量',areaStyle: {},data: [120, 132, 101, 134, 90, 230, 210]},{name: '联盟广告',type: 'line',stack: '总量',areaStyle: {},data: [220, 182, 191, 234, 290, 330, 310]},{name: '视频广告',type: 'line',stack: '总量',areaStyle: {},data: [150, 232, 201, 154, 190, 330, 410]},{name: '直接访问',type: 'line',stack: '总量',areaStyle: {},data: [320, 332, 301, 334, 390, 330, 320]},{name: '搜索引擎',type: 'line',stack: '总量',label: {normal: {show: true,position: 'top'}},areaStyle: {},data: [820, 932, 901, 934, 1290, 1330, 1320]}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);}}
};
</script><style  scoped>#main{position: absolute;left: 313px;top: 126px;width: 700px;height: 500px;}</style>

11. vue组件中引入js文件(放script中)

import   { login }   from   "../scripts/apis.js";

 12.vue组件中引入css文件(放style中)

import   login    from   "../scripts/apis.scss";                        import   login    from   "../scripts/apis.css";

 13.插槽

匿名插槽:子组件<slot><slot>      父组件<child>今天天气阳光明媚<child>具名插槽:子组件<slot name="footer"><slot>        父组件<child>   <template>    <p>今天天气挺好<p>     <template>   <child>作用域插槽:子组件<slot :nickName="'Tusi'"></slot>父组件 <slot-child><template slot-scope="scope"><div>{{scope.nickName}}</div></template></slot-child>

 14.vue六种传值方式(属性传值、$refs、$parent、通知传值(广播传值)、本地传值、路由传值

​
在介绍组件传值之前先明确三种组件关系:父子组件、兄弟组件、表兄弟组件(a1,a2,a3 | a1和a3)、无关系组件(a,b)1.属性传值:父传子
可传值类型:固定值   绑定属性    方法   本类对象父:<htitle :bindMsg="msg" :run="run" :fatherThis="this"></htitle>子:props:{'mess':String,'bindMsg':[String, Number],'run':Function,'fatherThis':Object,}可传值类型:属性   方法 2.$refs:子传父与vue获取元素ref="dataNum"(this.$refs.dataNum.dataset.num)
父:<v-fgsheader ref="header"></v-fgsheader>       使用:this.$refs.header.msgthis.$refs.header.属性
this.$refs.header.方法子:data(){  return{  msg:"我是子组件header的值哟"  }      }vue获取元素:<span data-num="21" ref="dataNum" @click="getData">55</span>this.$refs.dataNum.dataset.num3.$parent:父传子
可传值类型:属性   方法 直接在子组件中使用this.$parent.XX,不需要做任何多余操作子 :getFatherProp(){alert(this.$parent.fatherMsg);},4.兄弟传兄弟————通知传值(广播传值)
只传基本数据类型,不能传方法。传输:通过 bus.$emit('名称','数据')传播数据接收:bus.$on('名称',function(){})示例:example定义bus.js文件:import Vue from 'vue'       var bus= new Vue();        export default bus;然后引入:import vueEvents from '../Model/vueEvent.js'5.本地传值( localStorage和vuex都是本地存储)
本地传值方式对于Vue而言有两种,一种是JS的localStorage,另一种Vuex。1. localStorage存:localStorage.setItem('tolist',JSON.stringify(this.tolist));
取:var tolist = JSON.parse(localStorage.getItem('tolist'));2. Vuex
使用数据: this.\$store.state.count
调用方法: this.$store.commit('incCount');1.定义存储数据  var state = { count:1,}2. //类似于计算属性  state里边的数据改变时候触发的方法。 可以做一些操作 并且可以有返回值var getterfl={completedCountChange(state){return state.count * 2 +'位';}}3.Action 类似于 mutation,不同在于: Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作var actionfl = {asynIncCount(context){  
//因此你可以调用context.commit来提交一个mutation  使用action需要用dispatchcontext.commit('incCount');}
}6.路由传值(this.$router.push)
1.父组件push使用this.$router.push
2.在子组件中获取参数的时候是this.$route.params1.动态路由传值1.1 配置动态路由routes:[//动态路由参数  以冒号开头{path:'/user/:id',conponent:User}]1.2 传值第一种写法 :  <router-link :to="'/user/'+item.id">传值</router-link>第二种写法 : goToUser(id) {this.$router.push( {path:'/user/'+id});}1.3 在对应页面取值this.$route.params;  //结果:{id:123}2. Get传值(类似HTMLGet传值)6.路由传值(this.$router.push)
1.父组件push使用this.$router.push
2.在子组件中获取参数的时候是this.$route.params1.动态路由传值1.1 配置动态路由routes:[//动态路由参数  以冒号开头{path:'/user/:id',conponent:User}]1.2 传值第一种写法 :  <router-link :to="'/user/'+item.id">传值</router-link>第二种写法 : goToUser(id) {this.$router.push( {path:'/user/'+id});}1.3 在对应页面取值this.$route.params;  //结果:{id:123}2. Get传值(类似HTMLGet传值)2.1 配置路由const routes = [{path:'/user',component:User},]2.2 传值  第一种写法 : <router-link :to="'/user/?id='+item.id">传值</router-link>第二种写法 : goToUser(id) {//'user' 是路径名称this.$router.push({path:'user',query:{ID:id}});}2.3 在对应页面取值this.$route.query;  //结果 {id:123}3. 命名路由push传值3.1 配置路由const routes = [{path:'/user',name: 'User',component:User},]
3.2 传值  goToUser(id) {//'User' 是路径重命名this.$router.push({name:'User',params:{ID:id}});}
3.3 在对应页面取值this.$route.params;  //结果:{id:123}​

 15.增删改查

增:删:改:查询/搜索功能:
eg:"ruleForm.auditState"
<el-form :model="ruleForm" ref="ruleForm" class="el-ruleForm" size="small"><el-form-item label="审核状态" prop="auditState"><el-select v-model="ruleForm.auditState" placeholder="请选择" clearable><el-option v-for="item in statusArr" :key="item.name" :label="item.name" :value="item.id" /></el-select></el-form-item>
</el-form>
//把参数写在需要的请求列表里:
const params = {areaName: this.ruleForm.areaName ? this.ruleForm.areaName : null,cityName: this.ruleForm.cityName ? this.ruleForm.cityName : null,// cityCode: this.cityCode ? this.cityCode : null,auditState: this.ruleForm.auditState ? this.ruleForm.auditState : null,pageNum: this.pageNum,pageSize: this.pageSize}========================================================================================
消息提示:两种书写方式1.this.$message({type: 'success',message: '禁用成功!'})2.this.$message.success('登录成功');

 16.登录+验证规则+重置

<template><div class="login_container"><div class="login_box"><div class="avatar_box"><img src="../assets/111.gif" alt="" /></div><el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form"><el-form-item prop="username"><el-input v-model="loginForm.username" prefix-icon="el-icon-user"></el-input></el-form-item><el-form-item prop="password"><el-input v-model="loginForm.password" prefix-icon="el-icon-document" type="password"></el-input></el-form-item><el-form-item class="btns"><el-button type="primary" @click="login">Login</el-button><el-button type="info" @click="resetLoginForm">Reset</el-button></el-form-item></el-form></div><iframe src="https://www.tukuppt.com/muban/lgamzeod.html" allow="autoplay" hidden /></div></template><script>
export default {data() {return {loginForm: {username: 'admin',password: '123456'},loginFormRules: {username: [{ required: true, message: '请输入登录名称', trigger: 'blur' }, { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }],password: [{ required: true, message: '请输入登录密码', trigger: 'blur' }, { min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }]}};},methods: {resetLoginForm() {this.$refs.loginFormRef.resetFields();},login() {this.$refs.loginFormRef.validate(async valid => {if (!valid) return;const { data: res } = await this.$http.post('login', this.loginForm);console.log(res)if (res.meta.status !== 200) return this.$message.error('登录失败!');this.$message.success('登录成功');window.sessionStorage.setItem('token', res.data.token);this.$router.push('/home');});}}
};
</script>

17.模拟数据

下拉框:
statusArr: [{ id: 1, name: '待审核' }, { id: 2, name: '通过' }, { id: 3, name: '拒绝' }],

 18.电话邮箱正则验证

data() {var checkEmail = (rule, value, cb) => {const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;if (regEmail.test(value)) {return cb();}cb(new Error('请输入正确的邮箱'));};// 验证手机号var checkMobile = (rule, value, cb) => {const regMobile = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/;if (regMobile.test(value)) {return cb();}cb(new Error('请输入合法的手机号'));};return {// 验证规则addFormRules: {email: [{required: true,message: '请输入邮箱',trigger: 'blur'}, {validator: checkEmail,trigger: 'blur'}],}}   

19.dialog弹框(可用于增删改查)

<el-dialog title="修改用户" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed"><el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="70px"><el-form-item label="用户名"><el-input v-model="editForm.username"></el-input></el-form-item><el-form-item label="邮箱" prop="email"><el-input v-model="editForm.email"></el-input></el-form-item><el-form-item label="手机" prop="mobile"><el-input v-model="editForm.mobile"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="editDialogVisible = false">取 消</el-button><el-button type="primary" @click="editUserInfo">确 定</el-button></span></el-dialog>

 20.登录的盒子居中

	left: 50%;top: 50%;transform: translate(-50%, -50%);

21.api封装

import axios from 'axios' // 引入axios
import { ElMessage, ElMessageBox } from 'element-plus'
import { store } from '@/store'
import { emitter } from '@/utils/bus.js'const service = axios.create({baseURL: import.meta.env.VITE_BASE_API,timeout: 99999
})
let acitveAxios = 0
let timer
const showLoading = () => {acitveAxios++if (timer) {clearTimeout(timer)}timer = setTimeout(() => {if (acitveAxios > 0) {emitter.emit('showLoading')}}, 400)
}const closeLoading = () => {acitveAxios--if (acitveAxios <= 0) {clearTimeout(timer)emitter.emit('closeLoading')}}// http request 拦截器
service.interceptors.request.use(config => {if (!config.donNotShowLoading) {showLoading()}const token = store.getters['user/token']const user = store.getters['user/userInfo']config.data = JSON.stringify(config.data)config.headers = {'Content-Type': 'application/json','x-token': token,'x-user-id': user.ID}return config},error => {closeLoading()ElMessage({showClose: true,message: error,type: 'error'})return error}
)// http response 拦截器
service.interceptors.response.use(response => {closeLoading()if (response.headers['new-token']) {store.commit('user/setToken', response.headers['new-token'])}if (response.data.code === 0 || response.headers.success === 'true') {if (response.headers.msg) {response.data.msg = decodeURI(response.headers.msg)}return response.data} else {ElMessage({showClose: true,message: response.data.msg,type: 'error'})if (response.data.data && response.data.data.reload) {store.commit('user/LoginOut')}return response.data.msg ? response.data : response}},error => {closeLoading()switch (error.response.status) {case 500:ElMessageBox.confirm(`<p>检测到接口错误${error}</p><p>错误码<span style="color:red"> 500 </span>:此类错误内容常见于后台panic,请先查看后台日志,如果影响您正常使用可强制登出清理缓存</p>`, '接口报错', {dangerouslyUseHTMLString: true,distinguishCancelAndClose: true,confirmButtonText: '清理缓存',cancelButtonText: '取消'}).then(() => {store.commit('user/LoginOut')})breakcase 404:ElMessageBox.confirm(`<p>检测到接口错误${error}</p><p>错误码<span style="color:red"> 404 </span>:此类错误多为接口未注册(或未重启)或者请求路径(方法)与api路径(方法)不符--如果为自动化代码请检查是否存在空格</p>`, '接口报错', {dangerouslyUseHTMLString: true,distinguishCancelAndClose: true,confirmButtonText: '我知道了',cancelButtonText: '取消'})break}return error}
)export default service
import service from '@/utils/request'export const getApiList = (data) => {return service({url: '/api/getApiList',method: 'post',data})
}//在使用请求的组件里面引入
import { mapActions } from 'vuex'
import { captcha } from '@/api/user'
import { checkDB } from '@/api/initdb'
export default {name: 'Login',data() {return(){}}
}

21.Vue.js Ajax(axios)

GET 方法传递参数格式如下:

传递参数说明
// 直接在 URL 上添加参数 ID=12345
axios.get("/user?ID=12345").then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});// 也可以通过 params 设置参数:
axios.get("/user", {params: {ID: 12345}}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});

POST 方法传递参数格式如下: 

传递参数说明
axios.post("/user", {firstName: "Fred",        // 参数 firstNamelastName: "Flintstone"    // 参数 lastName}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});

执行多个并发请求 

实例
function getUserAccount() {return axios.get("/user/12345");
}function getUserPermissions() {return axios.get("/user/12345/permissions");
}
axios.all([getUserAccount(), getUserPermissions()]).then(axios.spread(function (acct, perms) {// 两个请求现在都执行完成}));

22.JSON.parse()

在接收服务器数据时一般是字符串。

我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象。

JSON.parse(text[, reviver])

参数说明:

  • text:必需, 一个有效的 JSON 字符串。
  • reviver: 可选,一个转换结果的函数, 将为对象的每个成员调用此函数。

23.vuex

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
  • Vuex 是一个数据管理工具,我们可以通过它简化组件间的数据共享问题。
  • Vuex 的安装和使用方法。
  • 使用 new Vuex.Store ({…}) 创建数据仓库。

24.vue3升级安装和卸载安装

1. 安装vue-cli
1.1 卸载旧版本
npm uninstall vue-cli -g
yarn global remove vue-cli
1.2 安装新的包
npm install -g @vue/cli
yarn global add @vue/cli
1.3 升级全局的 Vue CLI 包
npm update -g @vue/cli
yarn global upgrade --latest @vue/cli
1.4 查看当前 Vue CLI 版本
vue --version
vue -V

25.vue3项目初始化

创建my-project项目:vue create my-project提供了三种设置:Vue2版、Vue3版、手动选择功能;
按键盘上下键选择默认(default)还是手动(Manually);
这里我选择第三种:Manually select features;
回车键确认;
3. 选择配置
选择自己所要集成的配置(格键是选中与取消,A键是全选,回车确定)
这里我的选择如下:配置项:(*) Choose Vue version:选择 Vue 版本
(*)Babel:支持使用Babel编译器
(*)TypeScript:支持使用 TypeScript 书写源码
( )Progressive Web App (PWA) Support:支持PWA
(*) Router:支持 vue-router
(*)Vuex:支持 vuex
(*)CSS Pre-processors:支持 CSS 预处理器
(*)Linter / Formatter:支持代码风格检查和格式化
( )Unit Testing:支持单元测试
( )E2E Testing: 支持 E2E 测试
4. 选择 Vue 版本这里我选择:3.x安装的 vue-cli 将会是基于 vue3.x 版本5. 是否使用 class 风格的组件语法
如果在项目中想要保持使用 TypeScript 的 class 风格的话,建议大家选择y。这里我选择:y6. 是否使用 Babel 与 TypeScript 一起用于自动检测的填充
这里我选择:y7. 是否使用 history 路由模式这里我选择:y8. 选择CSS预处理器Sass/SCSS分两种:node-sass:是用 node(调用 cpp 编写的 libsass)来编译 sass,是自动编译实时的
dart-sass:是用 drat VM 来编译 sass,需要保存后才会生效
这里我选择:Sass/SCSS(with node-sass)9. 选择 eslint 配置ESLint with error prevention only:只进行报错提醒;
ESLint + Airbnb config:Airbnb配置,不严谨模式;
ESLint + Standard config:标准配置,正常模式;
ESLint + Prettier:严格模式;
TSlint:typescript格式验证工具
这里我选择:ESLint with error prevention only10. 选择什么时候执行 eslint 校验Lint on save:保存时检查
Lint and fix on commit:提交时检查
这里我选择:Lint on save11. 选择配置文件存放的位置In dedicated config files:在专用的配置文件中单独存放
In package.json:存放在 package.json 中
这里我选择:In dedicated config files12. 是否保存之前的配置项这里我选择:N13. 等待下载依赖模块14. 装好后,进入目录,启动cd my-project ( 进入项目根目录 )
yarn serve ( 启动项目 )项目目录
现在的目录是 Vue3.x 的 cli 看上去简洁多了,去掉了 Vue2.x 中 build 和 config 等目录项目配置
在项目的根目录下新建 vue.config.js 文件(是根目录,不是src目录)module.exports = {publicPath: process.env.NODE_ENV === "production" ? "./" : "/", // 部署生产环境和开发环境下的URLoutputDir: 'dist', // 构建输出目录(npm run build 或 yarn build 时 ,生成文件的目录名称)assetsDir: 'assets', // 用于放置生成的静态资源(js、css、img、fonts)的;(项目打包之后,静态资源会放在这个文件夹下)lintOnSave: true, // 是否开启eslint保存检测,有效值:ture | false | 'error'runtimeCompiler: false, // 是否使用包含运行时编译器的Vue核心的构建transpileDependencies: [], // 默认情况下 babel-loader 忽略其中的所有文件 node_modules,这里可增加例外的依赖包名productionSourceMap: false, // 是否在构建生产包时生成 sourceMap 文件,false将提高构建速度filenameHashing: false, //默认情况下,生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存。你可以通过将这个选项设为 false 来关闭文件名哈希。(false的时候就是让原来的文件名不改变)css: { // 配置高于chainWebpack中关于 css loader 的配置modules: false, // 是否开启支持 foo.module.css 样式extract: true, // 是否使用 css 分离插件 ExtractTextPlugin,采用独立样式文件载入,不采用 <style> 方式内联至 html 文件中sourceMap: false, // 是否构建样式地图,false 将提高构建速度loaderOptions: { // css预设器配置项sass: {data: '' //`@import "@/assets/scss/mixin.scss";`},css: {// options here will be passed to css-loader},postcss: {// options here will be passed to postcss-loader}}},configureWebpack: (config) => {//webpack-bundle-analyzer 插件const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginif (process.env.NODE_ENV === 'production') {return {plugins: [new BundleAnalyzerPlugin()]}}},// 支持webPack-dev-server的所有选项devServer: {open: true, // 是否自动启动浏览器host: '0.0.0.0',port: 3000, // 端口号https: false,hotOnly: false,proxy: null,// proxy: { // 配置多个代理//     '/api': {//         target: '<url>',//         ws: true,//         changOrigin: true//     },//     "/foo": {//         target: "<other_url>"//     }// },before: app => {}},parallel: require('os').cpus().length > 1, // 构建时开启多进程处理 babel 编译pwa: { // https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa},pluginOptions: {} // 第三方插件配置
};

 25.盒子居中

 .login_box{width: 450px;height: 300px;background: #fff;border-radius: 3px;position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);}


本文链接:https://www.ngui.cc/el/2883518.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000