style与class
# 当变量为true的时候才显示 active class
<div :class="{ active: isActive }"></div>
<div
class="static"
:class="{ active: isActive, 'text-danger': hasError }"
></div>
=> <div class="static active"></div>
# 更复杂点的判断逻辑推荐使用 computed
<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 :class="[isActive ? activeClass : '', errorClass]"></div>
<li :class="['menu-item', {'currentview': currentview === menuItem.key}]" ></li>
内联语法
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
直接绑定到一个样式对象通常更好,这会让模板更清晰:
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
计算属性与侦听器
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val,oldval) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val,oldval) {
this.fullName = this.firstName + ' ' + val
}
}
过滤器
<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
# js
filters: {
capitalize: function (value) { # value是 |之前的那个值
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
# 接受传参的情况
{{ message | filterA('arg1', arg2) }}
在filters中 message还是在函数的第一个参数
mixins
# 一个混入对象可以包含任意组件选项
var mixin = {
created: function () {
// this.hello()
},
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
# 混入的时候
# 当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
extend与$mount
webpack main.js 的入口
import Vue from 'vue';
import App from './app.vue';
new Vue({
el: '#app',
render: h => h(App)
});
Webpack 基本都是前端路由的,它的 html 里一般都只有一个根节点 <div id="app"></div>
,其余都是通过 JavaScript 完成
有了初始化的实例,之后所有的页面,都由 vue-router 帮我们管理,组件也都是用 import
导入后局部注册(也有在 main.js 全局注册的),不管哪种方式,我们只是写好 .vue
文件并导入即可,组件(或页面)的创建过程我们是无需关心的 ( 页面的创建过程:规避掉了 dom的操作细节
特点:
- 所有的内容,都是在
#app
节点内渲染的; - 组件的模板,是事先定义好的;
- 由于组件的特性,注册的组件只能在当前位置渲染。
换句话说,常规的组件使用方式,只能在规定的地方渲染组件,这在一些特殊场景下就比较局限了,例如:
- 组件的模板是通过调用接口从服务端获取的,需要动态渲染组件;(组件的渲染是异步的,甚至预先不知道模板是什么
- 实现类似原生
window.alert()
的提示框组件,它的位置是在<body>
下,而非<div id="app">
,并且不会通过常规的组件自定义标签的形式使用,而是像 JS 调用函数一样使用。
那么怎么 将创建的组件 在页面的任意一个dom节点上渲染呢? 而不是默认的根组件
====》 Vue.extend 配合 $mount
import Vue from 'vue';
# Vue.extend 的作用,就是基于 Vue 构造器,创建一个“子类“
# 解决了 异步获取template的问题
const AlertComponent = Vue.extend({
template: '<div>{{ message }}</div>',
// data 里 返回的是函数
data () {
return {
message: 'Hello, Aresn'
};
},
});
# 接下来 手动渲染组件 挂载在body下
const component = new AlertComponent().$mount(); # mount手动渲染
document.body.appendChild(component.$el);
# 简写=>
// 在 $mount 里写参数来指定挂载的节点
new AlertComponent().$mount('#app');
// 不用 $mount,直接在创建实例时指定 el 选项
new AlertComponent({ el: '#app' });
我们是用 $mount
手动渲染的组件,如果要销毁,也要用 $destroy
来手动销毁实例,必要时,也可以用 removeChild
把节点从 DOM 中移除
同样可以手动渲染的:(就是云雅的那个例子
===> 既能用写.vue文件引入模板(毕竟在 template 里堆字符串很痛苦),又可以根据需要传入适当的 props,还可以 手动渲染组件 实现任意节点挂载
==> 使用 render函数
import Vue from 'vue';
import Notification from './notification.vue';
const props = {}; // 这里可以传入一些组件的 props 选项
const Instance = new Vue({
render (h) {
return h(Notification, {
props: props # 通过props传数据给模板; (比如后端的数据
});
}
});
const Instance = new Vue({
el:body,
render:h=>h(Notification,{
props:{xxxdata}
})
});
const component = Instance.$mount();
document.body.appendChild(component.$el);
渲染后,如果想操作 Render 的 Notification
实例,因为 Instance 下只 Render 了 Notification 一个子组件,所以可以用 $children[0]
访问到。
const notification = Instance.$children[0];