简述
近日项目技术选型为Vue+Typescript
,终于也得体验一把typescript
的强大,
其相关依赖库版本如下,截止今日皆为最新版本号:
"flyio": "^0.6.1",
"iview": "^3.1.2",
"vue": "^2.5.17",
"vue-class-component": "^6.0.0",
"vue-property-decorator": "^7.0.0",
"vue-router": "^3.0.1",
"vuex": "^3.0.1",
"vuex-class": "^0.3.1",
"typescript": "^3.0.0",
一、项目相关配置在哪里写?
由于采用vue-cli@3.x版本来初始化工程,所以没有了2.x版本对外暴露的webpack配置文件,所以如果相对项目进行一些配置,需要在项目根目录下新建vue.config.js
.
比如需要修改项目启动的端口号,去掉打包后文件名的哈希值,如下:
module.exports = {
devServer: {
port: 8989
},
filenameHashing: false
}
如果需要将项目配置在服务器子级目录中,则需:
module.exports = {
baseUrl: '/child', // 默认为根目录下 '/'
devServer: {
port: 8989
},
filenameHashing: false
}
二、配置完路由后,无法在组件中使用this. r o u t e 和 t h i s . route和this. route和this.router
一般如此相像的问题需要修改src
目录下shims-vue.d.ts
文件
import Vue from 'vue';
import VueRouter, {Route} from 'vue-router';
declare module '*.vue' {
export default Vue;
}
declare module 'vue/types/vue' {
interface Vue {
$router: VueRouter; // 这表示this下有这个东西
$route: Route;
}
}
下面是组件中监听路由变化代码
export default class Home extends Vue {
@Watch('$route')
private onChildChanged(val: Route, oldVal: Route) {
console.log(val, oldVal);
}
}
上面直接使用是没有问题的,问题在组件中写组件的路由钩子发现不会触发.如下:
<script lang="ts">
import {Component, Vue, Watch} from 'vue-property-decorator';
import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src
import { Route, RawLocation } from 'vue-router';
@Component({
components: {
HelloWorld,
},
})
export default class Home extends Vue {
@Watch('$route')
private onChildChanged(val: Route, oldVal: Route) {
console.log(222);
console.log(val, oldVal);
}
// 不触发
private beforeRouteUpdate(to: Route, from: Route, next: () => void): void {
console.log(1);
console.log(to, from);
next();
}
}
</script>
解决方法就需要用到Component
下的registerHooks
方法,如下:
// main.ts
import Component from 'vue-class-component';
Component.registerHooks([
'beforeRouteEnter',
'beforeRouteLeave',
'beforeRouteUpdate',
]);
注册完毕后可使用
三、vuex辅助方法取消,换而使用vuex-class注解方式使用
- 比如使用
@State 来获取状态
- 比如使用
@Action 来获取动作
具体可见 vuex-class
下面以@State
为例
import {State, Getter, Action, Mutation} from 'vuex-class';
@Component
export default class HelloWorld extends Vue {
@State private count: number; // 这里ts编译报错,1.说必须进行初始化. 2.另外字段前面需要加上权限修饰符 private,protected,public
@Prop() private msg: string|any;
private handleClick() {
console.log(this.count);
}
}
第一个问题有以下三种解决方法
- 修改
tsconfig.json
文件,在compilerOptions
选项中加入"strictPropertyInitialization": false
- 修改
@State
写法为@State private count!: number;
,里面加了!
感叹号,表示我会给你赋值的,别担心.但是这种方式虽然代码正常运行,IDE却报错,对于强迫症的我们不能忍啊,于是乎继续寻找其他方法 - 依然修改
@State
的写法为@State private count: number|any;
,在后面加上number|any
,表示是数字或者任意值当然包括undefined
四、前后端合并代码图片资源找不到(404)
- 这种情况一般都是图片访问的路径不正确
- 一般我们的项目部署后不会放到服务器根目录,而是会创建一个子目录放进去,比如放到
/child
子目录里面 - 前端打包完毕后所有的资源在
dist
目录下,这是图片的正确访问路径为/child/dist/img/logo.png
,而图片资源打包完成后实际访问路径为/img/logo.png
- 因此需要修改图片的正确访问路径,由于基于webpack对图片进行打包的,所以需要修改一下
vue.config.js
中webpack
配置项,主要修改url-loader
中的publicPath
选项
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 为生产环境修改配置...
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options,
{ publicPath: '/child/dist/' }
))
} else {
// 为开发环境修改配置...
}
},
后续使用有问题会在此继续补充!