# 起因
由于文章的编辑是使用  title  和  content  两个响应式变量双向绑定着编辑区的输入框
变量:
1
let
1
<input id="input-title" placeholder="请输入标题" v-model="title" />
使用  articleId  作为当前浏览的文章,当监听到 articleId 的变化,则会通过网络请求更新   title  和  content  :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 监视articleId如有变化,重新渲染文章列表
watch(
  () => props.articleId,
  (articleId, prevArticleId) => {
    if (articleId == prevArticleId) {
      console.error('错误,watch新旧值相等了!')
    } else {
      // 使用axios 获取文章信息
      axios.get(`${server_url}/article/${props.articleId}`).then((results) => {
        // 将查询到的文章信息赋给title 和 content 两个响应性变量
        title.value = results.data[0].title
        content.value = results.data[0].content
        initEditor(results.data[0].content)
      })
    }
  }
)
所以当每次切换文章时,重新为编辑器填充的值就会触发  watch ,从而使得  saveArticle  方法被触发:
1
2
3
4// 监听tite 和 content
watch([title, content], ([newTitle, newContent]) => {
    saveArticle(props.articleId, title.value, content.value)
})
又因为  saveArticle  方法会向服务器发送修改请求,于是本该在内容被编辑时触发的请求却在切换文章时由于填充  title  和  content  时被触发,导致文章的修改时间被切换时覆盖。
# 解决方法
添加一个变量作为锁,锁住  saveArticle  的触发,并在触发后解锁,保证正常的编辑能够正常触发  saveArticle  ,在监听  articleId  的变化时 (组件通过监听  articleId  变化来确定当前浏览的文章更改 ),将锁开启,并在触发  title  和  content  之后将锁解锁,即可。
# 实现
定义锁
1
let contentUpdateLock = false
在 监听到  articleId 改变时  启动锁:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 监视articleId如有变化,重新渲染文章列表
watch(
  () => props.articleId,
  (articleId, prevArticleId) => {
    if (articleId == prevArticleId) {
      console.error('错误,watch新旧值相等了!')
    } else {
      // 使用axios 获取文章信息
      axios.get(`${server_url}/article/${props.articleId}`).then((results) => {
        // 将查询到的文章信息赋给title 和 content 两个响应性变量
        // 由articleId变化而产生的刷新,锁住
        contentUpdateLock = true
        title.value = results.data[0].title
        content.value = results.data[0].content
        initEditor(results.data[0].content)
      })
    }
  }
)
在 监听到 title  和  content  的变化时,根据锁的状态,拦截启动  saveArticle  函数,并且锁启动一次后自动销毁,这样就不会影响正常的编辑(监听 articleId 变化 => 锁激活 => 监听 title 和 content 变化 => 锁拦截调用 saveArticle => 锁自动销毁),而正常进行编辑时,只会 触发 title 和 content 的监听,不会改变 articleId,锁不会被激活,不会阻塞正常编辑的调用。
代码如下:
1
2
3
4
5
6
7
8
9// 监听 title 和 content
watch([title, content], ([newTitle, newContent]) => {
  // 如果被锁住,不可以触发储存方法
  if (!contentUpdateLock) {
    saveArticle(props.articleId, title.value, content.value)
  } else {
    contentUpdateLock = false // 触发后解锁,则不会影响正常使用
  }
})
