vue基础(一)补充3

模块导出导入#

ES中的模块导出导入#

export 和 export default

首先我们讲这两个导出,下面我们讲讲它们的区别

  • export与export default均可用于导出常量、函数、文件、模块等
  • 在一个文件或模块中,export、import可以有多个,export default仅有一个
  • 通过export方式导出,在导入时要加{ },export default则不需要
  • export能直接导出变量表达式,export default不行。

nodejs中模块导出导入#

exports、module.exports

尽量都用 module.exports 导出,然后用require导入。

module.exports 提供了暴露接口的方法。

require方能看到的只有module.exports这个对象,它是看不到exports对象的,而我们在编写模块时用到的exports对象实际上只是对module.exports的引用。

**module.exports **返回的是模块对象本身#

先说说它们之间的区别:

  • exports只能使用语法来向外暴露内部变量:如http://exports.xxx = xxx;
  • module.exports既可以通过语法,也可以直接赋值一个对象。

我们要明白一点,exports和module.exports其实是一个东西,不信我们来输出一下

Copy Highlighter-hljs
console.log(module.exports === exports); //输出结果为:true

输出结果是true其实就说明它们就是一个东西,其实exports = module.exports,因为他们是引用类型的一个变量名,所以当exports再指向一个引用类型的时候,那么他们就不再全等。

Copy Highlighter-hljs
exports = [0, 1]; console.log(exports === module.exports); //输出结果为:false

当然,如果直接通过exports.xxx的形式赋值,那么他们依然会指向同一个地址:

Copy Highlighter-hljs
exports.array = [0, 1]; console.log(exports === module.exports); //输出结果为:true

mixin混入对象#

mixin混入对象中声明了:如果是同名钩子函数将合并为一个数组,因此都被调用,但是混入对象的钩子将在自身实例钩子之前触发;

mixin混入对象和Vuex的区别:

    Vuex是状态共享管理,所以Vuex中的所有变量和方法都是可以读取和更改并相互影响的;

    mixin可以定义公用的变量或方法,但是mixin中的数据是不共享的,也就是每个组件中的mixin实例都是不一样的,都是单独存在的个体,不存在相互影响的;

    mixin混入对象值为函数的同名函数选项将会进行递归合并为数组,两个函数都会执行,只不过先执行mixin中的同名函数;

    mixin混入对象值为对象的同名对象将会进行替换,都优先执行组件内的同名对象,也就是组件内的同名对象将mixin混入对象的同名对象进行覆盖;

vue 中 关于路径 @ 以及 ~的意义#

  1. 样式里引入样式,需要用 @import这种开头。
  2. 还要在样式里引入样式,并且想要使用 @ 符号表示src目录, 在以上前提下,需要在 @ 前加上~波浪号代表根目录。
Copy Highlighter-hljs
@import '~@/assets/styles/mixins' background: url("~@/assets/home/author-bg.png") no-repeat center/cover;

::v-deep深度作用选择器#

直接在 <style lang="scss" scoped> .... </style> 中编写的话只会影响当前组件内的样式,但如果去掉scoped话又会影响全局样式。

Copy Highlighter-hljs
<style lang="scss" scoped> ::v-deep .van-swipe__indicators { } 如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符: <style scoped> .a >>> .b { /* ... */ } </style> 上述代码将会编译成: .a[data-v-f3f3eg9] .b { /* … */ } 有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。

sass 插值语句 #{}#

通过 #{} 插值语句可以在选择器或属性名中使用变量:

Copy Highlighter-hljs
@for $i from 1 through 3 { .my-scroll-item:nth-child(#{$i}) { .plan-curry3 { .badge { background-image: url("../assets/home/plan-badge#{$i}-active.png") !important; } } } }

loader原理,css-loader与style-loader#

1.css-loader 的作用是处理css中的 @import 和 url 这样的外部资源

2.style-loader 的作用是把样式插入到 DOM中,方法是在head中插入一个style标签,并把样式写入到这个标签的 innerHTML里

loader的原理

loader能把源文件翻译成新的结果,一个文件可以链式经过多个loader编译。以处理scss文件为例:

  • sass-loader把scss转成css
  • css-loader找出css中的依赖,压缩资源
  • style-loader把css转换成脚本加载的JavaScript代码

vue.config.js 配置#

vue-cli3 脚手架搭建完成后,项目目录中没有 vue.config.js 文件,需要手动创建

Copy Highlighter-hljs
module.exports = { publicPath: "./", lintOnSave: false, devServer: { open:false, // 是否打开浏览器 host:'lx.hi-daas.com', port:8080, https:false, hotOnly:false, // 热更新 disableHostCheck:true, proxy: { "/apis": { target: "http://serviceapi.ixlcg.com/api", // 接口域名 secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true, //是否跨域 pathRewrite: { "^/apis": "", //需要rewrite的, }, }, }, }, chainWebpack: config => { // 添加别名 config.resolve.alias .set('vue$', 'vue/dist/vue.esm.js') .set('@', resolve('src')) .set('@assets', resolve('src/assets')) .set('@scss', resolve('src/assets/scss')) .set('@components', resolve('src/components')) .set('@plugins', resolve('src/plugins')) .set('@views', resolve('src/views')) .set('@router', resolve('src/router')) .set('@store', resolve('src/store')) .set('@layouts', resolve('src/layouts')) .set('@static', resolve('src/static')) }, css: { loaderOptions: { // 默认情况下 `sass` 选项会同时对 `sass` 和 `scss` 语法同时生效 // 因为 `scss` 语法在内部也是由 sass-loader 处理的 // 但是在配置 `prependData` 选项的时候 // `scss` 语法会要求语句结尾必须有分号,`sass` 则要求必须没有分号 // 在这种情况下,我们可以使用 `scss` 选项,对 `scss` 语法进行单独配置 scss: { additionalData: `@import "~@/styles/index.scss";`, }, }, }, };

scss配置全局变量,由于sass-loader版本不同,loaderOptions 中 additionalData的键名也不同

Copy Highlighter-hljs
sass-loader v8-,这个选项名是 "data" sass-loader v8 中,这个选项名是 "prependData" sass-loader v10+,这个选项名是 "additionalData"

配置选项#

  • publicPath
Copy Highlighter-hljs
Typestring Default'/'  部署应用包时的基本 URL, 用法和 webpack 本身的 output.publicPath 一致。 这个值也可以被设置为空字符串 ('') 或是相对路径 ('./'),这样所有的资源都会被链接为相对路径,这样打出来的包可以被部署在任意路径。
  • lintOnSave

    Type: boolean | 'error'

    Default: true

    是否在保存的时候使用 eslint-loader 进行检查。 有效的值:ture | false | "error" 当设置为 "error" 时,检查出的错误会触发编译失败。

  • crossorigin

    Type: string
    Default: undefined
    设置生成的 HTML<link rel="stylesheet"><script> 标签的 crossorigin 属性。

  • css.loaderOptions

    Type: Object

    Default: {}

    向 CSS 相关的 loader 传递选项。

    支持的 loader 有:

    css-loader

    postcss-loader

    sass-loader

    less-loader

    stylus-loader

  • devServer

    Type: Object

    所有 webpack-dev-server 的选项都支持。注意:

    有些值像 host、port 和 https 可能会被命令行参数覆写。

    有些值像 publicPath 和 historyApiFallback 不应该被修改,因为它们需要和开发服务器的 publicPath 同步以保障正常的工作。

  • devServer.proxy

    Type: string | Object

    如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。

嵌套路由#

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如:

Copy Highlighter-hljs
/user/foo/profile /user/foo/posts +------------------+ +-----------------+ | User | | User | | +--------------+ | | +-------------+ | | | Profile | | +------------> | | Posts | | | | | | | | | | | +--------------+ | | +-------------+ | +------------------+ +-----------------+

借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。

创建的 app:

Copy Highlighter-hljs
<div id="app"> <router-view></router-view> </div>

这里的 <router-view> 是最顶层的出口,渲染最高级路由匹配到的组件。同样地,一个被渲染组件同样可以包含自己的嵌套 <router-view>。例如,在 User 组件的模板添加一个 <router-view>

Copy Highlighter-hljs
const User = { template: ` <div class="user"> <h2>User {{ $route.params.id }}</h2> <router-view></router-view> </div> ` }

要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:

Copy Highlighter-hljs
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 当 /user/:id/profile 匹配成功, // UserProfile 会被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 当 /user/:id/posts 匹配成功 // UserPosts 会被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })

Vue 开发必须知道的 36 个技巧#

Vue 开发必须知道的 36 个技巧

Axios 的插件化封装#

Copy Highlighter-hljs
import axios from 'axios' // 创建一个错误 function errorCreate(msg) { const error = new Error(msg) throw error } // 创建一个 axios 实例 const service = axios.create({ // baseURL: process.env.NODE_ENV == "development" ? "/apis" : "http://xxx.com/api", baseURL: process.env.NODE_ENV == "development" ? "/apis" : "http://xxx.com/api", timeout: 6000 // 请求超时时间 }) // 请求拦截器 service.interceptors.request.use( // 传入的config就是当前Axios对象 config => { // 判断 发送的请求地址不止login时,一律添加请求头 //if(conf.url !== 'login'){ // conf.headers.Authorization = localStorage.getItem('token'); //} config.headers['api-token'] = JSON.parse(window.localStorage.getItem('token')); console.log(config); // 将拦截器的操作返回给axios 对象 return config }, error => { // 发送失败 //对响应错误做点什么 console.log(error) Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( response => { // dataAxios 是 axios 返回数据中的 data const dataAxios = response.data // 这个状态码是和后端约定的 const { code } = dataAxios // 根据 code 进行判断 if (code == "200") { // 如果没有 code 代表这不是项目后端开发的接口 比如可能是 D2Admin 请求最新版本 return dataAxios.data } else { // 有 code 代表这是一个后端接口 可以进行进一步的判断 switch (code) { case 0: // [ 示例 ] code === 0 代表没有错误 return dataAxios case 'xxx': // [ 示例 ] 其它和后台约定的 code errorCreate(`[ code: xxx ] ${dataAxios.msg}: ${response.config.url}`) break default: // 不是正确的 code errorCreate(`${dataAxios.msg}: ${response.config.url}`) break } } }, error => { if (error && error.response) { switch (error.response.status) { case 400: error.message = '请求错误'; break case 401: error.message = '未授权,请登录'; break case 403: error.message = '拒绝访问'; break case 404: error.message = `请求地址出错: ${error.response.config.url}`; break case 408: error.message = '请求超时'; break case 500: error.message = '服务器内部错误'; break case 501: error.message = '服务未实现'; break case 502: error.message = '网关错误'; break case 503: error.message = '服务不可用'; break case 504: error.message = '网关超时'; break case 505: error.message = 'HTTP版本不受支持'; break default: break } } return Promise.reject(error) } ) export default service

导航守卫#

导航守卫: https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

Copy Highlighter-hljs
// 配置路由的导航守卫 import router from "./router"; // 当前用户是否登录 router.beforeEach((to, form, next) => { if (to.name === 'Login') { next(); } else { // 如果请求的不是登录页面,验证token // 1. 获取本地存储中的 token const token = localStorage.getItem('token'); if (!token) { // 2. 如果没有token,跳转到登录 next({ name: 'Login' }); } else { // 3. 如果有token,继续往下执行 next(); } } }); // // 跳转页面后统一回到顶部 router.afterEach((to, form, next) => { window.scrollTo(0, 0); });

es6新增语法之${}#

这是es6中新增的字符串方法

可以配合反单引号完成拼接字符串的功能

用法:
step1: 定义需要拼接进去的字符串变量

step2: 将字符串变量用${}包起来,再写到需要拼接的地方

step3:一定是用反单引号引起来的!不要写成单引号了!!

element-ui#

element-ui表格中加入按钮等元素时,需要使用 template 进行包裹:

而在 template 标签中有一个 slot-scope="scope" 属性, scope 的值就是本列中所有数据的值,参考: Table

表格->固定列,利用scope 中的值,争取显示用户状态

Copy Highlighter-hljs
<el-table-column label="操作" width="210px"> <template> <el-button type="primary" icon="el-icon-edit" plain></el-button> <el-button type="primary" icon="el-icon-check" plain></el-button> <el-button type="primary" icon="el-icon-delete" plain></el-button> </template> </el-table-column>

只要在 el-table 元素中定义了 height=500 属性,即可实现固定表头的表格,而不需要额外的代码。

要注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。

posted @   caibaotimes  阅读(250)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示
CONTENTS