# vue-learn **Repository Path**: jxmlearner/vue-learn ## Basic Information - **Project Name**: vue-learn - **Description**: vue学习笔记 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-05-21 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Vue学习笔记 + [vue常见面试题](https://segmentfault.com/a/1190000016344599) ## 1. 初始化项目 ``` vue create vue-learn #只选用了babel 和ESLint的模板 cd vue-learn code . ``` + 用 git 来管理 ```bash git init git remote add origin git@gitee.com:jxmlearner/vue-learn.git git push -u origin master ``` ## 2. 记nginx的反向代理配置示例 + 使用的是 [nginx for windows](http://nginx.org/en/docs/windows.html) ```bash server { listen 6666; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } location ^~ /iserver/ { proxy_pass http://192.168.4.199:8090/iserver/; proxy_set_header Host $host; proxy_set_header X-Real_IP $remote_addr; proxy_set_header X-Forwarded-for $remote_addr; } location ^~ /vue/ { proxy_pass http://192.168.4.167:3090/; proxy_set_header Host $host; proxy_set_header X-Real_IP $remote_addr; proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; } location ^~ /swagger/ { proxy_pass http://192.168.4.167:3090/swagger; proxy_set_header Host $host; proxy_set_header X-Real_IP $remote_addr; proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } ``` + 启动 nginx `nginx start` + 修改配置后重启 `nginx -s reload` ## 3. vue插件 + vue插件是要export的对象包含 install方法,该方法接收vue构造器及配置选项 ```js /** * Vue的插件,用来获取和设置localStorage存储 * */ let local = { save (key, value) { localStorage.setItem(key,JSON.stringify(value)) }, fetch(key) { return JSON.parse(localStorage.getItem(key)) || {} } } export default { install: function(Vue, opts) { Vue.prototype.$local = local } } ``` ## 4. gulp使用记录 + `yarn add gulp gulp-concat del -D` + [阮一峰 gulp教程](http://javascript.ruanyifeng.com/tool/gulp.html) + gulpfile.js ```js let gulp = require('gulp') let del = require('del') let concat = require('gulp-concat') let fs = require('fs') function swallowError (error) { console.error(error.toString()) this.emit('end') } // 清除原有的appiview样式 gulp.task('clean', (cb) => { fs.access('./src/assets/css/iview/appiview.scss', (err) => { if (!err) { del.sync(['./src/assets/css/iview/appiview.scss']) // 同步删除 不然会导致合并异常 cb() } else { cb() } }) }) // 生成新的appiview样式 gulp.task('iview', gulp.series('clean', function() { // 先执行clean 在执行iview 不添加[clean] 将会并行运行导致合并异常 return gulp.src('./src/assets/css/iview/*.scss') .pipe(concat('appiview.scss')) //合并后的文件名 .on('error', swallowError) .pipe(gulp.dest('./src/assets/css/iview')) })) // 开发时监听 文件变化 自动构建(npm/yarn) gulp watch gulp.task('watch', () => { gulp.watch('./src/assets/css/iview/*.scss', gulp.series('clean', 'iview')) }) // 任务流 gulp.task('default', gulp.series('clean', 'iview')) ``` ## 5. 小小进度百分比组件 ``` ``` ## 6. 安装 sass `yarn add node-sass sass-loader -D` ## 7. 加入 Vue-Router + `yarn add vue-router` ## 8. 组件的一些API + [参考阅读](https://blog.csdn.net/grapelove01/article/details/82501604) ### 8.1 extends 选项 + 类型: `Object | Function` + 详细: - 允许声明扩展另一个组件(可以是一个简单的选项对象或构造函数),而无需使用`Vue.extend`。这主要是为了扩展单文件组件。 + 示例: ```js var CompA = { ... } // 在没有调用 `Vue.extend` 时候继承 CompA var CompB = { extends: CompA, ... } ``` ### 8.2 Vue.extend(options)全局方法 + 参数: - `{ Object } options` + 用法: 使用基础Vue构造器,创建一个“子类”。参数是一个包含组件选项的对象。 `data` 选项是特例,需要注意 - 在 `Vue.extend()` 中它必须是函数 ```html
``` ```js // 创建构造器 var Profile = Vue.extend({ template: '

{{firstName}} {{lastName}} aka {{alias}}

', data: function() { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point') ``` 结果如下: ```html

Walter White aka Heisenberg

``` ### 8.3 Vue.component( id, [definition] ) + 参数: - `{String} id` - `{Function | Object} [definition]` + 用法: 注册或获取全局组件。注册还会自动使用给定的`id`设置组件的名称 ```js // 注册组件,传入一个扩展过的构造器 Vue.component('my-component', Vue.extend({ /* ... */ })) // 注册组件,传入一个选项对象 (自动调用 Vue.extend) Vue.component('my-component', { /* ... */ }) // 获取注册的组件 (始终返回构造器) var MyComponent = Vue.component('my-component') ``` ## 9. provide/inject如何做到响应式 [官方provide/inject有一个说明](https://cn.vuejs.org/v2/api/#provide-inject): >提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。 也可以利用 Object.defineProperty来定义 ```js ``` 子组件通过inject引入 ```js ``` ## 10. 表单只有一项时,按enter刷新页面的阻止 ```
// search方法 search() { // 搜索按钮事件 // 点击搜索按钮时, 页码定位到第1页 this.pageData.curPage = 1 this.loadListData() // 组织好条件后就去调用加载表格数据的方法 return false }, ``` ## 11. 踩坑数组的浅拷贝 有一个对象列表的数组,傻傻的以为用es6的数组解构就可以拷贝成不同的数据, 还是不能偷懒呀, 正确的使用姿势还是JSON.parse和JSON.stringify ```js // let tempArr = [...this.faceLibList] // 错误的使用方式 let tempArr = JSON.parse(JSON.stringify(this.faceLibList)) this.baseLibraryTree = this.toTreeDataHandle(tempArr) ``` ## 12. 判断某个slot是否存在 ```html ``` # 自定义tab组件 一个普通的tab标签大致的结构通常是如此: ```html
被激活标签项的内容
``` 转换成vue组件,想象中的样子 ``` Tab1内容 Tab2内容 Tab3内容 ``` ## 1. 外层 tabs容器组件 `tabs.vue` ``` ``` ## 2. 单个标签项 tab组件 (用了render function) `tab.vue` ``` ``` ## 3. tab内容展示容器组件 `content-container.vue` ``` ``` ## 4. 注册为全局组件 (和上面组件同目录的index.js) ``` import tabs from './tabs.vue' import tab from './tab.vue' export default (Vue) => { Vue.component(tabs.name, tabs) Vue.component(tab.name, tab) } ``` 接着要在main.js中引入并use一下 ``` import tabs from './components/tabs' Vue.use(tabs) ``` ## 5. 使用组件 ``` ``` ## 6. 效果 ![tab-component.gif](https://upload-images.jianshu.io/upload_images/4342827-a11dd0fec141c717.gif?imageMogr2/auto-orient/strip)