Vue3.x 从零开始(一)—— Vue-cli or Vite 构建 TypeScript 项目
<p><span style="font-size: 14px">千呼万唤始出来,2020 年 9 月 19 日凌晨,Vuejs 3.0 终于发布了,代号:One Piece</span></p><p><span style="font-size: 14px">作为一名从 Vue 1.x 就开始接触 Vue 的老玩家,心里只有一句话想说:学不动了...</span></p>
<p><span style="font-size: 14px">但学不动也得学...</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px">原本打算写一写 2.x 和 3.x 的差异,但仔细捋了一下发现内容还不少,干脆抛弃原本的思维,从零开始学 Vue</span></p>
<p><span style="font-size: 14px">所以《Vue 3.x 从零开始》系列可能比较啰嗦。对于 Vue 2.x 的用户,直接阅读官方的迁移指南是最好的选择</span></p>
<p><span style="font-size: 14px">当然,如果有兴趣和我一起从零开始,也是一个不错的选择</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px">在开始之前,请确保已经正确安装了 node.js </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 16px"><strong>一、Vue CLI 构建项目</strong></span></p>
<p><span style="font-size: 14px">为了快速构建 Vue 项目,Vue 团队开发了脚手架工具 Vue CLI,这个脚手架需要全局安装</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">yarn global add @vue/cli
<span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 128, 0, 1)"># OR</span>
npm install </span>-g @vue/cli</span></pre>
</div>
<p><span style="font-size: 14px"><strong><span style="color: rgba(128, 0, 0, 1)">对于 Vue 3.x 的项目,需要使用 Vue CLI v4.5 以上的版本。</span></strong>如果你的 Vue CLI 版本较低,也需要用上面的命令升级</span></p>
<p><span style="font-size: 14px">安装完成后可以在命令行输入 <span class="cnblogs_code">vue -V </span> (注意第二个 V 大写),如果出现版本号则安装成功</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200923145300179-699341871.png" alt="" loading="lazy"></span></p>
<p><span style="font-size: 14px">然后在需要创建项目的文件夹下启动终端,在命令行输入下面的命令</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">vue ui</span></pre>
</div>
<p><span style="font-size: 14px">这个命令会在浏览器打开一个页面(http://localhost:8000/project/select)</span></p>
<p><span style="font-size: 14px">这是 Vue CLI 提供的可视化工具,可以通过页面上的【创建】标签创建项目</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px">除了这种可视化的方式之外,还可以完全通过命令行创建项目:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">vue create my-vue3-demo</span><br><span style="color: rgba(0, 128, 0, 1); font-size: 14px"># my-vue3-demo 是项目目录的名称</span></pre>
</div>
<p><span style="font-size: 14px">运行命令之后,通过【↑】【↓】键选择条目</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200923150223545-1879818749.png" alt="" width="484" height="134" loading="lazy"></span></p>
<p><span style="font-size: 14px">这里可以直接选择 Vue 3 然后回车,Vue CLI 就会帮我们完成后续的创建工作</span></p>
<p><span style="color: rgba(128, 128, 128, 1); font-size: 14px">// 也可以选择第三项 “Manually select features”,会有更多的自定义配置,这里暂不介绍</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 16px"><strong>二、项目结构</strong></span></p>
<p><span style="font-size: 14px">项目创建之后,会在当前目录下多出一个项目文件夹</span></p>
<p><span style="font-size: 14px">通过命令行创建的默认 Vue 3 项目是一个比较纯粹的项目</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200923152902236-231041888.png" alt="" width="305" height="111" loading="lazy"></span></p>
<p><span style="font-size: 14px">从它的<strong> <span style="color: rgba(0, 128, 128, 1)">package.json</span> </strong>中可以看到只有 vue.js 的核心依赖</span></p>
<p><span style="font-size: 14px">然后启动项目试试,在项目根目录运行终端,在命令行输入</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">npm run serve</span></pre>
</div>
<p><span style="font-size: 14px">在浏览器中打开链接 <strong><span style="color: rgba(0, 128, 128, 1)">http://localhost:8080/</span></strong>,就能看到项目的启动页</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200923160233683-1921901133.png" alt="" width="533" height="355" loading="lazy"></span></p>
<p><span style="font-size: 14px">项目默认使用的端口是 8080,如果想使用别的端口,可以在<span style="color: rgba(128, 0, 0, 1)"><strong>项目的根目录</strong></span>创建一个<span style="color: rgba(0, 128, 128, 1)"> <strong>vue.config.js</strong> </span></span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vue.config.js</span>
module.exports =<span style="color: rgba(0, 0, 0, 1)"> {
outputDir: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">dist</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 打包的目录</span>
lintOnSave: <span style="color: rgba(0, 0, 255, 1)">true</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在保存时校验格式</span>
productionSourceMap: <span style="color: rgba(0, 0, 255, 1)">false</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 生产环境是否生成 SourceMap</span>
<span style="color: rgba(0, 0, 0, 1)">devServer: {
open: </span><span style="color: rgba(0, 0, 255, 1)">true</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 启动服务后是否打开浏览器</span>
overlay: { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 错误信息展示到页面</span>
warnings: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
errors: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
},
host: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">0.0.0.0</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
port: </span><span style="color: rgba(128, 0, 128, 1)">8066</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 服务端口</span>
https: <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">,
hotOnly: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> proxy: { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置代理
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> '/api': {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> target: host,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> changeOrigin: true,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> pathRewrite: {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> '/api': '/',
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> }
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> },
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> },</span>
<span style="color: rgba(0, 0, 0, 1)">},
}</span></span></pre>
</div>
<p><span style="font-size: 14px">这个文件中的<span style="color: rgba(0, 128, 128, 1)"><strong> devServer.port</strong> </span>即启动本地服务的端口(更多配置可以参考官方文档) </span></p>
<hr>
<p><span style="font-size: 14px">项目中有一个 public 文件夹,可以存放一些不需要经过 webpack 打包的文件(参考链接)</span></p>
<p><span style="font-size: 14px">这个目录下有一个 index.html 文件,这是整个应用的 html 基础模板,也是打包编译后的项目入口</span></p>
<p><span style="font-size: 14px">这个 index.html 文件中有一个<span style="color: rgba(0, 128, 128, 1)"><strong> #app</strong></span> 节点:</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200923192649809-1159646399.png" alt="" width="547" height="67" loading="lazy"></span></p>
<p><span style="font-size: 14px">Vue 的实例会挂载到这个节点</span></p>
<hr>
<p><span style="font-size: 14px">项目的代码在 src 目录下:</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200923191847968-1868741333.png" alt="" width="280" height="181" loading="lazy"></span></p>
<p><span style="font-size: 14px">现在的 src 目录非常简洁,其中 <span style="color: rgba(0, 128, 128, 1)"><strong>main.js</strong></span> 是 webpack 打包的入口文件</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200923192027670-961205145.png" alt="" width="389" height="152" loading="lazy"></span></p>
<p><span style="font-size: 14px">main.js 只是引入了 App.vue 组件,并挂载到上面提到的 #app 节点下</span></p>
<p><span style="font-size: 14px">这里的 <span style="color: rgba(128, 0, 0, 1)"><strong>createApp</strong></span> 方法是 Vue 3 新增的全局 API,用来创建一个 Vue 应用,并挂载到某个 DOM 节点</span></p>
<p><span style="font-size: 14px">在 2.x 的时代,上面的代码是这样写的:<span style="color: rgba(128, 128, 128, 1)">// 以下内容为 2.x 的对比,不感兴趣的话可以直接跳到下一节</span></span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200923195302784-1928595134.png" alt="" width="296" height="88" loading="lazy"></span></p>
<p><span style="font-size: 14px">从表面上看,createApp 只是改良版的 render 函数,但其实他解决了 2.x 中的一些不太优雅用法</span></p>
<p><span style="font-size: 14px">2.x 时代的 Vue 没有“应用”的概念,所谓的应用只是一个 Vue 的根实例 <span class="cnblogs_code"><span style="color: rgba(0, 0, 255, 1)">new</span> Vue()</span> </span></p>
<p><span style="font-size: 14px">当我们需要修改一些全局属性的时候,只能通过 Vue 对象本身来修改,比如:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 2.x 时代的全局属性</span>
Vue.prototype.$http =<span style="color: rgba(0, 0, 0, 1)"> axios;
Vue.directive(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">focus</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, {
inserted: el </span>=><span style="color: rgba(0, 0, 0, 1)"> el.focus()
});
Vue.config.errorHandler </span>= errorHandler;</span></pre>
</div>
<p><span style="font-size: 14px">这样的行为会污染 Vue 对象,导致从同一个 Vue 创建的实例会共享相同的全局配置</span></p>
<p><span style="font-size: 14px">而通过 createApp 返回的是独立的实例,修改该实例的属性不会影响其他 createApp 创建的实例:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 3.x createApp</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> foo =<span style="color: rgba(0, 0, 0, 1)"> createApp(Foo);
foo.directive(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">focus</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> ... </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">const</span> bar =<span style="color: rgba(0, 0, 0, 1)"> createApp(Bar);
bar.directive(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">focus</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> ... </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> foo 和 bar 都具备了 focus 指令,但这两个指令的内容相互独立</span></span></pre>
</div>
<p><span style="font-size: 14px">如果确实需要两个应用共享配置,还可以通过 createApp 创建一个工厂函数:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 255, 1)">const</span> createMyApp = options =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">const</span> app =<span style="color: rgba(0, 0, 0, 1)"> createApp(options)
app.directive(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">focus</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> ... </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> app
}
</span><span style="color: rgba(0, 0, 255, 1)">const</span> foo = createMyApp(Foo).mount(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">#foo</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">const</span> bar = createMyApp(Bar).mount(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">#bar</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> foo 和 bar 会具备同一个 focus 指令</span></span></pre>
</div>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 16px"><strong>三、使用 Vite 构建项目</strong></span></p>
<p><span style="font-size: 14px">除了上面的 Vue CLI 创建项目之外,Vue 3.x 还可以通过新工具 Vite 创建项目</span></p>
<p><span style="font-size: 14px">Vite 是一个由原生 ES 模块驱动的 Web 开发构建工具,支持模块热更新和按需加载</span></p>
<p><span style="font-size: 14px">用尤大的话来讲,用了 Vite 之后就可以告别 webpack 了</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200924101637887-2041166759.png" alt="" width="448" height="127" loading="lazy"> </span></p>
<p><span style="font-size: 14px">先来用 Vite 创建一个项目吧:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">npm init vite-app <span style="color: rgba(128, 0, 0, 1)"><project-name></span><span style="color: rgba(0, 128, 0, 1)">
# 将 <project-name> 改为自己的项目名</span></span></pre>
</div>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200924104356055-194762414.png" alt="" width="296" height="355" loading="lazy"></span></p>
<p><span style="font-size: 14px">项目结构也非常简洁,在 package.json 中只引入了 vue.js</span></p>
<p><span style="font-size: 14px">然后安装依赖,并启动项目:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1); font-size: 14px">npm install
npm run dev</span></pre>
</div>
<p><span style="font-size: 14px">项目地址为 <span style="color: rgba(0, 128, 128, 1)"><strong>http://localhost:3000/</strong></span>,如果页面没有自动打开,可以手动打开链接查看</span></p>
<p><span style="font-size: 14px">如果需要对 Vite 进行配置,也需要在根目录创建一个 config 文件,命名为 <span style="color: rgba(128, 0, 0, 1)"><strong>vite.config.js</strong></span>(或者 vite.config.ts)</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> vite.config.js</span>
module.exports =<span style="color: rgba(0, 0, 0, 1)"> {
port: </span><span style="color: rgba(128, 0, 128, 1)">8077</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 服务端口</span>
proxy: { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 代理
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> string shorthand</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/foo</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://localhost:4567/foo</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> with options</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/api</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
target: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://jsonplaceholder.typicode.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
changeOrigin: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
rewrite: (path) </span>=> path.replace(/^\/api/, <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">),
},
},
};</span></span></pre>
</div>
<p><span style="font-size: 14px">更多配置可以参考源码中的<strong> config.ts</strong>。不过大部分的配置项和上面提到的 vue.config.js 是一样的</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px">目前(2020-09-24)Vite 还处于 beta 阶段,用 Vite 创建项目的方式可以了解,但不建议用到项目中</span></p>
<p><span style="font-size: 14px">如果想学习更多关于 Vite 的知识,可以查看 @yuuang 写的《Vite 源码分析》</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 16px"><strong>四、TypeScript</strong></span></p>
<p><span style="font-size: 14px">Vue 3 有一个重要的特性就是更好的支持 TypeScirpt</span></p>
<p><span style="font-size: 14px">在使用 Vue CLI 创建项目的时候,可以选择<span style="color: rgba(128, 0, 0, 1)"><strong> "Manually select features"</strong> </span>选项,然后选择<strong><span style="color: rgba(128, 0, 0, 1)"> "TypeScript"</span></strong>,这样就能直接创建 ts 项目</span></p>
<p><span style="font-size: 14px">如果一开始没有创建 ts 项目,但电脑上装有 Vue CLI,可以通过下面的命令将项目改造为 ts 项目:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">vue add typescript</span></pre>
</div>
<p><span style="font-size: 14px">不过我们也可以自己动手,一步一步的引入 TypeScript,看看 <span style="color: rgba(0, 128, 128, 1)"><strong>vue add typescript</strong> </span>到底做了什么</span></p>
<p><span style="font-size: 14px">首先安装 typescript 依赖:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">npm install typescript -D</span></pre>
</div>
<p><span style="font-size: 14px">然后在项目根目录创建<span style="color: rgba(0, 128, 128, 1)"><strong> tsconfig.json</strong> </span>文件:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">include</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: [
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/**/*.ts</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/**/*.tsx</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">src/**/*.vue</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
],
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">exclude</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: [
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">node_modules</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
],
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">compilerOptions</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 与 Vue 的浏览器支持保持一致</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">target</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">es5</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果使用 webpack 2+ 或 rollup,可以利用 tree-shake:</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">module</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">es2015</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 这可以对 `this` 上的数据 property 进行更严格的推断</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">strict</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">moduleResolution</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">node</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
}
}</span></span></pre>
</div>
<p><span style="font-size: 14px">然后把 src 目录下的<strong><span style="color: rgba(128, 0, 0, 1)"> main.js 文件名改为 main.ts</span></strong><span style="color: rgba(0, 0, 0, 1)">,以及其他 js 文件改为 ts 后缀(config.js => config.ts)</span></span></p>
<p><span style="font-size: 14px">并编写 <span class="cnblogs_code">.d.ts</span> 文件 <span style="color: rgba(0, 128, 128, 1)"><strong>shims-vue.d.ts</strong></span> 放到 src 目录下,和 main.ts 平级</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> shims-vue.d.ts </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
declare module </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">*.vue</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> {
import { defineComponent } </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">vue</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">const</span> component: ReturnType<<span style="color: rgba(0, 0, 255, 1)">typeof</span> defineComponent><span style="color: rgba(0, 0, 0, 1)">;
export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> component;
}</span></span></pre>
</div>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200924151224901-1932402468.png" alt="" width="219" height="359" loading="lazy"></span></p>
<p><span style="font-size: 14px">由于 Vue 3 是使用 TypeScript 编写的,所以只要在 <script> 标签上声明 <span style="color: rgba(128, 0, 0, 1)"><strong>lang="ts"</strong></span>,就能直接在 .vue 文件中使用 ts 语法</span></p>
<p><span style="font-size: 14px">为了让 TypeScript 能够正确推断 Vue 组件中的类型,还需要使用全局方法 <span style="color: rgba(0, 128, 128, 1)"><strong>defineComponent</strong></span> 来定义组件</span></p>
<p><span style="font-size: 14px"><img src="https://img2020.cnblogs.com/blog/1059788/202009/1059788-20200924150304940-1656143287.png" alt="" width="600" height="305" loading="lazy"></span></p>
<p><span style="font-size: 14px">Vue 有一些特性和 TypeScript 并不能完美契合 (如 computed 的返回类型)</span></p>
<p><span style="font-size: 14px">为了更好的使用 ts,建议提前阅读《TypeScript 支持》</span></p>
<p><span style="font-size: 14px"> </span></p>
<p><span style="font-size: 14px">到这里项目内部的改造基本完成,接下来<span style="color: rgba(128, 0, 0, 1)"><strong>只要将入口文件从 main.js 改为 main.ts</strong> </span>即可</span></p>
<p><span style="font-size: 14px"><strong>如果是 <span style="color: rgba(0, 0, 255, 1)">Vite</span> 创建的项目</strong>,直接修改根目录下的 index.html 文件,将 <script> 标签的 src 地址改为 "/src/main.ts"</span></p>
<p><span style="font-size: 14px"><strong>如果是<span style="color: rgba(0, 0, 255, 1)"> Vue CLI</span> 创建的普通项目</strong>,只需要安装 <span class="cnblogs_code">@vue/cli-plugin-typescrip</span> </span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">npm install @vue/cli-plugin-typescript -D</span></pre>
</div>
<p><span style="font-size: 14px">搞定~ 接下来就可以启动项目开始愉悦的编码了~</span></p>
<p><span style="font-size: 14px"> </span></p><br><br>
来源:https://www.cnblogs.com/wisewrong/p/13717287.html
頁:
[1]