style与class
# 当变量为true的时候才显示 active class<div :class="{ active: isActive }"></div><divclass="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: {// 计算属性的 getterreversedMessage: 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># jsfilters: {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];
