<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vue &#8211; Blog of Code</title>
	<atom:link href="https://www.cztcode.com/category/web-build/vision/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.cztcode.com</link>
	<description>模型推理加速与编程实践</description>
	<lastBuildDate>Wed, 04 Jan 2023 10:29:47 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.cztcode.com/wp-content/uploads/2024/02/cropped-logo-32x32.webp</url>
	<title>Vue &#8211; Blog of Code</title>
	<link>https://www.cztcode.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">217219486</site>	<item>
		<title>VUE项目搭建规范</title>
		<link>https://www.cztcode.com/2023/4275/</link>
					<comments>https://www.cztcode.com/2023/4275/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Wed, 04 Jan 2023 10:29:47 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=4275</guid>

					<description><![CDATA[转自coderwhy，写项目按照这个来啦！]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>
<p class="wp-block-paragraph">转自：coderwhy，写项目按照这个来啦！</p>



<h2 class="wp-block-heading">一. 代码规范</h2>



<h3 class="wp-block-heading">1.1. 集成editorconfig配置</h3>



<p class="wp-block-paragraph">EditorConfig 有助于为不同 IDE 编辑器上处理同一项目的多个开发人员维护一致的编码风格。</p>



<pre class="wp-block-preformatted">&nbsp;# http://editorconfig.org<br>&nbsp;​<br>&nbsp;root = true<br>&nbsp;​<br>&nbsp;[*] # 表示所有文件适用<br>&nbsp;charset = utf-8 # 设置文件字符集为 utf-8<br>&nbsp;indent_style = space # 缩进风格（tab | space）<br>&nbsp;indent_size = 2 # 缩进大小<br>&nbsp;end_of_line = lf # 控制换行类型(lf | cr | crlf)<br>&nbsp;trim_trailing_whitespace = true # 去除行首的任意空白字符<br>&nbsp;insert_final_newline = true # 始终在文件末尾插入一个新行<br>&nbsp;​<br>&nbsp;[*.md] # 表示仅 md 文件适用以下规则<br>&nbsp;max_line_length = off<br>&nbsp;trim_trailing_whitespace = false</pre>



<p class="wp-block-paragraph">VSCode需要安装一个插件：EditorConfig for VS Code</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsq2gh989yj30pj05ggmb.jpg" alt="image-20210722215138665"/></figure>



<h3 class="wp-block-heading">1.2. 使用prettier工具</h3>



<p class="wp-block-paragraph">Prettier 是一款强大的代码格式化工具，支持 JavaScript、TypeScript、CSS、SCSS、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown 等语言，基本上前端能用到的文件格式它都可以搞定，是当下最流行的代码格式化工具。</p>



<p class="wp-block-paragraph">1.安装prettier</p>



<pre class="wp-block-preformatted">&nbsp;npm install prettier -D</pre>



<p class="wp-block-paragraph">2.配置.prettierrc文件：</p>



<ul class="wp-block-list">
<li>useTabs：使用tab缩进还是空格缩进，选择false；</li>



<li>tabWidth：tab是空格的情况下，是几个空格，选择2个；</li>



<li>printWidth：当行字符的长度，推荐80，也有人喜欢100或者120；</li>



<li>singleQuote：使用单引号还是双引号，选择true，使用单引号；</li>



<li>trailingComma：在多行输入的尾逗号是否添加，设置为 <code>none</code>；</li>



<li>semi：语句末尾是否要加分号，默认值true，选择false表示不加；</li>
</ul>



<pre class="wp-block-preformatted">&nbsp;{<br>&nbsp; &nbsp;"useTabs": false,<br>&nbsp; &nbsp;"tabWidth": 2,<br>&nbsp; &nbsp;"printWidth": 80,<br>&nbsp; &nbsp;"singleQuote": true,<br>&nbsp; &nbsp;"trailingComma": "none",<br>&nbsp; &nbsp;"semi": false<br>&nbsp;}</pre>



<p class="wp-block-paragraph">3.创建.prettierignore忽略文件</p>



<pre class="wp-block-preformatted">&nbsp;/dist/*<br>&nbsp;.local<br>&nbsp;.output.js<br>&nbsp;/node_modules/**<br>&nbsp;​<br>&nbsp;**/*.svg<br>&nbsp;**/*.sh<br>&nbsp;​<br>&nbsp;/public/*</pre>



<p class="wp-block-paragraph">4.VSCode需要安装prettier的插件</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsq2acx21rj30ow057mxp.jpg" alt="image-20210722214543454"/></figure>



<p class="wp-block-paragraph">5.测试prettier是否生效</p>



<ul class="wp-block-list">
<li>测试一：在代码中保存代码；</li>



<li>测试二：配置一次性修改的命令；</li>
</ul>



<p class="wp-block-paragraph">在package.json中配置一个scripts：</p>



<pre class="wp-block-preformatted">&nbsp; &nbsp; &nbsp;"prettier": "prettier --write ."</pre>



<h3 class="wp-block-heading">1.3. 使用ESLint检测</h3>



<p class="wp-block-paragraph">1.在前面创建项目的时候，我们就选择了ESLint，所以Vue会默认帮助我们配置需要的ESLint环境。</p>



<p class="wp-block-paragraph">2.VSCode需要安装ESLint插件：</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsq2oq26odj30pw05faaq.jpg" alt="image-20210722215933360"/></figure>



<p class="wp-block-paragraph">3.解决eslint和prettier冲突的问题：</p>



<p class="wp-block-paragraph">安装插件：（vue在创建项目时，如果选择prettier，那么这两个插件会自动安装）</p>



<pre class="wp-block-preformatted">&nbsp;npm i eslint-plugin-prettier eslint-config-prettier -D</pre>



<p class="wp-block-paragraph">添加prettier插件：</p>



<pre class="wp-block-code"><code>&nbsp; &nbsp;extends: &#91;<br>&nbsp; &nbsp; &nbsp;"plugin:vue/vue3-essential",<br>&nbsp; &nbsp; &nbsp;"eslint:recommended",<br>&nbsp; &nbsp; &nbsp;"@vue/typescript/recommended",<br>&nbsp; &nbsp; &nbsp;"@vue/prettier",<br>&nbsp; &nbsp; &nbsp;"@vue/prettier/@typescript-eslint",<br>&nbsp; &nbsp; &nbsp;'plugin:prettier/recommended'<br>&nbsp;  ],</code></pre>



<ol class="wp-block-list" start="4">
<li>添加忽略规则.eslintrc.js</li>
</ol>



<pre class="wp-block-code"><code>&nbsp;module.exports = {<br>&nbsp; &nbsp;root: true,<br>&nbsp; &nbsp;env: {<br>&nbsp; &nbsp; &nbsp;node: true,<br>&nbsp;  },<br>&nbsp; &nbsp;extends: &#91;<br>&nbsp; &nbsp; &nbsp;"plugin:vue/vue3-essential",<br>&nbsp; &nbsp; &nbsp;"eslint:recommended",<br>&nbsp; &nbsp; &nbsp;"@vue/typescript/recommended",<br>&nbsp; &nbsp; &nbsp;"plugin:prettier/recommended",<br>&nbsp;  ],<br>&nbsp; &nbsp;parserOptions: {<br>&nbsp; &nbsp; &nbsp;ecmaVersion: 2020,<br>&nbsp;  },<br>&nbsp; &nbsp;rules: {<br>&nbsp; &nbsp; &nbsp;"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",<br>&nbsp; &nbsp; &nbsp;"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",<br>&nbsp; &nbsp; &nbsp;"vue/multi-word-component-names": "off", //关闭组件名必须为多个单词<br>&nbsp;  },<br>&nbsp;};<br>&nbsp;​</code></pre>



<h3 class="wp-block-heading">1.4. git Husky和eslint</h3>



<p class="wp-block-paragraph">虽然我们已经要求项目使用eslint了，但是不能保证组员提交代码之前都将eslint中的问题解决掉了：</p>



<ul class="wp-block-list">
<li>也就是我们希望保证代码仓库中的代码都是符合eslint规范的；</li>



<li>那么我们需要在组员执行 <code>git commit</code> 命令的时候对其进行校验，如果不符合eslint规范，那么自动通过规范进行修复；</li>
</ul>



<p class="wp-block-paragraph">那么如何做到这一点呢？可以通过Husky工具：</p>



<ul class="wp-block-list">
<li>husky是一个git hook工具，可以帮助我们触发git提交的各个阶段：pre-commit、commit-msg、pre-push</li>
</ul>



<p class="wp-block-paragraph">如何使用husky呢？</p>



<p class="wp-block-paragraph">这里我们可以使用自动配置命令：</p>



<pre class="wp-block-preformatted">&nbsp;npx husky-init &amp;&amp; npm install</pre>



<p class="wp-block-paragraph">这里会做三件事：</p>



<p class="wp-block-paragraph">1.安装husky相关的依赖：</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqq0o5jxmj30bb04qwen.jpg" alt="image-20210723112648927"/></figure>



<p class="wp-block-paragraph">2.在项目目录下创建 <code>.husky</code> 文件夹：</p>



<pre class="wp-block-preformatted">&nbsp;npx huksy install</pre>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqq16zo75j307703mt8m.jpg" alt="image-20210723112719634"/></figure>



<p class="wp-block-paragraph">3.在package.json中添加一个脚本：</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqq26phpxj30dj06fgm3.jpg" alt="image-20210723112817691"/></figure>



<p class="wp-block-paragraph">接下来，我们需要去完成一个操作：在进行commit时，执行lint脚本：</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqq3hn229j30nf04z74q.jpg" alt="image-20210723112932943"/></figure>



<p class="wp-block-paragraph">这个时候我们执行git commit的时候会自动对代码进行lint校验。</p>



<h3 class="wp-block-heading">1.5. git commit规范</h3>



<h4 class="wp-block-heading">1.5.1. 代码提交风格</h4>



<p class="wp-block-paragraph">通常我们的git commit会按照统一的风格来提交，这样可以快速定位每次提交的内容，方便之后对版本进行控制。</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqw17gaqjj30to0cj3zp.jpg" alt=""/></figure>



<p class="wp-block-paragraph">但是如果每次手动来编写这些是比较麻烦的事情，我们可以使用一个工具：Commitizen</p>



<ul class="wp-block-list">
<li>Commitizen 是一个帮助我们编写规范 commit message 的工具；</li>
</ul>



<p class="wp-block-paragraph">1.安装Commitizen</p>



<pre class="wp-block-preformatted">&nbsp;npm install commitizen -D</pre>



<p class="wp-block-paragraph">2.安装cz-conventional-changelog，并且初始化cz-conventional-changelog：</p>



<pre class="wp-block-preformatted">&nbsp;npx commitizen init cz-conventional-changelog --save-dev --save-exact</pre>



<p class="wp-block-paragraph">这个命令会帮助我们安装cz-conventional-changelog：</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqvz2odi4j30ek00zmx2.jpg" alt="image-20210723145249096"/></figure>



<p class="wp-block-paragraph">并且在package.json中进行配置：</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqvzftay5j30iu04k74d.jpg" alt=""/></figure>



<p class="wp-block-paragraph">这个时候我们提交代码需要使用 <code>npx cz</code>：</p>



<ul class="wp-block-list">
<li>第一步是选择type，本次更新的类型</li>
</ul>



<figure class="wp-block-table"><table><thead><tr><th>Type</th><th>作用</th></tr></thead><tbody><tr><td>feat</td><td>新增特性 (feature)</td></tr><tr><td>fix</td><td>修复 Bug(bug fix)</td></tr><tr><td>docs</td><td>修改文档 (documentation)</td></tr><tr><td>style</td><td>代码格式修改(white-space, formatting, missing semi colons, etc)</td></tr><tr><td>refactor</td><td>代码重构(refactor)</td></tr><tr><td>perf</td><td>改善性能(A code change that improves performance)</td></tr><tr><td>test</td><td>测试(when adding missing tests)</td></tr><tr><td>build</td><td>变更项目构建或外部依赖（例如 scopes: webpack、gulp、npm 等）</td></tr><tr><td>ci</td><td>更改持续集成软件的配置文件和 package 中的 scripts 命令，例如 scopes: Travis, Circle 等</td></tr><tr><td>chore</td><td>变更构建流程或辅助工具(比如更改测试环境)</td></tr><tr><td>revert</td><td>代码回退</td></tr></tbody></table></figure>



<ul class="wp-block-list">
<li>第二步选择本次修改的范围（作用域）</li>
</ul>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqw8ca15oj30r600wmx4.jpg" alt="image-20210723150147510"/></figure>



<ul class="wp-block-list">
<li>第三步选择提交的信息</li>
</ul>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqw8mq3zlj60ni01hmx402.jpg" alt="image-20210723150204780"/></figure>



<ul class="wp-block-list">
<li>第四步提交详细的描述信息</li>
</ul>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqw8y05bjj30kt01fjrb.jpg" alt="image-20210723150223287"/></figure>



<ul class="wp-block-list">
<li>第五步是否是一次重大的更改</li>
</ul>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqw9z5vbij30bm00q744.jpg" alt="image-20210723150322122"/></figure>



<ul class="wp-block-list">
<li>第六步是否影响某个open issue</li>
</ul>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqwar8xp1j30fq00ya9x.jpg" alt="image-20210723150407822"/></figure>



<p class="wp-block-paragraph">我们也可以在scripts中构建一个命令来执行 cz：</p>



<figure class="wp-block-image"><img decoding="async" src="https://markdown.cztcode.com/008i3skNgy1gsqwc4gtkxj30e207174t.jpg" alt="image-20210723150526211"/></figure>



<h4 class="wp-block-heading">1.5.2. 代码提交验证</h4>



<p class="wp-block-paragraph">如果我们按照cz来规范了提交风格，但是依然有同事通过 <code>git commit</code> 按照不规范的格式提交应该怎么办呢？</p>



<ul class="wp-block-list">
<li>我们可以通过commitlint来限制提交；</li>
</ul>



<p class="wp-block-paragraph">1.安装 @commitlint/config-conventional 和 @commitlint/cli</p>



<pre class="wp-block-preformatted">&nbsp;npm i @commitlint/config-conventional @commitlint/cli -D</pre>



<p class="wp-block-paragraph">2.在根目录创建commitlint.config.js文件，配置commitlint</p>



<pre class="wp-block-preformatted">&nbsp;module.exports = {<br>&nbsp; &nbsp;extends: ['@commitlint/config-conventional']<br>&nbsp;}</pre>



<p class="wp-block-paragraph">3.使用husky生成commit-msg文件，验证提交信息：</p>



<pre class="wp-block-preformatted">&nbsp;npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"</pre>



<h2 class="wp-block-heading">二. 第三方库集成</h2>



<h3 class="wp-block-heading">2.1. vue.config.js配置</h3>



<p class="wp-block-paragraph">vue.config.js有三种配置方式：</p>



<ul class="wp-block-list">
<li>方式一：直接通过CLI提供给我们的选项来配置：
<ul class="wp-block-list">
<li>比如publicPath：配置应用程序部署的子目录（默认是 <code>/</code>，相当于部署在 <code>https://www.my-app.com/</code>）；</li>



<li>比如outputDir：修改输出的文件夹；</li>
</ul>
</li>



<li>方式二：通过configureWebpack修改webpack的配置：
<ul class="wp-block-list">
<li>可以是一个对象，直接会被合并；</li>



<li>可以是一个函数，会接收一个config，可以通过config来修改配置；</li>
</ul>
</li>



<li>方式三：通过chainWebpack修改webpack的配置：
<ul class="wp-block-list">
<li>是一个函数，会接收一个基于 <a href="https://github.com/mozilla-neutrino/webpack-chain" target="_blank" rel="noopener">webpack-chain</a> 的config对象，可以对配置进行修改；</li>
</ul>
</li>
</ul>



<pre class="wp-block-code"><code>&nbsp;const path = require('path')<br>&nbsp;​<br>&nbsp;module.exports = {<br>&nbsp; &nbsp;outputDir: './build',<br>&nbsp; &nbsp;// configureWebpack: {<br>&nbsp; &nbsp;// &nbsp; resolve: {<br>&nbsp; &nbsp;// &nbsp; &nbsp; alias: {<br>&nbsp; &nbsp;// &nbsp; &nbsp; &nbsp; views: '@/views'<br>&nbsp; &nbsp;// &nbsp; &nbsp; }<br>&nbsp; &nbsp;// &nbsp; }<br>&nbsp; &nbsp;// }<br>&nbsp; &nbsp;// configureWebpack: (config) =&gt; {<br>&nbsp; &nbsp;// &nbsp; config.resolve.alias = {<br>&nbsp; &nbsp;// &nbsp; &nbsp; '@': path.resolve(__dirname, 'src'),<br>&nbsp; &nbsp;// &nbsp; &nbsp; views: '@/views'<br>&nbsp; &nbsp;// &nbsp; }<br>&nbsp; &nbsp;// },<br>&nbsp; &nbsp;chainWebpack: (config) =&gt; {<br>&nbsp; &nbsp; &nbsp;config.resolve.alias.set('@', path.resolve(__dirname, 'src')).set('views', '@/views')<br>&nbsp;  }<br>&nbsp;}</code></pre>



<h3 class="wp-block-heading">2.2. vue-router集成</h3>



<p class="wp-block-paragraph">安装vue-router的最新版本：</p>



<pre class="wp-block-preformatted">&nbsp;npm install vue-router@next</pre>



<p class="wp-block-paragraph">创建router对象：</p>



<pre class="wp-block-code"><code>&nbsp;import { createRouter, createWebHashHistory } from 'vue-router'<br>&nbsp;import { RouteRecordRaw } from 'vue-router'<br>&nbsp;​<br>&nbsp;const routes: RouteRecordRaw&#91;] = &#91;<br>&nbsp;  {<br>&nbsp; &nbsp; &nbsp;path: '/',<br>&nbsp; &nbsp; &nbsp;redirect: '/main'<br>&nbsp;  },<br>&nbsp;  {<br>&nbsp; &nbsp; &nbsp;path: '/main',<br>&nbsp; &nbsp; &nbsp;component: () =&gt; import('../views/main/main.vue')<br>&nbsp;  },<br>&nbsp;  {<br>&nbsp; &nbsp; &nbsp;path: '/login',<br>&nbsp; &nbsp; &nbsp;component: () =&gt; import('../views/login/login.vue')<br>&nbsp;  }<br>&nbsp;]<br>&nbsp;​<br>&nbsp;const router = createRouter({<br>&nbsp; &nbsp;routes,<br>&nbsp; &nbsp;history: createWebHashHistory()<br>&nbsp;})<br>&nbsp;​<br>&nbsp;export default router</code></pre>



<p class="wp-block-paragraph">安装router：</p>



<pre class="wp-block-code"><code>&nbsp;import router from './router'<br>&nbsp;​<br>&nbsp;createApp(App).use(router).mount('#app')</code></pre>



<p class="wp-block-paragraph">在App.vue中配置跳转：</p>



<pre class="wp-block-code"><code>&nbsp;&lt;template&gt;<br>&nbsp; &nbsp;&lt;div id="app"&gt;<br>&nbsp; &nbsp; &nbsp;&lt;router-link to="/login"&gt;登录&lt;/router-link&gt;<br>&nbsp; &nbsp; &nbsp;&lt;router-link to="/main"&gt;首页&lt;/router-link&gt;<br>&nbsp; &nbsp; &nbsp;&lt;router-view&gt;&lt;/router-view&gt;<br>&nbsp; &nbsp;&lt;/div&gt;<br>&nbsp;&lt;/template&gt;</code></pre>



<h3 class="wp-block-heading">2.3. vuex集成</h3>



<p class="wp-block-paragraph">安装vuex：</p>



<pre class="wp-block-preformatted">&nbsp;npm install vuex@next</pre>



<p class="wp-block-paragraph">创建store对象：</p>



<pre class="wp-block-code"><code>&nbsp;import { createStore } from 'vuex'<br>&nbsp;​<br>&nbsp;const store = createStore({<br>&nbsp; &nbsp;state() {<br>&nbsp; &nbsp; &nbsp;return {<br>&nbsp; &nbsp; &nbsp; &nbsp;name: 'coderwhy'<br>&nbsp; &nbsp;  }<br>&nbsp;  }<br>&nbsp;})<br>&nbsp;​<br>&nbsp;export default store</code></pre>



<p class="wp-block-paragraph">安装store：</p>



<pre class="wp-block-preformatted">&nbsp;createApp(App).use(router).use(store).mount('#app')</pre>



<p class="wp-block-paragraph">在App.vue中使用：</p>



<pre class="wp-block-preformatted">&nbsp;&lt;h2&gt;{{ $store.state.name }}&lt;/h2&gt;</pre>



<h3 class="wp-block-heading">2.4. element-plus集成</h3>



<p class="wp-block-paragraph">Element Plus，一套为开发者、设计师和产品经理准备的基于 Vue 3.0 的桌面端组件库：</p>



<ul class="wp-block-list">
<li>相信很多同学在Vue2中都使用过element-ui，而element-plus正是element-ui针对于vue3开发的一个UI组件库；</li>



<li>它的使用方式和很多其他的组件库是一样的，所以学会element-plus，其他类似于ant-design-vue、NaiveUI、VantUI都是差不多的；</li>
</ul>



<p class="wp-block-paragraph">安装element-plus</p>



<pre class="wp-block-preformatted">&nbsp;npm install element-plus</pre>



<h4 class="wp-block-heading">2.4.1. 全局引入</h4>



<p class="wp-block-paragraph">一种引入element-plus的方式是全局引入，代表的含义是所有的组件和插件都会被自动注册：</p>



<pre class="wp-block-code"><code>&nbsp;import ElementPlus from 'element-plus'<br>&nbsp;import 'element-plus/lib/theme-chalk/index.css'<br>&nbsp;​<br>&nbsp;import router from './router'<br>&nbsp;import store from './store'<br>&nbsp;​<br>&nbsp;createApp(App).use(router).use(store).use(ElementPlus).mount('#app')</code></pre>



<h4 class="wp-block-heading">2.4.2. 局部引入</h4>



<p class="wp-block-paragraph">也就是在开发中用到某个组件对某个组件进行引入：</p>



<pre class="wp-block-code"><code>&nbsp;&lt;template&gt;<br>&nbsp; &nbsp;&lt;div id="app"&gt;<br>&nbsp; &nbsp; &nbsp;&lt;router-link to="/login"&gt;登录&lt;/router-link&gt;<br>&nbsp; &nbsp; &nbsp;&lt;router-link to="/main"&gt;首页&lt;/router-link&gt;<br>&nbsp; &nbsp; &nbsp;&lt;router-view&gt;&lt;/router-view&gt;<br>&nbsp;​<br>&nbsp; &nbsp; &nbsp;&lt;h2&gt;{{ $store.state.name }}&lt;/h2&gt;<br>&nbsp;​<br>&nbsp; &nbsp; &nbsp;&lt;el-button&gt;默认按钮&lt;/el-button&gt;<br>&nbsp; &nbsp; &nbsp;&lt;el-button type="primary"&gt;主要按钮&lt;/el-button&gt;<br>&nbsp; &nbsp; &nbsp;&lt;el-button type="success"&gt;成功按钮&lt;/el-button&gt;<br>&nbsp; &nbsp; &nbsp;&lt;el-button type="info"&gt;信息按钮&lt;/el-button&gt;<br>&nbsp; &nbsp; &nbsp;&lt;el-button type="warning"&gt;警告按钮&lt;/el-button&gt;<br>&nbsp; &nbsp; &nbsp;&lt;el-button type="danger"&gt;危险按钮&lt;/el-button&gt;<br>&nbsp; &nbsp;&lt;/div&gt;<br>&nbsp;&lt;/template&gt;<br>&nbsp;​<br>&nbsp;&lt;script lang="ts"&gt;<br>&nbsp;import { defineComponent } from 'vue'<br>&nbsp;​<br>&nbsp;import { ElButton } from 'element-plus'<br>&nbsp;​<br>&nbsp;export default defineComponent({<br>&nbsp; &nbsp;name: 'App',<br>&nbsp; &nbsp;components: {<br>&nbsp; &nbsp; &nbsp;ElButton<br>&nbsp;  }<br>&nbsp;})<br>&nbsp;&lt;/script&gt;<br>&nbsp;​<br>&nbsp;&lt;style lang="less"&gt;<br>&nbsp;&lt;/style&gt;</code></pre>



<p class="wp-block-paragraph">但是我们会发现是没有对应的样式的，引入样式有两种方式：</p>



<ul class="wp-block-list">
<li>全局引用样式（像之前做的那样）；</li>



<li>局部引用样式（通过babel的插件）；</li>
</ul>



<p class="wp-block-paragraph">1.安装babel的插件：</p>



<pre class="wp-block-preformatted">&nbsp;npm install babel-plugin-import -D</pre>



<p class="wp-block-paragraph">2.配置babel.config.js</p>



<pre class="wp-block-code"><code>&nbsp;module.exports = {<br>&nbsp; &nbsp;plugins: &#91;<br>&nbsp; &nbsp;  &#91;<br>&nbsp; &nbsp; &nbsp; &nbsp;'import',<br>&nbsp; &nbsp; &nbsp;  {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libraryName: 'element-plus',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;customStyleName: (name) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return `element-plus/lib/theme-chalk/${name}.css`<br>&nbsp; &nbsp; &nbsp; &nbsp;  }<br>&nbsp; &nbsp; &nbsp;  }<br>&nbsp; &nbsp;  ]<br>&nbsp;  ],<br>&nbsp; &nbsp;presets: &#91;'@vue/cli-plugin-babel/preset']<br>&nbsp;}</code></pre>



<p class="wp-block-paragraph">但是这里依然有个弊端：</p>



<ul class="wp-block-list">
<li>这些组件我们在多个页面或者组件中使用的时候，都需要导入并且在components中进行注册；</li>



<li>所以我们可以将它们在全局注册一次；</li>
</ul>



<pre class="wp-block-code"><code>&nbsp;import {<br>&nbsp; &nbsp;ElButton,<br>&nbsp; &nbsp;ElTable,<br>&nbsp; &nbsp;ElAlert,<br>&nbsp; &nbsp;ElAside,<br>&nbsp; &nbsp;ElAutocomplete,<br>&nbsp; &nbsp;ElAvatar,<br>&nbsp; &nbsp;ElBacktop,<br>&nbsp; &nbsp;ElBadge,<br>&nbsp;} from 'element-plus'<br>&nbsp;​<br>&nbsp;const app = createApp(App)<br>&nbsp;​<br>&nbsp;const components = &#91;<br>&nbsp; &nbsp;ElButton,<br>&nbsp; &nbsp;ElTable,<br>&nbsp; &nbsp;ElAlert,<br>&nbsp; &nbsp;ElAside,<br>&nbsp; &nbsp;ElAutocomplete,<br>&nbsp; &nbsp;ElAvatar,<br>&nbsp; &nbsp;ElBacktop,<br>&nbsp; &nbsp;ElBadge<br>&nbsp;]<br>&nbsp;​<br>&nbsp;for (const cpn of components) {<br>&nbsp; &nbsp;app.component(cpn.name, cpn)<br>&nbsp;}</code></pre>



<h3 class="wp-block-heading">2.5. axios集成</h3>



<p class="wp-block-paragraph">安装axios：</p>



<pre class="wp-block-preformatted">&nbsp;npm install axios</pre>



<p class="wp-block-paragraph">封装axios：</p>



<pre class="wp-block-code"><code>&nbsp;import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'<br>&nbsp;import { Result } from './types'<br>&nbsp;import { useUserStore } from '/@/store/modules/user'<br>&nbsp;​<br>&nbsp;class HYRequest {<br>&nbsp; &nbsp;private instance: AxiosInstance<br>&nbsp;​<br>&nbsp; &nbsp;private readonly options: AxiosRequestConfig<br>&nbsp;​<br>&nbsp; &nbsp;constructor(options: AxiosRequestConfig) {<br>&nbsp; &nbsp; &nbsp;this.options = options<br>&nbsp; &nbsp; &nbsp;this.instance = axios.create(options)<br>&nbsp;​<br>&nbsp; &nbsp; &nbsp;this.instance.interceptors.request.use(<br>&nbsp; &nbsp; &nbsp;  (config) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const token = useUserStore().getToken<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (token) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;config.headers.Authorization = `Bearer ${token}`<br>&nbsp; &nbsp; &nbsp; &nbsp;  }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return config<br>&nbsp; &nbsp; &nbsp;  },<br>&nbsp; &nbsp; &nbsp;  (err) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return err<br>&nbsp; &nbsp; &nbsp;  }<br>&nbsp; &nbsp;  )<br>&nbsp;​<br>&nbsp; &nbsp; &nbsp;this.instance.interceptors.response.use(<br>&nbsp; &nbsp; &nbsp;  (res) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 拦截响应的数据<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (res.data.code === 0) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return res.data.data<br>&nbsp; &nbsp; &nbsp; &nbsp;  }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return res.data<br>&nbsp; &nbsp; &nbsp;  },<br>&nbsp; &nbsp; &nbsp;  (err) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return err<br>&nbsp; &nbsp; &nbsp;  }<br>&nbsp; &nbsp;  )<br>&nbsp;  }<br>&nbsp;​<br>&nbsp; &nbsp;request&lt;T = any&gt;(config: AxiosRequestConfig): Promise&lt;T&gt; {<br>&nbsp; &nbsp; &nbsp;return new Promise((resolve, reject) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp;this.instance<br>&nbsp; &nbsp; &nbsp; &nbsp;  .request&lt;any, AxiosResponse&lt;Result&lt;T&gt;&gt;&gt;(config)<br>&nbsp; &nbsp; &nbsp; &nbsp;  .then((res) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;resolve((res as unknown) as Promise&lt;T&gt;)<br>&nbsp; &nbsp; &nbsp; &nbsp;  })<br>&nbsp; &nbsp; &nbsp; &nbsp;  .catch((err) =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;reject(err)<br>&nbsp; &nbsp; &nbsp; &nbsp;  })<br>&nbsp; &nbsp;  })<br>&nbsp;  }<br>&nbsp;​<br>&nbsp; &nbsp;get&lt;T = any&gt;(config: AxiosRequestConfig): Promise&lt;T&gt; {<br>&nbsp; &nbsp; &nbsp;return this.request({ ...config, method: 'GET' })<br>&nbsp;  }<br>&nbsp;​<br>&nbsp; &nbsp;post&lt;T = any&gt;(config: AxiosRequestConfig): Promise&lt;T&gt; {<br>&nbsp; &nbsp; &nbsp;return this.request({ ...config, method: 'POST' })<br>&nbsp;  }<br>&nbsp;​<br>&nbsp; &nbsp;patch&lt;T = any&gt;(config: AxiosRequestConfig): Promise&lt;T&gt; {<br>&nbsp; &nbsp; &nbsp;return this.request({ ...config, method: 'PATCH' })<br>&nbsp;  }<br>&nbsp;​<br>&nbsp; &nbsp;delete&lt;T = any&gt;(config: AxiosRequestConfig): Promise&lt;T&gt; {<br>&nbsp; &nbsp; &nbsp;return this.request({ ...config, method: 'DELETE' })<br>&nbsp;  }<br>&nbsp;}<br>&nbsp;​<br>&nbsp;export default HYRequest</code></pre>



<h3 class="wp-block-heading">2.6. VSCode配置</h3>



<pre class="wp-block-code"><code>&nbsp;{<br>&nbsp; &nbsp;"workbench.iconTheme": "vscode-great-icons",<br>&nbsp; &nbsp;"editor.fontSize": 17,<br>&nbsp; &nbsp;"eslint.migration.2_x": "off",<br>&nbsp; &nbsp;"&#91;javascript]": {<br>&nbsp; &nbsp; &nbsp;"editor.defaultFormatter": "dbaeumer.vscode-eslint"<br>&nbsp;  },<br>&nbsp; &nbsp;"files.autoSave": "afterDelay",<br>&nbsp; &nbsp;"editor.tabSize": 2,<br>&nbsp; &nbsp;"terminal.integrated.fontSize": 16,<br>&nbsp; &nbsp;"editor.renderWhitespace": "all",<br>&nbsp; &nbsp;"editor.quickSuggestions": {<br>&nbsp; &nbsp; &nbsp;"strings": true<br>&nbsp;  },<br>&nbsp; &nbsp;"dhttps://markdown.cztcode.com/008i3skNgy1gsqwar8xp1j30fq00ya9x.jpgebug.console.fontSize": 15,<br>&nbsp; &nbsp;"window.zoomLevel": 1,<br>&nbsp; &nbsp;"emmet.includeLanguages": {<br>&nbsp; &nbsp; &nbsp;"javascript": "javascriptreact"<br>&nbsp;  },<br>&nbsp; &nbsp;"explorer.confirmDragAndDrop": false,<br>&nbsp; &nbsp;"workbench.tree.indent": 16,<br>&nbsp; &nbsp;"javascript.updateImportsOnFileMove.enabled": "always",<br>&nbsp; &nbsp;"editor.wordWrap": "on",<br>&nbsp; &nbsp;"path-intellisense.mappings": {<br>&nbsp; &nbsp; &nbsp;"@": "${workspaceRoot}/src"<br>&nbsp;  },<br>&nbsp; &nbsp;"hediet.vscode-drawio.local-storage": "eyIuZHJhd2lvLWNvbmZpZyI6IntcImxhbmd1YWdlXCI6XCJcIixcImN1c3RvbUZvbnRzXCI6W10sXCJsaWJyYXJpZXNcIjpcImdlbmVyYWw7YmFzaWM7YXJyb3dzMjtmbG93Y2hhcnQ7ZXI7c2l0ZW1hcDt1bWw7YnBtbjt3ZWJpY29uc1wiLFwiY3VzdG9tTGlicmFyaWVzXCI6W1wiTC5zY3JhdGNocGFkXCJdLFwicGx1Z2luc1wiOltdLFwicmVjZW50Q29sb3JzXCI6W1wiRkYwMDAwXCIsXCIwMENDNjZcIixcIm5vbmVcIixcIkNDRTVGRlwiLFwiNTI1MjUyXCIsXCJGRjMzMzNcIixcIjMzMzMzM1wiLFwiMzMwMDAwXCIsXCIwMENDQ0NcIixcIkZGNjZCM1wiLFwiRkZGRkZGMDBcIl0sXCJmb3JtYXRXaWR0aFwiOjI0MCxcImNyZWF0ZVRhcmdldFwiOmZhbHNlLFwicGFnZUZvcm1hdFwiOntcInhcIjowLFwieVwiOjAsXCJ3aWR0aFwiOjExNjksXCJoZWlnaHRcIjoxNjU0fSxcInNlYXJjaFwiOnRydWUsXCJzaG93U3RhcnRTY3JlZW5cIjp0cnVlLFwiZ3JpZENvbG9yXCI6XCIjZDBkMGQwXCIsXCJkYXJrR3JpZENvbG9yXCI6XCIjNmU2ZTZlXCIsXCJhdXRvc2F2ZVwiOnRydWUsXCJyZXNpemVJbWFnZXNcIjpudWxsLFwib3BlbkNvdW50ZXJcIjowLFwidmVyc2lvblwiOjE4LFwidW5pdFwiOjEsXCJpc1J1bGVyT25cIjpmYWxzZSxcInVpXCI6XCJcIn0ifQ==",<br>&nbsp; &nbsp;"hediet.vscode-drawio.theme": "Kennedy",<br>&nbsp; &nbsp;"editor.fontFamily": "Source Code Pro, 'Courier New', monospace",<br>&nbsp; &nbsp;"editor.smoothScrolling": true,<br>&nbsp; &nbsp;"editor.formatOnSave": true,<br>&nbsp; &nbsp;"editor.defaultFormatter": "esbenp.prettier-vscode",<br>&nbsp; &nbsp;"workbench.colorTheme": "Atom One Dark",<br>&nbsp; &nbsp;"vetur.completion.autoImport": false,<br>&nbsp; &nbsp;"security.workspace.trust.untrustedFiles": "open",<br>&nbsp; &nbsp;"eslint.lintTask.enable": true,<br>&nbsp; &nbsp;"eslint.alwaysShowStatus": true,<br>&nbsp; &nbsp;"editor.codeActionsOnSave": {<br>&nbsp; &nbsp; &nbsp;"source.fixAll.eslint": true<br>&nbsp;  }<br>&nbsp;}</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2023/4275/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4275</post-id>	</item>
		<item>
		<title>浅拷贝与深拷贝</title>
		<link>https://www.cztcode.com/2022/4133/</link>
					<comments>https://www.cztcode.com/2022/4133/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Sun, 30 Jan 2022 02:28:57 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=4133</guid>

					<description><![CDATA[浅拷贝 定义 浅拷贝是按位拷贝对象，它会创建一个新对象，这个对象有着原始对象属性值的一份精确拷贝。 如果属性是基本类型，拷贝的就是基本类型的值；如果属性是内存地址（引用类型），拷贝的就是内存地址，因此如果其中一个对象改变了这个地址，就会影响到另一个对象。 Object.assign方法实行的是浅拷贝，而不是深拷贝。也就是说，如果源对象某个属性的值是对象，那么目标对象拷贝得到的是这个对象的引用。 输 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>
<h1 class="wp-block-heading">浅拷贝</h1>



<h2 class="wp-block-heading">定义</h2>



<p class="is-style-iw-2em wp-block-paragraph"><strong>浅拷贝</strong>是按位<strong>拷贝</strong>对象，它会创建一个新对象，这个对象有着原始对象属性值的一份精确<strong>拷贝</strong>。 如果属性是基本类型，<strong>拷贝</strong>的就是基本类型的值；如果属性是内存地址（引用类型），<strong>拷贝</strong>的就是内存地址，因此如果其中一个对象改变了这个地址，就会影响到另一个对象。</p>



<p class="is-style-iw-2em wp-block-paragraph"><code>Object.assign</code>方法实行的是浅拷贝，而不是深拷贝。也就是说，如果源对象某个属性的值是对象，那么目标对象拷贝得到的是这个对象的引用。</p>



<pre class="wp-block-code"><code>    const info={name:"why"} //属性的value是值，所以只是复制值
    const obj=Object.assign({},info)
    obj.name="he"
    console.log(info)

    const obj1 = {a: {b: 1}}//属性的value是对象，复制的是引用
    const obj2 = Object.assign({}, obj1)

    obj1.a.b = 2
    obj2.a.b // 2
    console.log(obj2)
</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">输出结果</p>



<pre class="wp-block-code"><code>{ name: 'why' }
{ a: { b: 2 } }
</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">这里也可以用es6语法展开运算符进行浅拷贝</p>



<div class="wp-block-jetpack-markdown"><pre><code>
    const obj1 = {a: {b: 1}}//属性的value是对象
    const obj2 = {...obj1}

    obj1.a.b = 2
    obj2.a.b // 2
    console.log(obj2.a===obj1.a)

</code></pre>
</div>



<p class="is-style-iw-2em wp-block-paragraph">比较一下，结果为true，对象确实是同一个</p>



<h1 class="wp-block-heading">深拷贝</h1>



<p class="is-style-iw-2em wp-block-paragraph">深拷贝会另外创造一个一模一样的对象，新对象跟原对象不共享内存，修改新对象不会改到原对象</p>



<p class="is-style-iw-2em wp-block-paragraph">利用lodash库实现深拷贝</p>



<p class="is-style-iw-2em wp-block-paragraph">Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库</p>



<pre class="wp-block-code"><code>const _ = require('lodash');
const obj1 = {
    a: 1,
    b: {f: {g: 1}},
    c: &#91;1, 2, 3]
};
const obj2 = _.cloneDeep(obj1);

console.log(obj1.b.f === obj2.b.f);

</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">结果是false，深拷贝不是同一个对象</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2022/4133/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4133</post-id>	</item>
		<item>
		<title>VUE3之VUEX</title>
		<link>https://www.cztcode.com/2021/4104/</link>
					<comments>https://www.cztcode.com/2021/4104/#comments</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Sun, 05 Sep 2021 15:04:13 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<category><![CDATA[综合]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=4104</guid>

					<description><![CDATA[VUE3之VUEX
vuex的基本使用
state getters mutations actions
辅助函数
modules]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>


<h2 class="wp-block-heading">vuex的基本使用</h2>



<p class="is-style-iw-2em wp-block-paragraph">创建一个store：</p>



<pre class="wp-block-code"><code>import {createStore} from 'vuex'

const store = createStore();

export default store;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在Main.js中使用：</p>



<pre class="wp-block-code"><code>import&nbsp;store&nbsp;from&nbsp;'./store'

createApp(App).use(store).mount('#app')</code></pre>



<h2 class="wp-block-heading">state</h2>



<p class="is-style-iw-2em wp-block-paragraph">在store中定义数据，需要在state属性中：</p>



<pre class="wp-block-code"><code>const store = createStore({
  state(){
    return{
      counter:0
    }
  }
});</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在组件中使用时，需要从$store.state中获取：</p>



<pre class="wp-block-code"><code>&lt;h2&gt;{{$store.state.counter}}&lt;/h2&gt;</code></pre>



<h2 class="wp-block-heading">mutations</h2>



<p class="is-style-iw-2em wp-block-paragraph">在vuex的开发模式中，不推荐直接对数据进行操作，而是应该通过commit来提交一次数据操作。在store中定义mutations属性：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;mutations:{
&nbsp;&nbsp;&nbsp;&nbsp;increment(state){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state.counter++
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;decrement(state){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state.counter--
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在组件中调用store的commit方法，参数是要执行的mutation的方法名：</p>



<pre class="wp-block-code"><code>  methods:{
    increment(){
      this.$store.commit("increment")
    },
    decrement(){
      this.$store.commit("decrement")
    }
  }</code></pre>



<h2 class="wp-block-heading">mutations的一些补充</h2>



<p class="is-style-iw-2em wp-block-paragraph">mutations中的方法的第一个参数是state，可以获取state中的变量，第二个参数是payload，即从外部传入的参数：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;mutations:{
&nbsp;&nbsp;&nbsp;&nbsp;incrementN(state,payload){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state.counter+=payload
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;},</code></pre>



<pre class="wp-block-code"><code>    methods: {
      addTen(){
        this.$store.commit('incrementN',10)
      }
    },</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">另一种提交的风格是，将两个参数合并，即传入一个对象，当中有type来指明提交给某个函数：</p>



<pre class="wp-block-code"><code>this.$store.commit({
&nbsp;&nbsp;type:'incrementN',
&nbsp;&nbsp;incre:10
})</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">另外为了防止将方法名写错，可以使用常量的方式定义方法名：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;const INCREMENT_N = "increment_n";
    mutations:{
&nbsp;&nbsp;&nbsp;&nbsp;&#091;INCREMENT_N](state,payload){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state.counter+=payload
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;},</code></pre>



<h2 class="wp-block-heading">mapState辅助函数</h2>



<p class="is-style-iw-2em wp-block-paragraph">可以通过计算属性来简化获取state中的数据：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;computed:{
&nbsp;&nbsp;&nbsp;&nbsp;sCounter(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;this.$store.state.counter
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">不过vuex为我们提供了一个函数，可以更加快速地获取到state中的变量：</p>



<pre class="wp-block-code"><code>import { mapState } from 'vuex'
  export default {
    computed:{
      sCounter(){
        return this.$store.state.counter
      },
      ...mapState(&#091;"counter","name"])
    }
  }</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">mapState传入的是要获取的state中的变量名数组，返回值是变量的computed对象，所以需要用&#8230;展开；也可以传入一个对象，可以自定义名字：</p>



<pre class="wp-block-code"><code>...mapState({
  sCounter:state=&gt;state.counter,
  name:state=&gt;state.name
})</code></pre>



<p class="is-style-iw-2em wp-block-paragraph"><strong>在composition API中使用</strong></p>



<p class="is-style-iw-2em wp-block-paragraph">vuex提供了一个useStore方法让我们在setup中可以获取到store：</p>



<pre class="wp-block-code"><code>import { useStore } from 'vuex'
import { computed } from 'vue'
  export default {
    setup(props) {
      const store = useStore();

      const sCounter = computed(()=&gt;store.state.counter)

      return {
        sCounter
      }
    }
  }</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">如果要使用mapState，需要进行一些处理：</p>



<pre class="wp-block-code"><code>setup(props) {
      const store = useStore();

      const storeStateFns = mapState(&#091;"counter","name"]);
      const storeState = {};
      Object.keys(storeStateFns).forEach(fnKey =&gt;{
        const fn = storeStateFns&#091;fnKey].bind({$store:store});
        console.log(fnKey);
        storeState&#091;fnKey]=computed(fn);
      })

      return {
        ...storeState 
      }
    }</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">mapState返回的都是函数，在执行时需要用到$store属性，所以需要加上bind。</p>



<p class="is-style-iw-2em wp-block-paragraph">对以上的内容进行封装以便使用：</p>



<pre class="wp-block-code"><code>      const storeStateFns = mapState(&#091;"counter","name"]);
      const storeState = {};
      Object.keys(storeStateFns).forEach(fnKey =&gt;{
        const fn = storeStateFns&#091;fnKey].bind({$store:store});
        console.log(fnKey);
        storeState&#091;fnKey]=computed(fn);
      })</code></pre>



<h2 class="wp-block-heading">getters</h2>



<p class="is-style-iw-2em wp-block-paragraph">一些数据可能需要结果处理之后再进行显示（和computed类似，不用在每一个组件中写计算属性），定义方式如下：</p>



<pre class="wp-block-code"><code>const store = createStore({
  state(){},
  mutations:{},
  getters:{
    totalPrice(state){
      let totalPrice=0;
      for (const book of state.books){
        totalPrice+=book.count*book.price
      }
      return totalPrice;
    }
  }
});</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">使用方式：</p>



<pre class="wp-block-code"><code>&lt;h2&gt;总价值:{{$store.getters.totalPrice}}&lt;/h2&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">getters中定义的函数的第一个参数是state，可以获取state中定义的变量，第二个参数是getters，可以用其调用getters中其它的函数：</p>



<pre class="wp-block-code"><code>  getters:{
    totalPrice(state,getters){
      let totalPrice=0;
      for (const book of state.books){
        totalPrice+=book.count*book.price
      }
      return totalPrice * getters.currentDiscount;
    },
    currentDiscount(state){
      return state.discount*0.9;
    }
  }</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">getter函数的返回值可以是一个值，在使用时就应该如同上面所示：</p>



<pre class="wp-block-code"><code>&lt;h2&gt;总价值:{{$store.getters.totalPrice}}&lt;/h2&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">也可以返回一个函数，返回函数的一个目的是传入我们的自定义参数：</p>



<pre class="wp-block-code"><code>totalPriceForCountN(state,getters){
&nbsp;&nbsp;return&nbsp;function(n){
&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;totalPrice=0;
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(const&nbsp;book&nbsp;of&nbsp;state.books){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(book.count&gt;=n){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;totalPrice+=book.count*book.price
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;totalPrice&nbsp;*&nbsp;getters.currentDiscount;
&nbsp;&nbsp;}
}</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">使用时需要在后面加上小括号表示函数调用：</p>



<pre class="wp-block-code"><code>&lt;h2&gt;总价值:{{$store.getters.totalPriceForCountN(4)}}&lt;/h2&gt;</code></pre>


]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2021/4104/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4104</post-id>	</item>
		<item>
		<title>VUE3之vue-router</title>
		<link>https://www.cztcode.com/2021/4089/</link>
					<comments>https://www.cztcode.com/2021/4089/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Wed, 01 Sep 2021 15:28:42 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=4089</guid>

					<description><![CDATA[VUE3之vue-router
vue-router的基本使用和配置
vue-router知识点补充
路由懒加载
动态路由
NotFound
嵌套路由
编程式导航
router-link的v-slot
动态添加/删除路由
路由导航守卫]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>


<h2 class="wp-block-heading">vue-router的基本使用和配置</h2>



<p class="is-style-iw-2em wp-block-paragraph">首先要有两个组件Home.vue和About.vue，之后将这两个组件注册到路由中：</p>



<pre class="wp-block-code"><code>import Home from '../pages/Home.vue';
import About from '../pages/About.vue';

// 配置映射关系
const routes = &#091;
  {path: '/', component: Home},
  {path: '/home', component: Home},
  {path: '/about', component: About}
];</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">创建一个路由对象，并传入配置：</p>



<pre class="wp-block-code"><code>import {createRouter, createWebHashHistory, createWebHistory} from 'vue-router'
//&nbsp;创建一个路由对象router
const&nbsp;router&nbsp;=&nbsp;createRouter({
&nbsp;&nbsp;routes,
&nbsp;&nbsp;history:&nbsp;createWebHashHistory()
})</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在main.js中使用router：</p>



<pre class="wp-block-code"><code>import&nbsp;{&nbsp;createApp&nbsp;}&nbsp;from&nbsp;'vue'
import&nbsp;router&nbsp;from&nbsp;'./router'
import&nbsp;App&nbsp;from&nbsp;'./App.vue'

const&nbsp;app=createApp(App);
app.use(router);
app.mount('#app');</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">此时路由已经添加成功，需要在app.vue中使用路由组件。</p>



<p class="is-style-iw-2em wp-block-paragraph">router-view是用于显示路由中组件的地方，router-link是一个控制路由路径的a元素，使用如下：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;&lt;div&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-link&nbsp;to="/home"&gt;首页&lt;/router-link&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-link&nbsp;to="/about"&gt;关于&lt;/router-link&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-view&gt;&lt;/router-view&gt;
&nbsp;&nbsp;&lt;/div&gt;</code></pre>



<h2 class="wp-block-heading">vue-router知识点补充</h2>



<p class="is-style-iw-2em wp-block-paragraph">在路由关系中：</p>



<pre class="wp-block-code"><code>const routes = &#091;
  {path: '/', component: Home},
  {path: '/home', component: Home},
  {path: '/about', component: About}
];</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">默认的&#8217;/&#8217;，可以为其指定一个component，也可以重定向到一个页面：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;{path:&nbsp;'/',&nbsp;redirect:&nbsp;'/home'},</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">route还有两个属性：name是为一个route定义一个名字，路由是可以通过这个name跳转的；meta定义了这个路由的内部数据，可以通过route.meta来获取到。</p>



<p class="is-style-iw-2em wp-block-paragraph">对于route-link，默认使用的是history的popstate策略，为其增加replace属性后将使用replacestate策略。</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;&lt;div&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-link&nbsp;to="/home"&nbsp;replace&gt;首页&lt;/router-link&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-link&nbsp;to="/about"&nbsp;replace&gt;关于&lt;/router-link&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-view&gt;&lt;/router-view&gt;
&nbsp;&nbsp;&lt;/div&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">被选中的route-link，会自动添加上两个class属性：router-link-active和router-link-exact-active</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.cztcode.com/wp-content/uploads/2021/08/image-40.png" alt="" class="wp-image-4090" /></figure>



<p class="is-style-iw-2em wp-block-paragraph">可以利用这个class为其配置样式。其中router-link-exact-active与router-link-active的区别是，router-link-exact-active只有在精准匹配时才会加上这个class（嵌套组件的嵌套路由），而router-link-active是任何父组件也会加上。</p>



<p class="is-style-iw-2em wp-block-paragraph">这个默认的class可以通过active-class和extra-active-class来修改：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;&lt;div&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-link&nbsp;to="/home"&nbsp;replace&nbsp;active-class="home-active"&gt;首页&lt;/router-link&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-link&nbsp;to="/about"&nbsp;replace&nbsp;active-class="about-active"&gt;关于&lt;/router-link&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-view&gt;&lt;/router-view&gt;
&nbsp;&nbsp;&lt;/div&gt;</code></pre>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.cztcode.com/wp-content/uploads/2021/08/image-41.png" alt="" class="wp-image-4092" /></figure>



<h2 class="wp-block-heading">路由懒加载</h2>



<p class="is-style-iw-2em wp-block-paragraph">在路由配置的component属性中，将原来的组件替换为一个function（import的promise）：</p>



<pre class="wp-block-code"><code>//&nbsp;import&nbsp;Home&nbsp;from&nbsp;'../pages/Home.vue';
//&nbsp;import&nbsp;About&nbsp;from&nbsp;'../pages/About.vue';

const&nbsp;routes&nbsp;=&nbsp;&#091;
&nbsp;&nbsp;{path:&nbsp;'/',&nbsp;redirect:&nbsp;'/home'},
&nbsp;&nbsp;{path:&nbsp;'/home',&nbsp;component:&nbsp;()=&gt;{
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;import("../pages/Home.vue")
&nbsp;&nbsp;}},
&nbsp;&nbsp;{path:&nbsp;'/about',&nbsp;component:&nbsp;()=&gt;{
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;import("../pages/About.vue")
&nbsp;&nbsp;}}
];</code></pre>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.cztcode.com/wp-content/uploads/2021/08/image-42.png" alt="" class="wp-image-4096" /></figure>



<p class="is-style-iw-2em wp-block-paragraph">利用webpack的魔法注释来为组件分包文件命名，格式为/* webpackChunkName: &#8220;&#8221; */：</p>



<pre class="wp-block-preformatted">const&nbsp;routes&nbsp;=&nbsp;[
&nbsp;&nbsp;{path:&nbsp;'/',&nbsp;redirect:&nbsp;'/home'},
&nbsp;&nbsp;{path:&nbsp;'/home',&nbsp;component:&nbsp;()=&gt;{
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;import(/*&nbsp;webpackChunkName:&nbsp;"home-chunk"&nbsp;*/"../pages/Home.vue")
&nbsp;&nbsp;}},
&nbsp;&nbsp;{path:&nbsp;'/about',&nbsp;component:&nbsp;()=&gt;{
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;import(/*&nbsp;webpackChunkName:&nbsp;"page-chunk"&nbsp;*/"../pages/About.vue")
&nbsp;&nbsp;}}
];</pre>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.cztcode.com/wp-content/uploads/2021/08/image-43.png" alt="" class="wp-image-4097" /></figure>



<h2 class="wp-block-heading">动态路由</h2>



<p class="is-style-iw-2em wp-block-paragraph">在route中可以加上/:params来表示动态路由：</p>



<pre class="wp-block-code"><code>// route
  {
    path: "/user/:username",
    component: ()=&gt;{
      return import("../pages/User.vue")
    }
  }</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在route-link中，必须要匹配到对应的格式才能正确路由：</p>



<pre class="wp-block-code"><code>// route-link
    &lt;router-link :to="'/user/'+name"&gt;用户&lt;/router-link&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在组件中获取动态路由的参数：一是从this中获取，在this.$route中：</p>



<pre class="wp-block-code"><code>&lt;template&gt;
  &lt;div&gt;
    &lt;h2&gt;User: {{$route.params.username}}&lt;/h2&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
  export default {
    created() {
      console.log(this.$route.params.username);
    },
  }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">二是使用vue-route 4的钩子函数useRoute直接获取这个组件的route：</p>



<pre class="wp-block-code"><code>&lt;script&gt;
import {useRoute, useRouter} from "vue-router"
  export default {
    setup(props) {
      const route = useRoute();
      console.log(route.params.username);
    }
  }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">嵌套路由同理。</p>



<h2 class="wp-block-heading">NotFound</h2>



<p class="is-style-iw-2em wp-block-paragraph">定义一个类似于动态路由中的route，不过path是固定写法：</p>



<pre class="wp-block-code"><code>  {
    // 固定写法pathMatch
    path: "/:pathMatch(.*)",
    component: ()=&gt;{
      return import("../pages/NotFound.vue")
    }
  }</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">由此可以导向我们编写的NotFound的组件。</p>



<p class="is-style-iw-2em wp-block-paragraph">获取NotFound时的路径的方法：从route.params.pathMatch中获取：</p>



<pre class="wp-block-code"><code>&lt;h2&gt;{{$route.params.pathMatch}}&lt;/h2&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">如果在/:pathMatch(.*)后面再加上一个*，就会将路径按照每一个&#8221;/&#8221;为分隔符进行分割并返回一个数组。</p>



<h2 class="wp-block-heading">嵌套路由</h2>



<p class="is-style-iw-2em wp-block-paragraph">现在home组件下还有两个子组件HomeShops和HomeMessage，分别应该使用/home/shops和/home/message来访问之，在配置路由时，在home的路由下的children属性来为这两个组件配置。</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;path:&nbsp;'/home',&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;component:&nbsp;()=&gt;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;import(/*&nbsp;webpackChunkName:&nbsp;"home-chunk"&nbsp;*/"../pages/Home.vue")
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;name:&nbsp;"home",
&nbsp;&nbsp;&nbsp;&nbsp;meta:&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name:&nbsp;"shopkeeper"
&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;children:&nbsp;&#091;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path:'shops',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;component:&nbsp;()=&gt;&nbsp;import("../pages/HomeShops.vue")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path:'message',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;component:()=&gt;&nbsp;import("../pages/HomeMessage.vue")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;]
&nbsp;&nbsp;},</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">可以发现在children中的route，path缺省了父组件的&#8221;/home&#8221;，并且也不需要加上&#8221;/&#8221;。</p>



<p class="is-style-iw-2em wp-block-paragraph">在children中设置重定向，path直接填写空字符串即可，但是redirect内容要填写完整的重定向路径：</p>



<pre class="wp-block-code"><code>    children: &#091;
      {
        path:"",
        redirect:"/home/message"
      },
      {
        path:'shops',
        component: ()=&gt; import("../pages/HomeShops.vue")
      },
      {
        path:'message',
        component:()=&gt; import("../pages/HomeMessage.vue")
      }
    ]</code></pre>



<h2 class="wp-block-heading">编程式导航</h2>



<p class="is-style-iw-2em wp-block-paragraph">编程式导航是指通过代码来实现跳转逻辑。例如我们需要点击一个按钮来跳转到“关于”页，假设有如下的button：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;button&nbsp;@click="jumpToAbout"&gt;关于&lt;/button&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">对于jumpToAbout方法，如果是在methods的options中定义，可以直接使用this.$router对象：</p>



<pre class="wp-block-code"><code>  methods: {
    jumpToAbout(){
      // 首先要拿到router对象（不推荐直接导入）
      this.$router.push("/about");
    }
  },</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">如果是在setup中，需要使用一个和useRoute相似的钩子函数useRouter：</p>



<pre class="wp-block-code"><code>import&nbsp;{useRouter}&nbsp;from&nbsp;'vue-router'
export&nbsp;default&nbsp;{
&nbsp;&nbsp;components:&nbsp;{
&nbsp;&nbsp;},
&nbsp;&nbsp;setup(props)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;router&nbsp;=&nbsp;useRouter();
&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;jumpToAbout(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;首先要拿到router对象（不推荐直接导入）
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;router.push("/about");
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name:&nbsp;"shopkeeper"
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;},</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在这个push方法中还可以传入一个对象（router-link的to属性也可以传入对象），对象中可以包含其它的一些配置，例如：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;router.push({
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path:"/about",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;query:{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name:&nbsp;"shopkeeper",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;age:18
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">参数可以在子组件的$route.query中获取：</p>



<pre class="wp-block-code"><code>&lt;h2&gt;About:&nbsp;{{$route.query.name}}-{{$route.query.age}}&lt;/h2&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">router还有的方法例如replace、go、forward、back等都和history中的用法相同。</p>



<h2 class="wp-block-heading">router-link的v-slot</h2>



<p class="is-style-iw-2em wp-block-paragraph">router-link实际上可以看作是一个插槽，在这个标签的内部可以写入我们想要展示的元素或者组件：</p>



<pre class="wp-block-code"><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;router-link&nbsp;to="/home"&nbsp;replace&nbsp;active-class="home-active"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;nav-bar&nbsp;title="首页"&gt;&lt;/nav-bar&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/router-link&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">route-link中定义v-slot属性，可以获取其内部传来的一个对象：</p>



<pre class="wp-block-code"><code>    &lt;!-- props：href 跳转的链接 --&gt;
    &lt;!-- props：route对象 --&gt;
    &lt;!-- props：navigate函数 --&gt;
    &lt;!-- props：isActive 当前是否处于活跃状态 --&gt;
    &lt;!-- props：isExactActive 是否是精确活跃状态 --&gt;
    &lt;router-link to="/home" replace active-class="home-active" v-slot="props" custom&gt;
      &lt;!-- &lt;nav-bar title="首页"&gt;&lt;/nav-bar&gt; --&gt;
      &lt;button&gt;{{props.href}}&lt;/button&gt;
      &lt;p&gt;{{props.route}}&lt;/p&gt;
      &lt;button @click="props.navigate"&gt;导航&lt;/button&gt;
      &lt;span :class="{'active': props.isActive}"&gt;{{props.isActive}}&lt;/span&gt;
    &lt;/router-link&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">如果再加上custom属性的话，router-link将不会给插槽中的组件外层嵌套一个a标签，即此时跳转需要我们手动执行（使用props.navigate函数）。</p>



<h2 class="wp-block-heading">router-view的v-slot</h2>



<p class="is-style-iw-2em wp-block-paragraph">router-view也可以使用插槽，在v-slot中可以获取props.Component属性，即当前要显示的组件，通过这种方式就可以结合transition、component、keep-live等组件使用</p>



<h2 class="wp-block-heading">动态添加/删除路由</h2>



<p class="is-style-iw-2em wp-block-paragraph">对于一些需要选择性注释的路由，可以动态添加：</p>



<pre class="wp-block-code"><code>// 动态添加路由
const categoryRoute = {
  path: "/category",
  component: ()=&gt;import("../pages/Category.vue") 
}
const momentRoute = {
  path: "moment",
  component: ()=&gt;import("../pages/HomeMoment.vue") 
}
// 添加顶级的路由对象
router.addRoute(categoryRoute);
// 添加二级的路由对象
router.addRoute("home",momentRoute);</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">动态删除一个路由有三种方式：</p>



<ul class="wp-block-list"><li>添加一个name相同的路由，之前的路由就会被替代</li><li>通过removeRoute方法，传入路由的名称</li><li>通过addRoute方法的返回值回调（返回的值是一个删除路由的函数）</li></ul>



<p class="is-style-iw-2em wp-block-paragraph">路由的其它一些方法补充：</p>



<ul class="wp-block-list"><li>router.hasRoute() 检查路由是否存在</li><li>router.getRoutes() 获取一个包含所有路由记录的数组</li></ul>



<h2 class="wp-block-heading">路由导航守卫</h2>



<p class="is-style-iw-2em wp-block-paragraph">路由的导航守卫有多种函数可以实现，现在以beforeEach为例，beforeEach种传入一个函数：</p>



<pre class="wp-block-code"><code>// to：Route对象，即将跳转到的route对象
// from：Route对象，从哪个路由对象导航过来的
/**
 * 返回值：
 * 1.false：不进行导航
 * 2.undefined或者不写返回值：进行默认的导航
 * 3.字符串：路径，跳转到对应的路径中
 * 4.对象：类似于router.push({path:"/login",component})
 */
router.beforeEach((to, from)=&gt;{
  console.log(to.path,from.path);
  if (to.path.indexOf("/home")!==-1){
    return "/login"
  }
})</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">使用导航守卫实现一个简单的登录逻辑：假定login组件中，按下登录按钮就会在localStorage中保存一个token，</p>



<pre class="wp-block-code"><code>&lt;template&gt;
  &lt;div&gt;
    &lt;button @click="loginClick"&gt;登录&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import {useRouter} from 'vue-router'
  export default {
    setup(props) {
      const router=useRouter()
      const loginClick=()=&gt;{
        window.localStorage.setItem("token","shopkeper")
        router.push({
          path:"/home"
        })
      }
      return {loginClick}
    }
  }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">那么在导航守卫中，如果要跳转到一个非login的页面，都应该判断本地是否有token，如果没有就应该跳转到login组件中：</p>



<pre class="wp-block-code"><code>router.beforeEach((to, from)=&gt;{
  if (to.path!== "/login"){
    const token = window.localStorage.getItem("token");
    if (!token){
      return "/login"
    }
  }
})</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">其它的导航守卫可以参考<a href="https://next.router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%89%8D%E7%BD%AE%E5%AE%88%E5%8D%AB" class="rank-math-link" target="_blank" rel="noopener">官网</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2021/4089/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4089</post-id>	</item>
		<item>
		<title>VUE3之其它组件</title>
		<link>https://www.cztcode.com/2021/4022/</link>
					<comments>https://www.cztcode.com/2021/4022/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Tue, 17 Aug 2021 13:12:15 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=4022</guid>

					<description><![CDATA[VUE3之其它组件
Render函数
JSX的使用
自定义指令
teleport
VUE插件]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>


<h2 class="wp-block-heading">Render函数</h2>



<p class="is-style-iw-2em wp-block-paragraph"><strong>基本使用</strong></p>



<p class="is-style-iw-2em wp-block-paragraph">render函数用于渲染html元素，用于利用JavaScript实现在template标签中做不了的事情。render提供一个h函数来构造元素，h函数的第一个参数是元素类型，第二个参数是元素的属性，第三个参数是元素的子组件：</p>



<pre class="wp-block-code"><code>&lt;script&gt;
import {h} from 'vue';
  export default {
    render() {
      return h("h2",{class:"title"},"hello render");
    },
  }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">render函数实现计数器</p>



<pre class="wp-block-code"><code>&lt;script&gt;
import {h} from 'vue';
  export default {
    data() {
      return {
        counter:0
      }
    },
    render() {
      return h("div",{class:"app"},&#091;
        h("h2",null,`当前计数：${this.counter}`),
        h("button",{
          onClick:()=&gt;this.counter++
        },"+1"),
        h("button",{
          onClick:()=&gt;this.counter--
        },"-1"),
      ]);
    },
  }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">setup函数也可以完成替代render函数的功能：</p>



<pre class="wp-block-code"><code>&lt;script&gt;
import {h,ref} from 'vue';
  export default {
    setup(props) {
      const counter=ref(0);
      return ()=&gt;{
        return h("div",{class:"app"},&#091;
        h("h2",null,`当前计数：${counter.value}`),
        h("button",{
          onClick:()=&gt;counter.value++
        },"+1"),
        h("button",{
          onClick:()=&gt;counter.value--
        },"-1"),
      ]);
      }
    },
  }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph"><strong>插槽的使用</strong></p>



<pre class="wp-block-code"><code>// HelloWorld.vue
&lt;script&gt;
import { h } from 'vue';
    export default {
        render() {
            return h("div",null,&#091;
                h("h2",null,"hello world"),
                this.$slots.default? this.$slots.default({name:"sk"}):h("span",null,"我是hello world的默认插槽") 
            ]);
        },
    }
&lt;/script&gt;</code></pre>



<pre class="wp-block-code"><code>// App.vue
&lt;script&gt;
import {h} from 'vue';
import HelloWorld from './HelloWorld.vue';
  export default {
    render() {
      return h(HelloWorld,{},{
        default: props=&gt;h("span",null,`App传入HelloWorld的内容: ${props.name}`)
      });
    },
  }
&lt;/script&gt;</code></pre>


]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2021/4022/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4022</post-id>	</item>
		<item>
		<title>VUE3之Composition API（三）</title>
		<link>https://www.cztcode.com/2021/4019/</link>
					<comments>https://www.cztcode.com/2021/4019/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Tue, 17 Aug 2021 07:59:41 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=4019</guid>

					<description><![CDATA[VUE3之Composition API（三）
生命周期钩子
setup中的provide和inject
案例]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>


<h2 class="wp-block-heading">生命周期钩子</h2>



<p class="is-style-iw-2em wp-block-paragraph">在setup中使用生命周期函数，直接导入vue中的onX函数注册生命周期：</p>



<pre class="wp-block-code"><code>&lt;script&gt;
import {onMounted, onUpdated,onUnmounted,ref} from 'vue';
    export default {
        setup(props) {
            const counter =ref(0);
            const increment=()=&gt;{
                counter.value++;
            };
            onMounted(() =&gt; {
                console.log("app mounted");
            });
            onUpdated(() =&gt; {
                console.log("app updated");
            });
            onUnmounted(() =&gt; {
                console.log("app unmounted");
            });
            return {
                counter,
                increment
            }
        }
    }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">一个生命周期函数可以使用多次。</p>


]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2021/4019/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4019</post-id>	</item>
		<item>
		<title>VUE3之Composition API（二）</title>
		<link>https://www.cztcode.com/2021/4011/</link>
					<comments>https://www.cztcode.com/2021/4011/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Mon, 16 Aug 2021 15:27:39 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=4011</guid>

					<description><![CDATA[VUE3之Composition API（二）
Reactive API的补充
toRefs和toRef
ref API的补充
customRef
setup中computed的使用
watchEffect
setup中使用ref
watch]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>


<h2 class="wp-block-heading"><strong>Reactive API的补充</strong></h2>



<p class="is-style-iw-2em wp-block-paragraph">isProxy：检查对象是否是由reactive或readonly创建的proxy.</p>



<p class="is-style-iw-2em wp-block-paragraph">isReactive：检查对象是否是由reactive创建的响应式代理；如果该代理是readonly建的，但包裹了由reactive 创建的另一个代理，它也会返回true ;</p>



<p class="is-style-iw-2em wp-block-paragraph">isReadonly：检查对象是否是由readonly 创建的只读代理。</p>



<p class="is-style-iw-2em wp-block-paragraph">toRaw：返回reactive或readonly 代理的原始对象（不建议保留对原始对象的持久引用。请谨慎使用)。</p>



<p class="is-style-iw-2em wp-block-paragraph">shallowReactive：创建一个响应式代理，它跟踪其自身property 的响应性，但不执行嵌套对象的深层响应式转换(深层还是原生对象)。</p>



<p class="is-style-iw-2em wp-block-paragraph">shallowReadonly：创建一个proxy，使其自身的 property为只读，但不执行嵌套对象的深度只读转换（深层还是可读、可写的)。</p>



<h2 class="wp-block-heading"><strong>toRefs和toRef</strong></h2>



<p class="is-style-iw-2em wp-block-paragraph">toRefs：将reactive对象中所有属性都转为ref，建立连接</p>



<p class="is-style-iw-2em wp-block-paragraph">toRef：对其中一个属性进行转换为ref，建立连接</p>



<pre class="wp-block-code"><code>&lt;script&gt;
import { reactive, toRefs, toRef } from "vue";
    export default {
        setup() {
            const info=reactive({name:"sk",age:18});
            // toRefs：将reactive对象中所有属性都转为ref，建立连接
            // let { name, age }=toRefs(info);
            // toRef：对其中一个属性进行转换为ref，建立连接
            let {name}=toRefs(info);
            let age=toRef(info,"age");
            const change=()=&gt;{
                // age.value++;
                info.age++;
            }

            return {
                name,
                age,
                change
            }
        }
    }
&lt;/script&gt;</code></pre>



<h2 class="wp-block-heading"><strong>ref API的补充</strong></h2>



<p class="is-style-iw-2em wp-block-paragraph">unref：如果我们想要获取一个ref引用中的value，那么也可以通过unref方法︰如果参数是一个ref，则返回内部值，否则返回参数本身;这是val = isRef(val) ? val.value : val的语法糖函数;</p>



<p class="is-style-iw-2em wp-block-paragraph">isRef：判断值是否是一个ref对象。</p>



<p class="is-style-iw-2em wp-block-paragraph">shallowRef：创建一个浅层的ref对象</p>



<p class="is-style-iw-2em wp-block-paragraph">triggerRef：手动触发和shallowRef相关联的副作用。</p>



<pre class="wp-block-code"><code>&lt;script&gt;
import { ref, shallowRef, triggerRef } from "vue";
    export default {
        setup() {
            // 浅层响应式
            const info=shallowRef({name:"sk"});
            const changeInfo=()=&gt;{
                info.value.name="james";
                triggerRef(info);
            }
            return {
                info,
                changeInfo
            }
        }
    }
&lt;/script&gt;</code></pre>



<h2 class="wp-block-heading"><strong>customRef</strong></h2>



<p class="is-style-iw-2em wp-block-paragraph">customRef可以是我们能够决定如何跟踪依赖与什么时候触发更新。其工厂函数需要传入track和trigger参数，并返回一个拥有get和set方法的对象：</p>



<pre class="wp-block-code"><code>import { customRef } from "vue";
// 自定义ref
export default function(value){
    let timer=null;
    return customRef((track,trigger)=&gt;{
        return {
            get(){
                track();
                return value;
            },
            set(newValue){
                clearTimeout(timer);
                timer=setTimeout(()=&gt;{
                    value=newValue;
                    trigger();
                },1000);
            }
        }
    })
}</code></pre>


]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2021/4011/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4011</post-id>	</item>
		<item>
		<title>VUE3之Composition API（一）</title>
		<link>https://www.cztcode.com/2021/4004/</link>
					<comments>https://www.cztcode.com/2021/4004/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Sun, 15 Aug 2021 02:16:45 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=4004</guid>

					<description><![CDATA[VUE3之Composition API（一）
mixin和extends
setup
reactive API
ref API
readOnly]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>


<h2 class="wp-block-heading">mixin和extends</h2>



<p class="is-style-iw-2em wp-block-paragraph"><strong>mixin的基本使用</strong></p>



<p class="is-style-iw-2em wp-block-paragraph">mixin本质上是一个对象，其中可以包含一个组件的option属性:</p>



<pre class="wp-block-code"><code>export const demoMixin = {
    data() {
        return {
            message:"hello demoMixin"
        }
    },
    methods: {
        foo(){
            console.log("demo mixin foo");
        }
    },
    created() {
        console.log("执行了demo mixin");
    },
}</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在使用时，写在组件的options的mixins属性里面：</p>



<pre class="wp-block-code"><code>&lt;script&gt;
import {demoMixin} from './mixins/demoMixin.js'
    export default {
        mixins:&#091;demoMixin],
        data() {
            return {
                title: "hello world"
            }
        },
        methods: {
            
        },
    }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">如果mixin与组件中不存在命名冲突，就直接合并，如果存在冲突，分成不同情况处理：</p>



<p class="is-style-iw-2em wp-block-paragraph">返回值对象默认情况下会合并，如果data返回值对象的属性发生了冲突，那么会保留组件自身的数据。</p>



<p class="is-style-iw-2em wp-block-paragraph">生命周期钩子函数会被合并到数组中，都会被调用。</p>



<p class="is-style-iw-2em wp-block-paragraph">对于methods、computed这种对象，会直接合并，如果对象的key相同，则采用组件的value。</p>



<p class="is-style-iw-2em wp-block-paragraph"><strong>全局mixin</strong></p>



<p class="is-style-iw-2em wp-block-paragraph">全局mixin是直接调用app实例的mixin方法，并传入mixin对象完成的，所有app的组件都会享有全局mixin的内容：</p>



<pre class="wp-block-code"><code>const app=createApp(App);
app.mixin({
    created() {
        console.log("全局的生命周期")
    },
})
app.mount('#app');</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">extends</p>



<p class="is-style-iw-2em wp-block-paragraph">extends类似于OOP的继承，可以让一个页面继承于另一个页面：</p>



<pre class="wp-block-code"><code>// BasePage.vue
&lt;script&gt;
    export default {
        data() {
            return {
                title:"hello page"
            }
        },
        methods: {
            bar(){
                console.log("base page bar");
            }
        },
    }
&lt;/script&gt;</code></pre>



<pre class="wp-block-code"><code>// Home.vue
&lt;template&gt;
    &lt;div&gt;
        home page
        &lt;h2&gt;{{title}}&lt;/h2&gt;
        &lt;button @click="bar"&gt;按钮&lt;/button&gt;
    &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import BasePage from './BasePage.vue';
    export default {
        extends:BasePage
    }
&lt;/script&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">extends的规则和用法与mixin相同，并且只能继承父组件的script标签的内容。</p>


]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2021/4004/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4004</post-id>	</item>
		<item>
		<title>VUE3之Animation（二）</title>
		<link>https://www.cztcode.com/2021/3997/</link>
					<comments>https://www.cztcode.com/2021/3997/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Fri, 13 Aug 2021 08:22:01 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=3997</guid>

					<description><![CDATA[VUE3之Animation（二）
animate.css
gsap库
利用gsap实现数字渐变效果
transition-group
列表的交替动画]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>


<h2 class="wp-block-heading">animate.css</h2>



<p class="is-style-iw-2em wp-block-paragraph">安装：</p>



<pre class="wp-block-code"><code>npm install animate.css -save</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">在文件中添加引用：</p>



<pre class="wp-block-code"><code>import "animate.css";</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">第一种使用方法和普通的animation用法差不多，需要使用动画的元素要被&lt;transition&gt;包裹，并在style中通过动画的名字使用animate.css的样式：</p>



<pre class="wp-block-code"><code>&lt;template&gt;
  &lt;div class="app"&gt;
      &lt;div&gt;
        &lt;button @click="isShow=!isShow"&gt;显示/隐藏&lt;/button&gt;
      &lt;/div&gt;
      &lt;transition name="sk" mode="out-in" :appear="true"&gt;
        &lt;h2 class="title" v-if="isShow"&gt;hello world&lt;/h2&gt;
      &lt;/transition&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
  export default {
    data() {
      return {
        isShow: true
      }
    },
  }
&lt;/script&gt;

&lt;style scoped&gt;

  .title{
    display: inline-block;
  }

  .sk-enter-active{
    animation: rollIn 1s ease-in
  }
  
  .sk-leave-active{
    animation: rollOut 1s ease-in
  }
&lt;/style&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">第二种用法是直接在transition标签中加入enter-active-class和leave-active-class属性，属性值为”animate__animated&nbsp;“+动画名称：</p>



<pre class="wp-block-code"><code>      &lt;transition enter-active-class="animate__animated animate__rotateIn" 
        leave-active-class="animate__animated animate__rotateOutDownLeft"&gt;
        &lt;h2 class="title" v-if="isShow"&gt;hello world&lt;/h2&gt;
      &lt;/transition&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">此外还有一些属性例如enter-to-class、enter-from-class、leave-to-class、leave-from-class</p>


]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2021/3997/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3997</post-id>	</item>
		<item>
		<title>VUE3之Animation（一）基本使用</title>
		<link>https://www.cztcode.com/2021/3994/</link>
					<comments>https://www.cztcode.com/2021/3994/#respond</comments>
		
		<dc:creator><![CDATA[Jellow]]></dc:creator>
		<pubDate>Thu, 12 Aug 2021 13:45:04 +0000</pubDate>
				<category><![CDATA[Vue]]></category>
		<guid isPermaLink="false">https://www.cztcode.com/?p=3994</guid>

					<description><![CDATA[VUE3之Animation（一）基本使用
transition的基本使用
animation帧动画
transition的属性]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div>


<h2 class="wp-block-heading">transition的基本使用</h2>



<p class="is-style-iw-2em wp-block-paragraph">对要使用动画的单个组件使用transition标签包裹，并为transition标签定义一个name：</p>



<pre class="wp-block-code"><code>      &lt;transition name="sk"&gt;
        &lt;h2 v-if="isShow"&gt;hello world&lt;/h2&gt;
      &lt;/transition&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">根据name的名称去style中定义样式，以name-为开头的一系列class：</p>



<pre class="wp-block-code"><code>&lt;style scoped&gt;
  .sk-enter-from,
  .sk-leave-to{
    opacity: 0;
  }

  .sk-enter-to,
  .sk-leave-from{
    opacity: 1;
  }

  .sk-enter-active,
  .sk-leave-active{
    transition: opacity 2s ease;
  }
&lt;/style&gt;</code></pre>



<p class="is-style-iw-2em wp-block-paragraph">如果在transition中不指定name，以上的class都以v-开头，如v-enter-from</p>


]]></content:encoded>
					
					<wfw:commentRss>https://www.cztcode.com/2021/3994/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3994</post-id>	</item>
	</channel>
</rss>
