国际化配置更新

阅读论文保存当前滚动位置以及查找状态
master
pan 4 years ago
parent 0266d27d95
commit d1c492986a
  1. 6
      nuxt.config.js
  2. 3
      package.json
  3. 381
      pages/index/read.vue
  4. 4
      plugins/uuid.js
  5. 8
      store/read.js
  6. 18
      yarn.lock

@ -37,7 +37,7 @@ export default {
** Plugins to load before mounting the App ** Plugins to load before mounting the App
** https://nuxtjs.org/guide/plugins ** https://nuxtjs.org/guide/plugins
*/ */
plugins: ['@/plugins/element-ui','@/plugins/vue-cookies','@/plugins/global','@/plugins/moment','@/plugins/contextmenu'], plugins: ['@/plugins/element-ui','@/plugins/vue-cookies','@/plugins/global','@/plugins/moment','@/plugins/contextmenu','@/plugins/uuid'],
/* /*
** Auto import components ** Auto import components
** See https://nuxtjs.org/api/configuration-components ** See https://nuxtjs.org/api/configuration-components
@ -193,9 +193,10 @@ export default {
"add_tip_fail": "笔记添加失败", "add_tip_fail": "笔记添加失败",
"add_tip_ok": "笔记添加成功", "add_tip_ok": "笔记添加成功",
"auto_save": "失去焦点自动保存", "auto_save": "失去焦点自动保存",
"click_note_list": "选中内容定位笔记", "click_note_list": "单击卡片定位笔记",
"contextmenu_err": "请选中文本进行操作", "contextmenu_err": "请选中文本进行操作",
"del_confirm": "确认删除此笔记?", "del_confirm": "确认删除此笔记?",
"note_zero": "还没有任何笔记,尝试正文选中文本右击添加一个笔记吧!",
"rating_1": "本文对您的科研工作是否有帮助", "rating_1": "本文对您的科研工作是否有帮助",
"rating_2": "本文的内容是否科学严谨", "rating_2": "本文的内容是否科学严谨",
"rating_3": "您对本文的推荐程度", "rating_3": "您对本文的推荐程度",
@ -340,6 +341,7 @@ export default {
"click_note_list": "", "click_note_list": "",
"contextmenu_err": "", "contextmenu_err": "",
"del_confirm": "", "del_confirm": "",
"note_zero": "",
"rating_1": "", "rating_1": "",
"rating_2": "", "rating_2": "",
"rating_3": "", "rating_3": "",

@ -32,7 +32,8 @@
"nuxt-i18n": "^6.13.1", "nuxt-i18n": "^6.13.1",
"v-contextmenu": "^2.9.0", "v-contextmenu": "^2.9.0",
"vue-cookies": "^1.7.2", "vue-cookies": "^1.7.2",
"vue-runtime-helpers": "^1.1.2" "vue-runtime-helpers": "^1.1.2",
"vue-uuid": "^2.0.2"
}, },
"devDependencies": { "devDependencies": {
"@nuxt/typescript-build": "^1.0.3", "@nuxt/typescript-build": "^1.0.3",

@ -1,5 +1,5 @@
<template> <template>
<div > <div>
<v-contextmenu ref="contextmenu"> <v-contextmenu ref="contextmenu">
<v-contextmenu-item v-if="!disabled"> <v-contextmenu-item v-if="!disabled">
<el-popover <el-popover
@ -7,25 +7,29 @@
trigger="click" trigger="click"
@hide="resetNote" @hide="resetNote"
> >
<el-form ref="form" :model="note_form" :rules="rules" label-width="80px"> <el-form ref="form" :model="note_form" :rules="rules" label-width="80px">
<el-form-item :label="$t('note.table.original_text')" > <el-form-item :label="$t('note.table.original_text')">
<el-input autosize type="textarea" v-model="note_form.original_text" disabled></el-input> <el-input autosize type="textarea" v-model="note_form.original_text" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('read.form.note_title')" prop="note_title"> <el-form-item :label="$t('read.form.note_title')" prop="note_title">
<el-input v-model="note_form.note_title" :placeholder="$t('input_please', { keyword: this.$t('read.form.note_title') })"></el-input> <el-input v-model="note_form.note_title"
</el-form-item> :placeholder="$t('input_please', { keyword: this.$t('read.form.note_title') })"></el-input>
<el-form-item :label="$t('read.form.note_content')" prop="note_content"> </el-form-item>
<el-input autosize type="textarea" v-model="note_form.note_content" :placeholder="$t('input_please', { keyword: this.$t('read.form.note_content') })"></el-input> <el-form-item :label="$t('read.form.note_content')" prop="note_content">
</el-form-item> <el-input autosize type="textarea" v-model="note_form.note_content"
<el-form-item> :placeholder="$t('input_please', { keyword: this.$t('read.form.note_content') })"></el-input>
<el-button @click="addNote">{{$t('button.add')}}</el-button> </el-form-item>
<el-button @click="visible=false">{{$t('button.cancel')}}</el-button> <el-form-item>
</el-form-item> <el-button @click="addNote">{{$t('button.add')}}</el-button>
</el-form> <el-button @click="visible=false">{{$t('button.cancel')}}</el-button>
</el-form-item>
</el-form>
<el-button slot="reference">{{$t('read.contextmenu.add')}}</el-button> <el-button slot="reference">{{$t('read.contextmenu.add')}}</el-button>
</el-popover> </el-popover>
</v-contextmenu-item> </v-contextmenu-item>
<v-contextmenu-item><el-button @click="showSearch=true;queryContent()" class="w-100">{{$t('read.contextmenu.search')}}</el-button></v-contextmenu-item> <v-contextmenu-item>
<el-button @click="updateFind(true);queryContent()" class="w-100">{{$t('read.contextmenu.search')}}</el-button>
</v-contextmenu-item>
</v-contextmenu> </v-contextmenu>
<el-tabs v-model="activeName" type="card" closable @tab-remove="removeTab"> <el-tabs v-model="activeName" type="card" closable @tab-remove="removeTab">
<el-tab-pane :label="key" :name="key" v-for="(item,key) in openList" :key="key"> <el-tab-pane :label="key" :name="key" v-for="(item,key) in openList" :key="key">
@ -33,59 +37,71 @@
<el-col :span="18"> <el-col :span="18">
<el-form :inline="true" v-if="showSearch"> <el-form :inline="true" v-if="showSearch">
<el-form-item :label="$t('read.form.keyword')"> <el-form-item :label="$t('read.form.keyword')">
<el-input @input="queryContent" :placeholder="$t('input_please',{keyword:$t('read.form.keyword')})" v-model="search_form.keyword" <el-input @input="queryContent" :placeholder="$t('input_please',{keyword:$t('read.form.keyword')})"
maxlength="10" v-model="search_form.keyword"
show-word-limit> maxlength="10"
<i slot="prefix" class="el-input__icon el-icon-search"></i> show-word-limit>
</el-input> <i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
</el-form-item> </el-form-item>
<template v-if="num>0"> <template v-if="num>0">
<el-form-item>{{search_index+1+'/'+num}}</el-form-item> <el-form-item>{{search_index+1+'/'+num}}</el-form-item>
<el-tooltip :content="$t('read.tip.search_prev')"> <el-tooltip :content="$t('read.tip.search_prev')">
<el-image src="/prev.svg" class="img" @click="search_index>0?search_index--:search_index=num-1;change_search_index()"></el-image> <el-image src="/prev.svg" class="img"
@click="search_index>0?search_index--:search_index=num-1;change_search_index()"></el-image>
</el-tooltip> </el-tooltip>
<el-tooltip :content="$t('read.tip.search_next')"> <el-tooltip :content="$t('read.tip.search_next')">
<el-image src="/next.svg" class="img" @click="search_index<num-1?search_index++:search_index=0;change_search_index()"></el-image> <el-image src="/next.svg" class="img"
@click="search_index<num-1?search_index++:search_index=0;change_search_index()"></el-image>
</el-tooltip> </el-tooltip>
</template> </template>
</el-form> </el-form>
<pre class="content" v-contextmenu:contextmenu :ref="'edit'+item.title" @mouseup="show" <pre class="content" v-contextmenu:contextmenu :ref="'edit'+item.title" @mouseup="show"
@contextmenu="selectText" v-html="item.content" @contextmenu="selectText" @scroll="scrollContent" v-html="item.content"
/> />
</el-col> </el-col>
<el-col :span="5" class="ml3 note-list"> <el-col :span="5" class="ml3 note-list">
<el-row v-for="(item,index) in noteList" :key="index" class="mb2"> <template v-if="noteList.length>0">
<el-card> <el-row v-for="(item,index) in noteList" :key="index" class="mb2">
<div slot="header" class="clearfix"> <el-tooltip :content="$t('read.tip.click_note_list')" :disabled="item.isEdit">
<el-row type="flex" justify="space-around"> <el-card>
<span>{{item.title}}</span> <div slot="header" class="clearfix">
<el-button-group> <el-row type="flex" justify="space-around">
<el-button size="mini" type="primary" @click="edit(item)" icon="el-icon-edit"></el-button> <span>{{item.title}}</span>
<el-popconfirm <el-button-group>
@onConfirm="del(item,index)" <el-button size="mini" type="primary" @click="edit(item)" icon="el-icon-edit"></el-button>
:title="$t('read.tip.del_confirm')" <el-popconfirm
> @onConfirm="del(item,index)"
<el-button size="mini" type="danger" slot="reference" icon="el-icon-delete"></el-button> :title="$t('read.tip.del_confirm')"
</el-popconfirm> >
</el-button-group> <el-button size="mini" type="danger" slot="reference" icon="el-icon-delete"></el-button>
</el-row> </el-popconfirm>
</div> </el-button-group>
<div class="text item" @click="jump(item)" @mouseover="highlighting(item)" </el-row>
@mouseout="reset(item)"> </div>
<transition v-if="item.isEdit" @after-leave="save(item)">
<el-tooltip class="item" effect="dark" :content="$t('read.tip.auto_save')" v-model="item.isEdit"> <div class="text item" @click="jump(item)" @mouseover="highlighting(item)"
<el-input autosize type="textarea" v-model="item.content"></el-input> @mouseout="reset(item)">
</el-tooltip> <transition v-if="item.isEdit" @after-leave="save(item)">
</transition> <el-tooltip class="item" effect="dark" :content="$t('read.tip.auto_save')"
<template v-else><pre style="background-color: white">{{item.content}}</pre></template> v-model="item.isEdit">
</div> <el-input autosize type="textarea" v-model="item.content"></el-input>
</el-card> </el-tooltip>
<el-alert v-if="item.message" </transition>
@close="item.message=null;item.type=null" <template v-else>
:title="item.message" <pre style="background-color: white">{{item.content}}</pre>
:type="item.type"> </template>
</el-alert> </div>
</el-row> </el-card>
</el-tooltip>
<el-alert v-if="item.message"
@close="item.message=null;item.type=null"
:title="item.message"
:type="item.type">
</el-alert>
</el-row>
</template>
<h1 v-else>{{$t('read.tip.note_zero')}}</h1>
</el-col> </el-col>
</el-row> </el-row>
</el-tab-pane> </el-tab-pane>
@ -119,34 +135,36 @@
export default Vue.extend({ export default Vue.extend({
name: 'read', name: 'read',
layout: 'my-pre',
data() { data() {
return { return {
// //
showSearch:false, showSearch: false,
// //
visible: false, visible: false,
// //
search_form:{ search_form: {
keyword:'' keyword: ''
}, },
// //
num:0, num: 0,
// //
search_index:-1, search_index: -1,
// //
note_form:{ note_form: {
note_title:'', note_id: '',
note_content:'', note_title: '',
original_text:'' note_content: '',
original_text: ''
}, },
// //
rules:{ rules: {
note_title:[{ note_title: [{
required: true, required: true,
message: this.$t('input_please', { keyword: this.$t('read.form.note_title') }), message: this.$t('input_please', { keyword: this.$t('read.form.note_title') }),
trigger: 'blur' trigger: 'blur'
}], }],
note_content:[{ note_content: [{
required: true, required: true,
message: this.$t('input_please', { keyword: this.$t('read.form.note_content') }), message: this.$t('input_please', { keyword: this.$t('read.form.note_content') }),
trigger: 'blur' trigger: 'blur'
@ -168,71 +186,118 @@
// //
openList() { openList() {
return this.$store.state.read.read return this.$store.state.read.read
},
//
pre() {
return this.$refs['edit' + this.activeName][0]
},
//
activeContent() {
return this.$store.state.read.read[this.activeName]
} }
}, },
watch: { watch: {
// //
activeName(newVal) { activeName(newVal) {
this.$store.commit('read/choose', newVal) this.$store.commit('read/choose', newVal)
this.doScroll()
if (this.activeContent.find && this.activeContent.find.showSearch) {
this.showSearch = this.activeContent.find.showSearch
this.search_form.keyword = this.activeContent.find.keyword
let search_index = this.activeContent.find.search_index
this.queryContent()
this.search_index = search_index
this.change_search_index()
} else {
this.showSearch = false
this.search_form = {
keyword: ''
}
this.num = 0
this.search_index = -1
}
}, },
showSearch(newVal){ showSearch(newVal) {
if(!newVal){ if (!newVal) {
let pre:HTMLElement=this.$refs['edit'+this.$store.state.read.activeName][0] let pre: HTMLElement = this.pre
this.search_form.keyword='' this.search_form.keyword = ''
this.resetQuery(pre) this.resetQuery(pre)
} }
} }
}, },
methods: { methods: {
//
scrollContent(e) {
this.$store.commit('read/scroll', e.target.scrollTop)
},
doScroll() {
this.$nextTick(() => {
if (this.activeContent.scrollTop) {
this.pre.scrollTo({
top: this.activeContent.scrollTop
})
}
})
},
// //
change_search_index(){ change_search_index() {
let ele=document.getElementsByClassName('search-light')[this.search_index] let ele = this.pre.querySelectorAll('span[class^=search-light]')[this.search_index]
ele.classList.add('choose-search-text') ele.classList.add('choose-search-text')
ele.scrollIntoView({ ele.scrollIntoView({
block: 'center' block: 'center'
}) })
for(let index=0;index<this.num;index++){ for (let index = 0; index < this.num; index++) {
if(index!==this.search_index){ if (index !== this.search_index) {
document.getElementsByClassName('search-light')[index].classList.remove('choose-search-text') this.pre.querySelectorAll('span[class^=search-light]')[index].classList.remove('choose-search-text')
} }
} }
this.updateFind(this.showSearch)
},
updateFind(showSearch = false) {
this.showSearch = showSearch
this.$store.commit('read/find', {
showSearch: showSearch,
keyword: this.search_form.keyword,
search_index: this.search_index
})
}, },
// //
resetQuery(pre:HTMLElement){ resetQuery(pre: HTMLElement) {
for(let span of pre.querySelectorAll('span[class^=search-light]')){ for (let span of pre.querySelectorAll('span[class^=search-light]')) {
let text=document.createTextNode(span.innerText) let text = document.createTextNode(span.innerText)
span.replaceWith(text) span.replaceWith(text)
} }
pre.normalize() pre.normalize()
this.num=0 this.num = 0
this.search_index=-1 this.search_index = -1
}, },
// //
queryContent(){ queryContent() {
let pre:HTMLElement=this.$refs['edit'+this.$store.state.read.activeName][0] let pre: HTMLElement = this.pre
this.resetQuery(pre) this.resetQuery(pre)
if(this.search_form.keyword.length===0){ if (this.search_form.keyword.length === 0) {
let selection=getSelection() let selection = getSelection()
if(selection&&selection.toString().length>0){ if (selection && selection.toString().length > 0) {
this.search_form.keyword=selection.toString() this.search_form.keyword = selection.toString()
}else{ } else {
return return
} }
} }
let replaceObj=[] let replaceObj = []
for(let node of pre.childNodes) { for (let node of pre.childNodes) {
let content=node.nodeType===3?node.data:node.innerText let content = node.nodeType === 3 ? node.data : node.innerText
let matchAll = content.matchAll(new RegExp(this.search_form.keyword, 'g')) let matchAll = content.matchAll(new RegExp(this.search_form.keyword, 'g'))
let replaceNodes=[] let replaceNodes = []
if(node.nodeType===1&&node.innerText.length===this.search_form.keyword.length) { if (node.nodeType === 1 && node.innerText.length === this.search_form.keyword.length) {
node.classList.add('search-light') node.classList.add('search-light')
}else{ } else {
let length = 0 let length = 0
let prev let prev
for (let match of matchAll) { for (let match of matchAll) {
this.num+=1 this.num += 1
let start = document.createTextNode(content.substr(prev ? prev : 0, match.index - length)) let start = document.createTextNode(content.substr(prev ? prev : 0, match.index - length))
let span = document.createElement('span') let span = document.createElement('span')
span.classList.add('search-light') span.classList.add('search-light')
@ -241,7 +306,7 @@
replaceNodes.push(start, span) replaceNodes.push(start, span)
length += start.data.length + this.search_form.keyword.length length += start.data.length + this.search_form.keyword.length
} }
if(length>0){ if (length > 0) {
replaceNodes.push(document.createTextNode(content.substr(prev))) replaceNodes.push(document.createTextNode(content.substr(prev)))
replaceObj.push({ replaceObj.push({
source: node, source: node,
@ -251,29 +316,29 @@
} }
} }
for(let item of replaceObj){ for (let item of replaceObj) {
let node=item.source let node = item.source
let replaceNodes=item.target let replaceNodes = item.target
if(replaceNodes.length>0) { if (replaceNodes.length > 0) {
if(node.nodeType===3) { if (node.nodeType === 3) {
node.replaceWith(replaceNodes[0]) node.replaceWith(replaceNodes[0])
for (let index = 1; index < replaceNodes.length; index++) { for (let index = 1; index < replaceNodes.length; index++) {
replaceNodes[index - 1].after(replaceNodes[index]) replaceNodes[index - 1].after(replaceNodes[index])
} }
}else{ } else {
node.innerHTML='' node.innerHTML = ''
for(let child of replaceNodes){ for (let child of replaceNodes) {
node.appendChild(child) node.appendChild(child)
} }
} }
} }
} }
if(this.num>0) { if (this.num > 0) {
this.search_index=0 this.search_index = 0
this.change_search_index() this.change_search_index()
}else{ } else {
this.$message.warning({ this.$message.warning({
message: this.$t('read.tip.search_zero',{keyword:this.search_form.keyword}).toString(), message: this.$t('read.tip.search_zero', { keyword: this.search_form.keyword }).toString(),
showClose: true, showClose: true,
duration: 2000 duration: 2000
}) })
@ -293,10 +358,10 @@
this.$set(item, 'message', '保存成功') this.$set(item, 'message', '保存成功')
}, },
// //
del(item: any,index:number) { del(item: any, index: number) {
this.$set(item, 'type', 'success') this.$set(item, 'type', 'success')
this.$set(item, 'message', '删除成功') this.$set(item, 'message', '删除成功')
this.noteList.splice(index,1) this.noteList.splice(index, 1)
}, },
// //
submitRating() { submitRating() {
@ -323,6 +388,8 @@
block: 'center' block: 'center'
}) })
} }
this.highlighting(item)
}, },
// //
show() { show() {
@ -342,26 +409,27 @@
} }
this.activeName = this.$store.state.read.activeName this.activeName = this.$store.state.read.activeName
}, },
resetNote(){ resetNote() {
this.replace = {} this.replace = {}
this.note_form.note_title='' this.note_form.note_id = ''
this.note_form.note_content='' this.note_form.note_title = ''
this.note_form.original_text='' this.note_form.note_content = ''
this.note_form.original_text = ''
}, },
// //
addNote() { addNote() {
let that=this let that = this
this.$refs.form.validate((valid: boolean)=>{ this.$refs.form.validate((valid: boolean) => {
if (valid&&Object.keys(that.replace.replaceVal).length>0) { if (valid && Object.keys(that.replace.replaceVal).length > 0) {
let id=new Date().getTime() let id = new Date().getTime()
let c=document.createElement('span') let c = document.createElement('span')
c.setAttribute('id',id.toString()) c.setAttribute('id', id.toString())
that.replace.val.replaceWith(that.replace.replaceVal[0]) that.replace.val.replaceWith(that.replace.replaceVal[0])
for (let index =1;index<that.replace.replaceVal.length;index++) { for (let index = 1; index < that.replace.replaceVal.length; index++) {
that.replace.replaceVal[index-1].after(that.replace.replaceVal[index]) that.replace.replaceVal[index - 1].after(that.replace.replaceVal[index])
} }
that.noteList.unshift({ that.noteList.unshift({
id: `fuck${(Math.random()*10).toFixed()}`, id: this.note_form.note_id,
title: this.note_form.note_title, title: this.note_form.note_title,
content: this.note_form.note_content content: this.note_form.note_content
}) })
@ -376,9 +444,9 @@
showClose: true, showClose: true,
duration: 1000 duration: 1000
}) })
return false; return false
} }
this.visible=false this.visible = false
}) })
}, },
@ -394,10 +462,12 @@
let anchorNode = range.startContainer let anchorNode = range.startContainer
let bold = document.createElement('span') let bold = document.createElement('span')
bold.classList.add('bold') bold.classList.add('bold')
this.note_form.note_id = this.$uuid.v1()
bold.setAttribute('id', this.note_form.note_id)
if (range.endOffset - range.startOffset === anchorNode.length) { if (range.endOffset - range.startOffset === anchorNode.length) {
console.info(tip + '全选') console.info(tip + '全选')
bold.innerText = anchorNode.wholeText bold.innerText = anchorNode.wholeText
this.replace={ this.replace = {
val: anchorNode, val: anchorNode,
replaceVal: [bold] replaceVal: [bold]
} }
@ -406,12 +476,12 @@
let start = document.createTextNode(anchorNode.substringData(0, range.startOffset)) let start = document.createTextNode(anchorNode.substringData(0, range.startOffset))
let end = document.createTextNode(anchorNode.substringData(range.endOffset, anchorNode.length)) let end = document.createTextNode(anchorNode.substringData(range.endOffset, anchorNode.length))
bold.innerText = anchorNode.substringData(range.startOffset, range.endOffset - range.startOffset) bold.innerText = anchorNode.substringData(range.startOffset, range.endOffset - range.startOffset)
this.replace={ this.replace = {
val: anchorNode, val: anchorNode,
replaceVal: [start,bold,end] replaceVal: [start, bold, end]
} }
} }
this.note_form.original_text=bold.innerText this.note_form.original_text = bold.innerText
} else { } else {
let tip = '跨节点' let tip = '跨节点'
let startNode = range.startContainer let startNode = range.startContainer
@ -424,26 +494,20 @@
}, },
mounted() { mounted() {
this.activeName = this.$store.state.read.activeName this.activeName = this.$store.state.read.activeName
for (let n = 0; n < 10; n++) {
this.noteList.push({
id: `fuck${n}`,
title: `笔记${n}`,
content: `内容${n}`
})
}
let that=this let that = this
addEventListener('keyup',function(event) { addEventListener('keyup', function(event) {
// //
if(event.shiftKey&&'F'===event.key.toUpperCase()){ if (event.shiftKey && 'F' === event.key.toUpperCase()) {
event.preventDefault(); event.preventDefault()
that.showSearch=!that.showSearch that.showSearch = !that.showSearch
}else if('ESCAPE'===event.key.toUpperCase()){ } else if ('ESCAPE' === event.key.toUpperCase()) {
that.showSearch=false that.showSearch = false
} }
that.updateFind(that.showSearch)
},true) }, true)
} }
}) })
</script> </script>
<style> <style>
@ -452,17 +516,24 @@
font-size: larger; font-size: larger;
} }
.search-light{ .search-light {
color:blue; color: blue;
} }
.choose-search-text { .choose-search-text {
animation: changeshadow 1s ease-in infinite ; animation: changeshadow 1s ease-in infinite;
} }
@keyframes changeshadow { @keyframes changeshadow {
0%{ text-shadow: 0 0 4px blue} 0% {
50%{ text-shadow: 0 0 40px blue} text-shadow: 0 0 4px blue
100%{ text-shadow: 0 0 4px blue} }
50% {
text-shadow: 0 0 40px blue
}
100% {
text-shadow: 0 0 4px blue
}
} }
.choose-note { .choose-note {
@ -513,11 +584,11 @@
width: 100%; width: 100%;
} }
.el-input.el-input--prefix>input[type='text'] { .el-input.el-input--prefix > input[type='text'] {
height: 40px; height: 40px;
} }
.img{ .img {
height: 30px; height: 30px;
width: 30px; width: 30px;
vertical-align: text-top; vertical-align: text-top;

@ -0,0 +1,4 @@
import Vue from 'vue'
import UUID from 'vue-uuid'
Vue.use(UUID)

@ -29,5 +29,13 @@ export const mutations = {
//选择论文标签 //选择论文标签
choose(state,title=Object.keys(state.read)[Object.keys(state.read).length-1]){ choose(state,title=Object.keys(state.read)[Object.keys(state.read).length-1]){
state.activeName=title state.activeName=title
},
//滚动正文
scroll(state,scrollTop){
state.read[state.activeName].scrollTop=scrollTop
},
//查找状态
find(state,item){
state.read[state.activeName].find=item
} }
} }

@ -1710,6 +1710,11 @@
resolved "https://registry.npm.taobao.org/@types/unist/download/@types/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" resolved "https://registry.npm.taobao.org/@types/unist/download/@types/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
integrity sha1-nAiGeYdvN061mD8VDUeHqm+zLX4= integrity sha1-nAiGeYdvN061mD8VDUeHqm+zLX4=
"@types/uuid@^8.0.0":
version "8.0.0"
resolved "https://registry.npm.taobao.org/@types/uuid/download/@types/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0"
integrity sha1-FlquSBmtIXShdHbb5m/uvVSVVsA=
"@types/webpack-bundle-analyzer@^3.8.0": "@types/webpack-bundle-analyzer@^3.8.0":
version "3.8.0" version "3.8.0"
resolved "https://registry.npm.taobao.org/@types/webpack-bundle-analyzer/download/@types/webpack-bundle-analyzer-3.8.0.tgz?cache=0&sync_timestamp=1590133772527&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fwebpack-bundle-analyzer%2Fdownload%2F%40types%2Fwebpack-bundle-analyzer-3.8.0.tgz#d1f196f95159254f76a3c2283c4677585bdf354d" resolved "https://registry.npm.taobao.org/@types/webpack-bundle-analyzer/download/@types/webpack-bundle-analyzer-3.8.0.tgz?cache=0&sync_timestamp=1590133772527&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fwebpack-bundle-analyzer%2Fdownload%2F%40types%2Fwebpack-bundle-analyzer-3.8.0.tgz#d1f196f95159254f76a3c2283c4677585bdf354d"
@ -10334,6 +10339,11 @@ uuid@^3.3.2:
resolved "https://registry.npm.taobao.org/uuid/download/uuid-3.4.0.tgz?cache=0&sync_timestamp=1592944143460&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" resolved "https://registry.npm.taobao.org/uuid/download/uuid-3.4.0.tgz?cache=0&sync_timestamp=1592944143460&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4= integrity sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=
uuid@^8.1.0:
version "8.3.0"
resolved "https://registry.npm.taobao.org/uuid/download/uuid-8.3.0.tgz?cache=0&sync_timestamp=1595885088251&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea"
integrity sha1-q3OAhcoi3JqMknJeRZsdUH311uo=
v-contextmenu@^2.9.0: v-contextmenu@^2.9.0:
version "2.9.0" version "2.9.0"
resolved "https://registry.npm.taobao.org/v-contextmenu/download/v-contextmenu-2.9.0.tgz#1753a7afc42051f1ed5cb75c20498a16fd7ec332" resolved "https://registry.npm.taobao.org/v-contextmenu/download/v-contextmenu-2.9.0.tgz#1753a7afc42051f1ed5cb75c20498a16fd7ec332"
@ -10491,6 +10501,14 @@ vue-template-es2015-compiler@^1.9.0:
resolved "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" resolved "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
integrity sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU= integrity sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=
vue-uuid@^2.0.2:
version "2.0.2"
resolved "https://registry.npm.taobao.org/vue-uuid/download/vue-uuid-2.0.2.tgz#0cfb739e660a3af1d4e3342743578114f79b2438"
integrity sha1-DPtznmYKOvHU4zQnQ1eBFPebJDg=
dependencies:
"@types/uuid" "^8.0.0"
uuid "^8.1.0"
vue@^2.6.11: vue@^2.6.11:
version "2.6.11" version "2.6.11"
resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"

Loading…
Cancel
Save