day-057-fifty-seven-20230425-vue项目-vue自定义指令-vue-cli的配置
vue项目
vuex版
-
普通版纯axios:切换页面,就会重新发送一次ajax请求
-
普通版升级:vuex版
-
vuex的常用功能
-
vuex 数据通信
-
vuex 缓存数据 前进后退,切换页面,数据都不会重新加载
- 除非刷新或关闭页面重新打开
- 不用vuex版的:切换页面,就会重新发送一次ajax请求
-
-
能用vuex版的缓存来做的特点
- 不步骤更新的数据,如表格头或用户登录数据之类的
vuex版相对于纯axios的步骤
-
vuex版相对于纯axios的比较
-
获取数据,需要在vuex中获取,组件页面接收使用
- 减少了请求次数
-
切换功能,可以自己写逻辑,来实现数据筛选
-
减少了请求次数
- 不用发送一次获取数据的请求
-
-
删除功能,还是发送删除请求,将数据库中的数据删除。
-
接下来,不再发送重新获取数据更新页面请求,手动将vuex的数据删除,数据改变,页面使用数据,会自动更新页面
- 减少了请求次数
-
-
完成功能,还是发送完成请求,将数据库中的数据改为完成状态。
-
接下来,不再发送重新获取数据更新页面请求,手动将vuex的数据改为完成,数据改变,页面使用数据,会自动更新页面
- 减少了请求次数
-
-
新增功能,还跟以前一样
- 因为后台新增的id,前端并不确定数据是否已经改变了。
-
vuex版配合axios
-
vuex版配合axios步骤
-
操作数据类
-
获取数据,vuex发送一个axios请求用于获取表格数据,组件页面通过vuex拿到表格数据,之后渲染到页面上。
-
在
/src/store/
中创建一个目录/模块目录名/
,里面有一个index.js文件
,以便vuex主实例对象
导入作为一个模块。/src/store/模块目录名/index.js
导出的一个对象,只不过它可以被/src/store/index.js
这个vuex主实例对象
导入并使用。- 这个
/src/store/模块目录名/index.js
依然可以导入其它模块或者是其它方法,以生成自己的模块。不过总体都在/src/store/index.js
这个vuex主实例对象
上。
-
/src/store/模块目录名/index.js
中的state属性里有一个变量,用于保存表格数据。 -
/src/store/模块目录名/index.js
中的mutations属性里有一个同步函数,用于修改表格数据。 -
/src/store/模块目录名/index.js
中的actions属性里有一个异步函数,用于发送axios请求获取表格数据,并通过mutations属性里的同步函数修改state属性里的表格数据变量。 -
在业务组件中从vuex中导入mapState与mapActions辅助函数,并用这两个辅助函数把
/src/store/模块目录名/index.js
中的state属性里的表格数据变量展开放置到业务组件的computed计算属性中,把/src/store/模块目录名/index.js
中的actions属性里的异步函数放置到业务组件的methods方法函数中。 -
业务组件中定义一个计算属性,用于放置渲染表格用的表格数据,它主要对vuex中的表格数据变量进行处理,并用于渲染页面的表格DOM。
-
一开始让业务组件表格loading。
-
在业务组件的created()中调用vuex异步函数,发送一个axios请求表格数据。得到数据后,更新vuex中的表格数据。之后业务组件通过计算属性拿到并处理好vuex中的表格数据,更新业务组件中的表格数据。
-
停止表格loading。
-
-
切换功能,修改tab当前选中角标,业务组件中的表格数据计算属性也会重新计算,进而更新表格。
- 用一个变量保存tab的当前选中角标。
- 如果当前选中角标与当前点击id一致,就不做操作。
- 如果当前选中角标为当前点击id。
- 由于当前角标改变,业务组件中的表格数据计算属性也会重新计算,进而更新表格。
-
删除功能,直接发送一个axios请求用于删除数据,vuex中的同步修改数据,业务组件中的表格数据计算属性也会重新计算,进而更新表格。
/src/store/模块目录名/index.js
中的mutations属性里有一个同步函数,用于删除vuex表格数据中一项数据。- 在业务组件中从vuex中导入mapMutations辅助函数,并用这个辅助函数把把
/src/store/模块目录名/index.js
中的mutations属性里的同步函数放置到业务组件的methods方法函数中。 - 直接发送一个axios请求用于删除后端的一项数据。
- 删除失败,做出提示后,不做操作。
- 删除成功,做出提示后,调用vuex中的同步函数,删除vuex表格数据中一项数据。
- 由于vuex表格数据改变,业务组件通过计算属性拿到并处理好vuex中的表格数据,更新业务组件中的表格数据。
-
完成功能,直接发送一个axios请求用于完成数据,vuex中的同步修改数据,业务组件中的表格数据计算属性也会重新计算,进而更新表格。
/src/store/模块目录名/index.js
中的mutations属性里有一个同步函数,用于修改vuex表格数据中一项数据变成完成状态。- 在业务组件中从vuex中导入mapMutations辅助函数,并用这个辅助函数把把
/src/store/模块目录名/index.js
中的mutations属性里的同步函数放置到业务组件的methods方法函数中。 - 直接发送一个axios请求用于完成后端的一项数据。
- 完成操作失败,做出提示后,不做操作。
- 完成操作成功,做出提示后,调用vuex中的同步函数,修改vuex表格数据中一项数据变成完成状态。
- 由于vuex表格数据改变,业务组件通过计算属性拿到并处理好vuex中的表格数据,更新业务组件中的表格数据。
-
新增功能,对数据进行校验,发送一个axios请求用于新增数据,调用vuex异步函数,发送一个axios请求表格数据,更新vuex中的表格数据。业务组件通过计算属性拿到并处理好vuex中的表格数据,更新业务组件中的表格数据。
- 对数据进行校验,并处理数据让其符合后台需求的格式。
- 直接发送一个axios请求用于新增数据。
- 新增失败,做出提示后,不做操作。
- 新增成功,做出提示后,复用关闭弹窗的方法,之后调用vuex异步函数,发送一个axios请求表格数据。得到数据后,更新vuex中的表格数据。之后业务组件通过计算属性拿到并处理好vuex中的表格数据,更新业务组件中的表格数据。
-
-
非操作数据类的其它方法
-
格式化数据类的
- 处理表格数据,格式化
-
让页面布局变动的
- 关闭页面弹窗之类的,让页面出现提示框或隐藏之类的
- 重置表单之类的功能
-
校验表单数据类的
-
-
工程化开发
-
做功能的时候,分区块进行开发。
-
axios工程化
-
/src/api/index.js
中引入同目录中其它文件夹,每个文件夹中的index.js就是它的一个模块。表现为api对象中的一个属性。- 使用表现为:this.$api.模块名.模块中的请求函数。
-
-
vuex工程化
-
/src/store/index.js
中引入同目录中其它文件夹,每个文件夹中的index.js就是它的一个模块。表现为在它的Vuex实例对象中配置对象中modules对象中的一个属性。-
使用模块中的state及getters及mutations及actions等。
- 一般通过辅助函数来进行。
-
-
-
查找页面与预期不符合的bug
vue自定义指令
vue自定义指令的类型
-
全局指令
-
一般指令都是全局的
Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el) { // 聚焦元素 el.focus() } })
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <h1 v-color:theArg1:theArg2.theModifiers1.theModifiers2="'red'+6">h1</h1> </div> <script> //全局指令: `v-color`; Vue.directive("color", { bind(el, binding, vnode, oldVnode) { console.log(`bind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, inserted(el, binding, vnode, oldVnode) { console.log(`inserted()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, update(el, binding, vnode, oldVnode) { console.log(`update()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, componentUpdated(el, binding, vnode, oldVnode) { console.log(`componentUpdated()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, unbind(el, binding, vnode, oldVnode) { console.log(`unbind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, }); //局部指令: `v-color`; let vm = new Vue({ el: "#app", }); </script> </body> </html>
-
-
局部指令
{ el: "#app", directives: { focus: { // 指令的定义 inserted: function (el) { el.focus() } } } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <h1 v-color:theArg1:theArg2.theModifiers1.theModifiers2="'red'+6">h1</h1> </div> <script> let vm = new Vue({ el: "#app", directives: { //局部指令: `v-color`; color:{ bind(el, binding, vnode, oldVnode) { console.log(`bind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, inserted(el, binding, vnode, oldVnode) { console.log(`inserted()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, update(el, binding, vnode, oldVnode) { console.log(`update()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, componentUpdated(el, binding, vnode, oldVnode) { console.log(`componentUpdated()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, unbind(el, binding, vnode, oldVnode) { console.log(`unbind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, } }, }); </script> </body> </html>
自定义指令的定义方式
-
自定义指令的定义方式:
-
对象,有五个钩子函数
-
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
-
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- 虚拟DOM—真实DOM 插入页面的时候,执行
-
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
-
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
-
unbind:只调用一次,指令与元素解绑时调用。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <h1 v-color:theArg1:theArg2.theModifiers1.theModifiers2="'red'+6" v-background="'blue'">h1</h1> </div> <script> //全局指令: `v-color`; Vue.directive("color", { bind(el, binding, vnode, oldVnode) { console.log(`bind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, inserted(el, binding, vnode, oldVnode) { console.log(`inserted()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); el.style.color=binding.value.slice(0,3) }, update(el, binding, vnode, oldVnode) { console.log(`update()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, componentUpdated(el, binding, vnode, oldVnode) { console.log(`componentUpdated()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, unbind(el, binding, vnode, oldVnode) { console.log(`unbind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, }); let vm = new Vue({ el: "#app", directives: { // bgColor(){},//函数(简写); // 对象 bgColor: { bind() {}, }, //局部指令: `v-background`; background:{ bind(el, binding, vnode, oldVnode) { console.log(`bind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, inserted(el, binding, vnode, oldVnode) { console.log(`inserted()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); el.style.backgroundColor=binding.value; }, update(el, binding, vnode, oldVnode) { console.log(`update()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, componentUpdated(el, binding, vnode, oldVnode) { console.log(`componentUpdated()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, unbind(el, binding, vnode, oldVnode) { console.log(`unbind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); }, } }, }); </script> </body> </html>
-
-
函数(简写) ,相当于对象的inserted()和update()这两个钩子,常用的方式
-
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- 虚拟DOM—真实DOM 插入页面的时候,执行
-
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <h1 v-color:theArg1:theArg2.theModifiers1.theModifiers2="'red'+6" v-background="'blue'">h1</h1> </div> <script> //全局指令: `v-color`; Vue.directive("color", (el, binding, vnode, oldVnode)=> { console.log(`函数简写,相当于对象的inserted()和update(): el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); console.log(`binding.value.slice(0,3)-->`, binding.value.slice(0,3)); el.style.color=binding.value.slice(0,3) }); //局部指令: `v-color`; let vm = new Vue({ el: "#app", directives: { background(el, binding, vnode, oldVnode) { console.log(`函数简写,相当于对象的inserted()和update(): el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode); el.style.backgroundColor=binding.value } }, }); </script> </body> </html>
-
-
vue自定义指令钩子函数的参数
-
钩子函数里面的参数
-
el:指令所绑定的元素,可以用来直接操作 DOM
-
binding:一个对象,包含以下 property:
- name:指令名,不包括 v- 前缀。
- rawName: 指令名,包括 v- 前缀。
- value:指令的绑定值,计算后的,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
- expression:字符串形式的指令表达式。不能计算,例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
- arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
- modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
-
vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
-
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1 v-color:theArg1:theArg2.theModifiers1.theModifiers2="'red'+6" v-background="'blue'">h1</h1>
</div>
<script>
//全局指令: `v-color`;
Vue.directive("color", {
bind(el, binding, vnode, oldVnode) {
console.log(`bind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
},
inserted(el, binding, vnode, oldVnode) {
console.log(`inserted()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
el.style.color=binding.value.slice(0,3)
},
update(el, binding, vnode, oldVnode) {
console.log(`update()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
},
componentUpdated(el, binding, vnode, oldVnode) {
console.log(`componentUpdated()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
},
unbind(el, binding, vnode, oldVnode) {
console.log(`unbind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
},
});
let vm = new Vue({
el: "#app",
directives: {
// bgColor(){},//函数(简写);
// 对象
bgColor: {
bind() {},
},
//局部指令: `v-background`;
background:{
bind(el, binding, vnode, oldVnode) {
console.log(`bind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
},
inserted(el, binding, vnode, oldVnode) {
console.log(`inserted()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
el.style.backgroundColor=binding.value;
},
update(el, binding, vnode, oldVnode) {
console.log(`update()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
},
componentUpdated(el, binding, vnode, oldVnode) {
console.log(`componentUpdated()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
},
unbind(el, binding, vnode, oldVnode) {
console.log(`unbind()钩子函数: el-->`,el,`\n binding-->`,binding,`\n vnode-->`,vnode,`\n oldVnode-->`,oldVnode);
},
}
},
});
</script>
</body>
</html>
vue-cli的配置
-
vue-cli的配置文件在
/vue.config.js
-
2023年4月vue2的
/vue.config.js
新默认配置//脚手架的默认配置 const { defineConfig } = require('@vue/cli-service')//用于提示的一个函数,写在它里面,可以提示一些TypeScript数据类型。 module.exports = defineConfig({ transpileDependencies: true, //... })
-
老vue2的
/vue.config.js
新默认配置//老配置 module.exports = { //... }
-
-
vue-cli默认有一套配置规则,在
/vue.config.js
添加内容会覆盖默认配置信息,增加配置
vue-cli基础配置
-
publicPath:“/” 项目打包放到服务器上后,从服务器的根文件下读取文件(html)
- “./” 项目打包放到服务器上后,根据html文件的位置读取相关文件
-
outputDir:打包的出口文件夹名称 dist
-
assetsDir: 把打包的文件放到对应文件夹里 (js、css、img、fonts)
-
indexPath: 打包后的html文件的路径和名称
-
pages:配置多入口和多出口
-
*lintOnSave: boolean | ‘warning’ | ‘default’ | ‘error’
-
默认:‘default’
-
‘default’/‘error’:控制台爆红,不会继续编译(弹窗)
-
‘warning’/true:控制台爆红,继续编译
-
false:控制台不爆红,代码继续编译(eslint 失效)
-
实际业务开发中:
- 生产环境:false
- 开发环境:true/‘warning’
-
-
productionSourceMap: true 打包js的时候,是否生成map文件 [代码调试文件]
-
runtimeCompiler:false 是否组件中使用 template 选项了,但是这会让你的应用额外增加 10kb 左右
-
transpileDependencies:false es6转成es5的过程中,会忽略所有
node_modules
中的文件- 想要转 :值 --> 数组 [‘bfj’,“base/index.js”]
进阶配置
-
configureWebpack 增加某些配置项(loader plugins)
-
chainWebpack 允许对内部的 webpack 配置进行更细粒度的修改
-
css.requireModuleExtension:true
-
默认情况下,只有 *.module.[ext] 结尾的文件才会被视作 CSS Modules 模块。
- [ext] ----》 *.(css|scss|sass|less|styl(us)?)
-
-
css.extract: 生产环境下是 true,开发环境下是 false
- 是否将组件中的 CSS 提取至一个独立的 CSS 文件中
-
css.sourceMap:false
- 是否为 CSS 开启 source map
-
css.loaderOptions 新增或修改css loader
-
*跨域配置
-
开发环境 需要配置 跨域代理服务器 webpack-dev-server
-
生产环境 就不需要通过webpack配置跨域代理服务器了,需要用过 nginx/apache
-
配置代理服务器
module.exports = { devServer: { host:"127.0.0.1", port:"8081", open:true, proxy:{ "/zhihu":{ target:"https://www.zhihu.com" }, "/jianshu":{ target:"https://www.jianshu.com",//目标服务器网址 ws: true,//使用websocket changeOrigin: true,//是否伪装访问 pathRewrite:{//网址重写 "/jianshu":"" } } } } }
-
-
兼容配置
-
browerslist:兼容浏览器的
-
css兼容 添加属性前缀+ browerslist
- postcss-loader + autoprefixer(添加前缀)
- browerslist(浏览器)
-
js兼容
-
browerslist(浏览器)
-
babel-loader @vue/cli-plugin-babel/preset(vue版的babel-loader) es6–es5
-
class 特色语法处理
-
Promise API 重写—@babel/polyfill
-
下载(webpack)
yarn add @babel/polyfill
-
main.js中导入
import '@babel/polyfill';
-
直接下载使用,会重写所有的API
-
不要直接引入
-
babel.config.js
-
使用 useBuiltIns: ‘usage’,根据你写的es6代码将使用的API进行重写,其余的不会重写
module.exports = { presets: [ '@vue/cli-plugin-babel/preset', { useBuiltIns: 'usage' } ] }
-
-
-
-