Vue初学
初学,今天看了VueJS的文档,参考方老师的课,列了一个Vue知识图谱,在github上找了一个CNode社区的Vue项目,明天把文档都看完之后就开始看项目源码,然后自己实现一遍。预计花费时间一周,也就是说下周二CNode的项目就要做出来并且写好笔记!
下面是我今天记得笔记
MVVM
// 用defineProperty定义的所有属性,基本上一开始的属性都是false 比如 不可写,不可枚举,不可配置
Object.defineProperty(obj,'name',{
value: 'jianyang',
//默认值
writable: false,
configurable: false,
enumerable: false
})
// 创造一个闭包
obj = {}
!(function(){
var name = 'jianyang'
Object.defineProperty(obj,'name',{
// 默认值
get: function(){
console.log("get进入")
return name
},
set: function(xxx){
console.log("set进入")
name = xxx
}
})
})()
// 在获取obj的属性的时候回自动调用get函数
// 在设置obj属性值得时候会自动调用set函数
// 这是Vue用defineProperty做MVVM的基础
// 下面双向绑定 dom改js的时候 js的属性值会变 js改dom的时候也会直接反应在视图上
//html
<input type="text" id="inputA">
//js 得引入jQuery
obj = {}
!(function(){
var name = 'jianyang'
Object.defineProperty(obj,'name',{
// 默认值
get: function(){
return name
},
set: function(xxx){
name = xxx
render()
}
})
})()
// 重新渲染inputA的值
render: function () {
inputA.value = obj.name
}
// 在input里的值改了的时候就改变obj的值
// 改了obj的值后调用 set函数,set函数里调用render()重新渲染inputA的值
// 也就是说结果都是调用render()函数,在input中输入值可以调用render()函数,直接改obj的值也调用render()函数
$('input').on('input',function(){
var value = $('#inputA').val()
obj.name = value
})
Vue.js
// v-bind:data-id ="" 单向绑定
// v-model= "" 双向绑定
// v-click:on="" => @click = ""
// v-bind:data-id="" => :data-id = ""
<ol id='app' :data-id="index" @click="xxx(index,$event)">
<li v:for="(number,index) in numbers">{{number}} {{index}}</li>
<li v:for="(value,key) in obj">{{value}} {{key}}</li>
<li v:for="(o,index) in objArray">{{o}} {{index}}</li>
<>
</ol>
let xxx = new Vue({
el: '#app',
data: {
numbers:[1,2,4,5,6,8,1,2,3,4,5],
obj: {
name: 'jianyang',
age: 23
},
objArray: [
{text:'hi'},
{text:'how'},
{text:'are'},
{text:'you'}
]
},
method: {
xxx: function(index,event){
console.log(index,event)
},
}
})
// 组件
Vue.component('xxx',{
template: '<li>这是一个待办项</li>'
})
new Vue({
el:'#app',
})
// 组件传值的方式1 定义属性直接在组件传值
<xxx name="jianyang" age="22"></xxx>
Vue.component('xxx',{
template: '<li>这个人是 {{name}} {{age}}</li>',
props: ['name','age']
})
new Vue({
el:'#app',
})
// 组件传值方式2 从data中取到数据
<li v:for="xxx in people">
<xxx :name="xxx.name" :age="xxx.age"></xxx>
</li>
Vue.component('xxx',{
template: '<li>这个人是 {{name}} {{age}}</li>',
})
new Vue({
el:'#app',
data: {
people:[
{name: "jianyang", age: 23},
{name: "xiaohua", age:22},
{name: "xiaoming", age: 10}
]
}
})
Vue.js文档
Vue实例
// 只有当实例被创建时就已经存在于 data 中的属性才是响应式的
// 有一个例外 Object.freeze(obj) 会阻止对象现有属性的修改了,也就不是响应式的了
var obj = {
foo: 'bar'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
// Vue的实例属性和方法
vm.$data === data // => true 可以直接通过$data操作数据, vm.$data 和 this
vm.$el === document.getElementById('example') // => true $el还会用到,因为之前看到比人用到过
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
// 声明周期钩子,这个挺有用的,在编微信小程序的时候就知道每个钩子函数是做不同的事情的,要分开。 例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。
模板语法
// 模板语法,但是注意渲染的是纯文本不是HTML,如果你想要渲染HTML,需要使用 v-html 指令 有啥区别吗?
//TEXT
<span>Message: {{ msg }}</span>
//HTML 会把span标签内的内容直接替换为一段HTML
//你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。
<span v-html="msg"></span>
// v-once 指令 一次性插值,这个标签下的所有属性之后都不会改变
<span v-once>这个将不会改变: {{ msg }}</span>
计算属性和侦听器
// 一般都用计算属性,因为比较方便,代码简单
// 在有回调或者执行代码比较多的时候用watch
特殊的绑定 class 和 style
// 内联样式直接传入对象
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
// 传入计算属性
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
// 传入数组
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
<div class="active text-danger"></div>
// 总之传入的时候写的是js代码
条件渲染
// 我有点知道key的作用了,应该与虚拟dom的算法有关。如果不声明key,可能会复用已有的元素,而不是重新声明,这样就变得非常快,但在一些情境下不行!
// v-show v-if
// v-if
// v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
// v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
// v-show 的元素是切换 display 还会留在dom中,而 v-if 就是没渲染
// v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
<h1 v-show="ok">Hello!</h1>
// v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
display 和
visibility
有啥区别,一个还占位置,一个不占位置
有没有不渲染dom的属性?
// 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。请查阅列表渲染指南 以获取详细信息。
列表渲染
// 当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 track-by="$index"。
// 建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
事件处理
// 可把原生dom对象传进函数中
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
// 鼠标按钮修饰符
.left
.right
.middle
// 这些修饰符会限制处理函数仅响应特定的鼠标按钮。
// 做个人简历的时候应该会用到
Vue组件基础
// 组件做成这样,用一个函数去封装数据,用到了闭包。让每个组件的数据都是私有的,以免污染全局
data: function () {
return {
count: 0
}
}
// 监听子组件事件
// 把事件挂载在组件上,子组件通过$emit方法去调挂载的事件,这个函数之后应该经常用到,还可以传第二个参数
<button v-on:click="$emit('enlarge-text')">
Enlarge text
</button>
<blog-post
...
v-on:enlarge-text="postFontSize += 0.1"
></blog-post>