Open FrankFang opened 7 years ago
1、 现在你在页面左边修改 resume,会发现 ResumePreview 不会自动更新,你该怎么办呢?
解决方法:在ResumeEditor.vue 文件中第二十行代码 <input type="text" :value="value" >
加 v-model="subitem[key]"
让input双向绑定数据即可:
<div class="resumeField" v-for="(value,key) in subitem">
<label >{{key}}</label>
<input type="text" :value="value" > //此处未双向绑定数据
</div>
2、在多个文件 import vue,会怎样? 这个不是很清楚,老师可以给我们讲讲哦~
3、为什么要写 white-space: pre-line;
white-space: pre-line的作用是合并空白符序列,但是保留换行符、<br>
及填充line盒子时也会换行。
我们这里不加的话, a、 1.既定产品需求; 2.修复 bug
就不会换行了。
b、在input填写时,如果填写多个空格也会在全部显示出来,导致页面显示很难看。
LC
预览 1.对编辑组件内的数组类型的数据的input控件改成model指令绑定 v-model="subitem[key]" 2.在同一个js文件中引入两个会报错(Duplicate declaration),在store的index.js中不引入vue会报错,你们说的缓存是什么情况,难道只有我报错嘛。。。 3.主要是为了文字换行,white-space: pre-line和white-space: pre-wrap都会换行,查了下区别pre-line是对空白符合并,而pre-wrap不会对空白符合并;
1.在非严格模式下:
将写为双向绑定即可
<input type="text" :value="value" @input="resume[item.field][key] = $event.target.value">
2.在严格模式下:
const store = new Vuex.Store({
// ...
strict: true
})
用之前的方法会报错,那么用『Vuex 的思维』去解决这个问题的方法是:给 中绑定 value,然后侦听 input 或者 change 事件,在事件回调中调用 action。代码还未实现,有些不熟练😂
最近在写react的时候,所有子组件中都要写 import React from 'react'
,直觉告诉我webpack不傻,引用多次肯定不会多次打包,但我在网上没有搜到让我信服的理由。于是自己做了个实验
目录结构:
//demo.js--相当于vue
export default {
test(argu) {
console.log(argu)
}
}
//test1.js --相当于某个组件
import demo from './demo'
export default {
test1() {
demo.test(1)
}
}
//test2.js --相当于另一个组件
import demo from './demo'
export default {
test1() {
demo.test(2)
}
}
//add.js --入口文件
import Test1 from './test1'
import Test2 from './test2'
Test1.test1()
Test2.test2()
我在test1.js
,test2.js
中都引入demo.js
,并且exoprt 出依赖demo.js
的方法,然后再在app.js
中引入test1.js
,test2.js
webpack打包后打开bundle.js
,找到demo部分
发现demo只被引入了一次。
所以得出结论,多次import同一个文件,webpack并不会多次打包,只会在打包后的文件中会多次引用打包文件后的对象。
合并空白符序列,但是保留换行符。
1.在非严格模式下:
将写为双向绑定即可
<input type="text" :value="value" @input="resume[item.field][key] = $event.target.value">
2.在严格模式下:
const store = new Vuex.Store({
// ...
strict: true
})
用之前的方法会报错,为什么会报错? 因为在严格模式下,Vuex的状态不允许在mutation 处理器以外的地方被修改!
那么用『Vuex 的思维』去解决这个问题的方法是:
1.给 中绑定事件,并传递相应的参数,在事件中将相应参数commit
到Vuex.store
下的Mutation中
2.在./store/index.js
中注册一个响应input事件的Mutation
处理器,将得到的payload
更新到state.resume
commit : 严格模式下实现ResumePreview自动更新
1.不会自动更新,是因为input的更新的值没有绑定到state上,双向绑定即可。 2.本项目是在两个文件内import vue,从打包后的源码来看, webpack类似对引入的构造函数进行编号,例如:webpack_require(0)、webpack_require(1)、···,只是多次调用这些打包后对应的函数,并没有重复打包。 在同一文件多次引入同一个文件,会报错“Duplicate declaration “filename””。 3.连续的空白符会被合并。保留换行符。input输入一大段文字,显示在对应的p标签。p标签默认样式是不换行的,但是如果用户强制换行,只会产生空格,故而修改p标签默认样式,在用户需要换行时换行。 预览
在editer中双向绑定input即可
<div class="resumeField" v-for="(value,key) in subitem">
<label>{{key}}</label>
<input type="text" v-model="subitem[key]">
</div>
import 的意思本身就有,不会重复引入,这一点跟include不同
#ifinclude xxx
#endif
white-space: pre-line是对行首空格的处理,表示无效行首空格,对应的还有 pre-wrap(保留空格)
问题一: 在页面左边修改 resume,会发现 ResumePreview 不会自动更新,你该怎么办呢
修改input为双向绑定:
原来的:<input type="text" :value="value" >
修改后的:<input type="text" :value="value" @input="subitem[key] = $event.target.value">
问题二:多次 import 同一个文件会怎么样? webpack不会重复打包多次import的重复模块,webpack 在处理依赖关系的时候,会给模块分配个 id,同一模块只会写入打包文件一次。
问题三:white-space: pre-line
的作用?
多个空格会合并,换行会保留,帮助用户去掉输入过程中连续输入的空格
问题1
<div class="resumeField" v-for="(value,key) in subitem">
<label>{{key}}</label>
<input type="text" v-model="subitem[key]">
//将input设置为双向绑定
</div>
或(v-model就是下面的语法糖,双向绑定 = 单向绑定 + UI 事件监听)
<div class="resumeField" v-for="(value,key) in subitem">
<label>{{key}}</label>
<input type="text" :value="value" @input="subitem[key] = $event.target.value">
//将input设置为双向绑定
</div>
问题2: 多次import同一个文件,会提示‘Duplicate declaration “filename’的错误
问题3: 会合并连续的空格,换行会保留
Q:现在你在页面左边修改 resume,会发现 ResumePreview 不会自动更新,你该怎么办呢?
A:在ResumeEditor.vue
18行的 input
添加 v-model
指令在表单控件上使用双向绑定,<input type="text" :value="value" v-model="subitem[key]">
Q:多次 import
同一个文件,会怎样?
A:Module build failed: Duplicate declaration "xxxx"
Q:为什么要写 white-space: pre-line;
A:white-space: pre-line;
// 合并空白符序列,但是保留换行符。花括号外面要用 ` 小撇,不能不引号
`{ '学习' }`
现在你在页面左边修改 resume,会发现 ResumePreview 不会自动更新,你该怎么办呢?
在ResumeEditor中的<input type="text" :value="value">
中加上双向绑定v-model,改写成<input type="text" :value="value" v-model="subitem[key]">
Q: 多次 import 同一个文件,会怎样?
A: 会报错:Module build failed;webpack不会重复打包,重复的话,只会引入已经打包好的参考
Q: 为什么要写 white-space: pre-line
;
A: 合并空白符序列,但是保留换行符。
现在你在页面左边修改 resume,会发现 ResumePreview 不会自动更新,你该怎么办呢? 在ResumeEditor中的中改为单项绑定并且事件监听
<input type="text" :value="value" @input="subitem[key] = $event.target.value">
<input type="text" :value="value" @input="resume[item.field][key] = $event.target.value">
Q: 多次 import 同一个文件,会怎样? A: 报错:Module build failed;重复打包的时候,只会引入已经打包好的 Q: 为什么要写 white-space: pre-line; A: 合并连续的空格,保留换行
一、现在你在页面左边修改 resume,会发现 ResumePreview 不会自动更新,你该怎么办呢?
根据:Vuex文档中"表单验证“中的方法:给 input 中绑定 value,然后侦听 input 或者 change 事件,在事件回调中调用 action:
commit: 自动更新ResumePreview
二、
源码
预览
三、
多次 import 同一个文件,会怎样?
A:不同文件中多次import同一个文件,webpack不会多次打包,只会多次引用打包后的该文件对应的函数
为什么要写 white-space: pre-line;
A:连续的空白符会被合并。在遇到换行符或者
元素时会换行;帮助用户去掉输入过程中连续输入的空格
问题: 1.在页面左边修改 resume,会发现 ResumePreview 不会自动更新,该怎么办呢?
<div class="resumeField" v-for="(value,key) in subitem">
<label>{{key}}</label>
<input type="text" v-model="subitem[key]"> //将input设置为双向绑定
</div>
或(v-model就是下面的语法糖,双向绑定 = 单向绑定 + UI 事件监听):
<div class="resumeField" v-for="(value,key) in subitem">
<label>{{key}}</label>
<input type="text" :value="value" @input="subitem[key] = $event.target.value"> //将input设置为双向绑定
</div>
2.多次 import 同一个文件,会怎样? 多次 import 同一个文件会报错:Module build failed;webpack不会重复打包,重复的话,只会引入已经打包好的。
3.为什么要写 white-space: pre-line? 会合并连续的空格,原有的换行会保留。
将v-bind改成v-model双向绑定
<div class="resumeField"v-for="(value,key) in subitem">
1.多次import同一个文件会怎样,webpack不会打包多次,只会引入已经打包好的。 2.white-space 属性设置如何处理元素内的空白。pre-line合并空白符序列,但是保留换行符。
1,现在你在页面左边修改 resume,会发现 ResumePreview 不会自动更新,你该怎么办呢? 单向绑定+事件绑定
<input type="text" :value="value" @input="subitem[key] = $event.target.value">
<input type="text" :value="value" @input="resume[item.field][key]= $event.target.value" >
2,实现上面的效果,回复在下面(源码+预览) 源码 预览 3,回答代码里的问题(不会就搜): 3.1多次 import 同一个文件,会怎样? 会报错 3.2为什么要写 white-space: pre-line white-space 属性设置如何处理元素内的空白。pre-line合并空白符序列,但是保留换行符
接下来我们来做预览功能。
首先想一个问题:
当然是从 ResumeEditor 来,对吧。
方案一:
那么最傻的办法就是在 ResumePreview 里面去读 ResumeEditor 的 data。
这种办法可以是可以,但是有一个「耦合性」太高的问题。
假设 ResumePreview 代码是这样的:
你会发现,ResumePreview 严重依赖 ResumeEditor,换句话说,ResumePreview 必须和 ResumeEditor 在一起,ResumePreview 不能从其他的地方读入 resume 数据。
这样的代码就很不优雅。
方案二:
讲数据抽离出来。我们能不能把 resume 的数据独立出来,专门供 ResumeEditor、ResumePreview 甚至其他组件来使用呢?可以。大概思路是这样:
这样一来,ResumeEditor 和 ResumePreview 互不干涉,只是数据来自同一个地方。
ResumeEditor 改了 resume 之后,由于 ResumePreview 用的是同一个 resume,所以立马就知道 resume 变化了(Vue.js 可以监听任意一个对象的变化)。
Vuex
全局数据源
基于方案二,我们再进一步想,为什么不把所有的数据都交给 globalData 来控制呢?
上文中 ResumeEditor 的 selected 属性没有交给 globalData 管理,万一另一个组件要用这个 selected 呢?所以我们还不如把所有的数据都交给 globalData 来控制。
这样,globalData 就叫做全局数据源,管理所有的数据。
双向绑定 V.S. 单向绑定
前面我们学过,可以用 Vue.js 添加双向绑定:
实际上,双向绑定不是魔法,上面的代码基本等价于
也就是说:
通过这个 JSBin 你应该可以理解这一点。
那么 Vuex 为什么要推荐单向绑定呢?
为了「控制欲」。
双向绑定是很方便,因为 data 和页面内容是自动同步的。
但是成也萧何败萧何。正是因为这个「自动同步」,所以有些人不喜欢双向绑定。「自动同步」意味着你不知道 data 什么时候就变了(when),也不知道是谁变的(who),变成了什么也不通知你(what)。
当然你可以加一个 watch 来监听 data 的变化。但这就显得很复杂了。
单向绑定牺牲一部分的便捷性,换来更大的「控制力」。
单向绑定大概的思路就是:
data -> 页面
单向绑定)你会发现单向绑定的思路其实也有双向绑定的意味,只不过重点在于「不是自动的」。
单向绑定还有其他优点,请看这个知乎问答。
使用 Vuex
Vuex 就是单向数据绑定的践行者之一了。
你需要先过一遍 Vuex 的文档,来了解 Vuex。你需要:
如果不通读 Vuex 文档,并运行其中的例子,之后的代码你肯定无法理解!
通读文档非常重要!我讲得再多也没文档讲得清楚。
引入 Vuex
首先我们要把 Vuex 文档里最简单的例子运行在我们的页面里:
改写 data
我们把 selected 和 resume 移到 store 里会发现 tab 无法切换了。
这是因为默认 computed 只能用于读数据,如果你还想写数据,就要用到 Vue 的 setter / getter 功能 了。
如果你想知道如何实现 setter 和 getter,就看 MDN 的文档
ResumeEditor 和 ResumePreview 使用同一个 store
你可以看到我们的 store 是放到
<App />
上的,所以所有组件都可以使用this.$store
来访问到它。(为什么要以 $ 开头?Vue 习惯如此,所有全局的东西都用 $ 开头,跟 jQuery 无关)那么我们来试试在 ResumePreview 里访问 resume 数据。
这个时候你刷新页面,就能在 ResumePreview 里面看到 resume 啦。
接下来我们让 ResumePreview 变得完整点、好看点:
好了,我们完成了 ResumePreview 并且引入了 Vuex。
致饥人谷学员
请依次回答上面三个问题。
我的预览的:https://jirengu-inc.github.io/jrg-project-5/step-8-resumer/dist/#/
预告