如何在 vue 中使用jquery 插件
1. 通过npm install 安装jquery 插件(同时会安装其以来JQuery) npm install jquery-slimscroll
2. 在build/webpack.dev.conf.js 和 build/webpack.prod.conf.js 配置文件中的plugins中追加
plugins: [
// ...
new webpack.ProvidePlugin({
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
jQuery: 'jquery'
})
]
目的是让jQuery可以在所有组件中可以全局访问 因为jqeury插件都依赖于jQuery
3. 在使用jquery插件的组件中引入该插件js代码: import 'jquery-slimscroll'
import './file.js' 可以用来在当前组件文件中执行某个js文件里的代码
Vue如何引入第三方JS库
1. npm install js库
2. 根据第三方js源码 采用不同的导入方式
1) 在ProvidePlugin中添加 全局可用
2) import xxx from 'js库'
3) import 'js库' ( import './plugins/xx.js' )
VUE如何在单页面应用中打开浏览器新标签 并且保持登陆认证信息?(登陆信息存储在sessionStorage中)
1. sessionStorage如何在多个浏览器tabs之间共享
1) 原理:
(通过localStorage的change事件 用localStorage作为传输媒介,将当前tab页面的sessionStorage数据传递到新打开的tab页面中)
2) 实现代码:
// 复制当前页面的sessionStorage值到新打开的浏览器标签页
var cpSessionStorage = function(event) {
if(!event) { event = window.event } // ie
if(!event.newValue) return // do nothing if no value to work with
if (event.key == 'getSessionStorage') {
// 先将当前页面的sessionStorage值 放到localStorage中, 通过localStorage作为传输媒介 (同时会触发localStorage change事件)
localStorage.setItem('sessionStorage', JSON.stringify(sessionStorage))
// 删除掉localStorage中的值
setTimeout(function () {
localStorage.removeItem('sessionStorage')
}, 0)
} else if (event.key == 'sessionStorage' && !sessionStorage.length) {
// 获取其它tab传递过来的sessionStorage数据
var data = JSON.parse(event.newValue)
for (var key in data) {
sessionStorage.setItem(key, data[key])
}
}
}
// 监听localStorage change事件
if(window.addEventListener) {
window.addEventListener("storage", cpSessionStorage, false)
} else {
window.attachEvent("onstorage", cpSessionStorage)
}
// 设置虚假数据 触发localStorage change事件
if (!sessionStorage.length) {
localStorage.setItem('getSessionStorage', 'auth_tokens')
localStorage.removeItem('getSessionStorage', 'auth_tokens')
}
2. 需要打开新标签按钮 通过window.open的形式实现跳转 不再走vue-router
全屏full-screen API使用
可选类库: vue-fullscreen、screenfull等
http://mirari.cc/vue-fullscreen/
https://github.com/sindresorhus/screenfull.js/
全屏api原理: 使用H5的全屏API接口
使用注意事项:
坑: 全屏之后, 被全屏的元素z-index已达到最高, 导致在全屏之后的页面上 不能再出现弹框、dialog对话框等组件 (被挡住),
而且这个z-index是无法改变的
解决: 可以将弹出框、dialog对话框等放到一个container容器中,然后将整个容器全屏
对于一些动态生成的弹框,可以监听其onShow等事件,在弹框出现的时候,将弹框动态插入到全屏容器中(可以)
总之,想办法将要在全屏容器中弹出的其它窗口放入到全屏容器中 否则将被挡住,显示不出来
Vue.js阅读源码学习的知识
1. 通过闭包变量实现缓存方法 (src/shared/util.js -> cached 方法)
function cached(fn) {
// 闭包变量 用于保存缓存的数据
const cache = Object.create(null)
// 返回一个方法
return function(strKey) {
const hit = cache[strKey]
// 如果缓存对象中有以strKey为key的值,直接返回 否则,调用 处理函数fn 获取strKey对应的值 并进行缓存
return hit || (cache[strKey] = fn(strKey))
}
}
// 同一种类型 cached只调用一次
const toUpperCase = cached(str => str.toUpperCase())
// ...可以通过调用多次cached方法 产生多种类型额缓存对象
const toLowerCase = cached(str => str.toLowerCase())
// toUpperCase 调用多次
toUpperCase("aa")
toUpperCase("bb")
toUpperCase("cc")
Vue父子组件通讯
parent->child: props down
child->parent: events up
注意:在子组件中修改引用类型的prop时,会影响到parent中的值
组件样式
组件内使用的样式 一定要加scoped 否则会影响其他组件
如果想覆盖第三方UI库(iview/elementui等)组件的样式
不能加scoped
最好在目标组件上加一个样式类作为限制 ,否则会影响其它页面的相同组件
Single Page Application(SPA)
The entire page state (including the DOM and Javascript/Vuex data) will remain in memory
provided that a full page reload did not occur (which would be the case if you're using vue-router).
This is called a Single Page Application (SPA).In a SPA, you need to ensure that you drop any
references (e.g. set to null) to large objects and arrays when they are no longer needed so that
the memory can be freed by the garbage collector.
(所以vuext-store里的数据,只有在单页面应用内部路由的时候 数据才保持 如果F5刷新整个页面,数据丢失)
递归菜单组件
<Menu :theme="theme" :active-name="activeName" :mode="mode" :open-names="openNames" :accordion="accordion" width="auto" @on-select="onSelect" @on-open-change="onOpenChange">
<main-menu v-for="(item, index) in menuList" :menu-item="item" :key="index"></main-menu>
</Menu>
main-menu:
<div>
<Submenu v-if="menuItem.children && menuItem.children.length" :name="menuItem.id || menuItem.name">
<template slot="title">
<Icon v-if="menuItem.icon" :type="menuItem.icon"></Icon>
{{ menuItem.title }}
</template>
<MainMenu v-for="(item, index) in menuItem.children" :menu-item="item" :key="index"></MainMenu>
</Submenu>
<!-- MenuItem name属性 绑定菜单对象的唯一值id -->
<MenuItem v-else :name="menuItem.id || menuItem.name">
<Icon v-if="menuItem.icon" :type="menuItem.icon"></Icon>
{{ menuItem.title }}
</MenuItem>
</div>
菜单树结构处理:
let menuMap = {}
// 功能: 1.过滤菜单对象中的某些属性 2.查找某个叶子节点的访问路径
function mappingMenus (menus, parent) {
if (Array.isArray(menus)) {
return menus.map((menu) => {
let node = {
id: menu.id,
path: menu.path,
name: menu.name,
title: menu.title,
// 保存所有父级菜单ID列表 形成一条菜单查找路径
parentIds: parent ? parent.parentIds.concat(parent.id) : []
}
// 非叶子节点处理
if (menu.children && menu.children.length) {
return {
...node,
children: this.mappingMenus(menu.children, node)
}
}
// 叶子节点处理 叶子节点菜单 ID->所有父级菜单 映射
menuMap[menu.id] = {
openNames: node.parentIds,
path: node.path
}
return node
})
}
return []
}
vue-router多次路由到某个组件,不复用,每次都创建一个新的组件
问题搜索关键字: Routing the same component, the component is not reload, but be reused
解决:在router-view上指定唯一key值
<router-view :key="$route.fullPath"></router-view>
注意,此处的router-view是用于导航组件的路由
参考链接 https://github.com/vuejs/vue-router/issues/1490
VUE
1. v-if & css内联样式同时使用 BUG
错误写法: <div v-if="condition" style="background:red;"></div>
报错: DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node
参考:https://github.com/vuejs/vue/issues/4535
2. 需要响应式的变量 必须放置到 data属性中 初始化