1. data中数据响应式问题
当一个 Vue 实例被创建时,它将data对象中的所有的属性加入到 Vue 的响应式系统中。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。当这些数据改变时,视图会进行重渲染。但是只有当实例被创建时就已经存在于data中的属性才是响应式的。也就是说如果你对于某个data中的对象添加一个新的属性,那么对于该属性的修改将不会响应式的显示。
<div class="Home">{{demo}}</div>
<script>
new Vue({
data:{
demo:{
a:"a",
b:"b"
}
}
})
<script>
//其中,demo对象中,a属性与b属性都是响应式的在视图中显示。而
2. el与$mount
- 对比
vue中el与$mount在使用中并没没有什么区别,都是将实例化后的vue挂载到指定的dom元素中。如果在实例化vue时指定el,则该vue将会渲染在el对应的DOM中。反之 没有指定el,则vue实例会处于一种“未挂载”的状态,此时通过$mount来手动执行挂载。new vue时候$mount和el并没有什么本质上的不同 - el
注意:不可使用html,body元素作为挂载元素,因为挂载元素会被Vue生成的DOM替换,而html如果没有html,body标签会报错。
new Vue ({
el: "#app",
vue,
store,
router,
render: h => h(App)
})
- $mount
如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用 vm.$mount() 手动地挂载一个未挂载的实例。
如果没有提供 elementOrSelector 参数,模板将被渲染为文档之外的的元素,并且你必须使用原生 DOM API 把它插入文档中。
这个方法返回实例自身,因而可以链式调用其它实例方法。
var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})
// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')
// 同上
new MyComponent({ el: '#app' })
// 或者,在文档之外渲染并且随后挂载
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)
3. render 函数和 template 属性
- template
一个字符串模板作为 Vue 实例的标识使用。模板将会 替换 挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发插槽。
template中可以调用简单的可以直接返回的一元运算符,并且能直接返回数据,也可以调用js的全局方法比如,Date.now(),但是不能调用自己在全局定义的变量
var app = new Vue({
el:'#root',
template:`
<div>
{{isActive?'active':'not active'}}
{{Date.now()}}
</div>
`,
data:{
isActive:false,
}
})
- render
字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。该渲染函数接收一个 createElement 方法作为第一个参数用来创建 VNode。如果组件是一个函数组件,渲染函数还会接收一个额外的 context 参数,为没有实例的函数组件提供上下文信息。
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。实际上用template来创建html 在 webpack 做编译时 template 会被编译成 render 来运行的。
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 标签名称
this.$slots.default // 子节点数组
)
},
props: {
level: {
type: Number,
required: true
}
}
})
4. 插槽slot
插槽是使用在子组件中的,插槽是为了将父组件中的子组件模板数据正常显示。
子组件在父组件中注册的标签中不能添加其他的标签,使用插槽可以实现。放在子组件中的什么位置,父组件中被子组件标签包裹的元素就显示在子组件的什么位置。
<div id="app">
<div class="father">
<h3>这里是父组件</h3>
<child>
<span>菜单1</span>
<span>菜单2</span>
<span>菜单3</span>
</child>
</div>
</div>
<template id="child">
<div class="child">
<h3>这里是子组件</h3>
<slot></slot>
</div>
</template>
<script>
var vm = new Vue({
el: '#app',
data: {},
components: {
child: {
template: '#child'
}
}
});
</script>
元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
一个不带 name 的 出口会带有隐含的名字“default”。
在向具名插槽提供内容的时候,我们可以在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
现在 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot的 中的内容都会被视为默认插槽的内容。然而,如果你希望更明确一些,仍然可以在一个 中包裹默认插槽的内容。
5. 箭头函数
ES6中允许使用“箭头”(=>)定义函数,根据箭头函数有参数和无参数来区分
- 无参数的箭头函数
var f = () => v;
//等同于下面的代码
var f = function() {
return v;
}
- 有一个参数的箭头函数
var f = v => v;
//等同于下面的代码
var f = function(v) {
return v;
}
- 有多个参数的箭头函数
var f = (v,w) => v+w;
//等同于下面的代码
var f = function(v,w) {
return v+w;
}
- 根据箭头函数返回语句来区分
有的函数体内的语句大于一条的话,它的写法如下使用一个大括号将其括起来,并使用return语句返回
aaa: () => {
var c = 2;
var d = 4;
return c + d;
}
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象时,必须在对象外面加一个大括号,并将整个对象用小括号括起来
aaa: () => ({
a: "aaa",
b: "bbb",
c: "ccc"
})
- 箭头函数也可以与变量解构结合使用:
aaa: ({a,b}) => a + " " + b
//等同于下面的代码
function full(d) {
return d.a+" "+ d.b;
}
注意:
箭头函数中的this继承于它外面第一个不是箭头函数的函数的this指向。
箭头函数的 this 一旦绑定了上下文,就不会被任何代码改变。