文章目录
:class与class共存
<body>
<div id="root">
<div class="warn" v-bind:class='{serious:isSerious}'>{{message}}</div>
</div>
</body>
.warn{
font-size: 14px;
}
.serious{
color:red;
}
import Vue from "vue";
import "./index.css";
const vm = new Vue({
el:"#root",
data:{
message:"attacking",
isSerious:true
}
});
:class
:class='js表达式'
表达式是一个对象
内联在模板里
:class="{key:value}"
key
是类名, value
是布尔值。
value
为true
则有该类,false
则没有该类
<template>
<p :class="{smallFont:true}">have a nice day</p>
</template>
<style>
.smallFont{
font-size:0.75em;
}
</style>
<template>
<p :class="{smallFont:isSmall}">have a nice day</p>
</template>
<script>
export default {
data(){
return {
isSmall:true
}
}
}
</script>
<style>
.smallFont{
font-size:0.75em;
}
</style>
绑定在data对象里
:class
绑定到data
对象里,返回一个对象。
<template>
<p :class="cssObj">have a nice day</p>
</template>
<script>
export default {
data(){
return {
cssObj:{
smallFont:true
}
}
}
}
</script>
<style>
.smallFont{
font-size:0.75em;
}
</style>
绑定到computed里
:class
绑定到computed
里,返回一个对象
<template>
<p :class="cssObj">have a nice day</p>
</template>
<script>
export default {
computed:{
cssObj:function(){
return {
smallFont:true
}
}
}
}
</script>
<style>
.smallFont{
font-size:0.75em;
}
</style>
表达式是一个数组
数组中的元素既可以是字符串变量,也可以是对象。
数组元素是字符串变量
:class="[str1,str2]"
str1
、str2
是字符串变量,其值就是类名。
内联在模板里
<template>
<p :class="['smallFont']">hello world</p>
</template>
<style>
.smallFont{
font-size:0.75em;
}
</style>
<template>
<p :class="[fontClass]">hello world</p>
</template>
<script>
export default {
data(){
return {
fontClass:"smallFont"
}
}
}
</script>
<style>
.smallFont{
font-size:0.75em;
}
</style>
绑定在data对象里
:class
绑定在data
对象里,返回一个数组。
<template>
<p :class="cssArr">hello world</p>
</template>
<script>
export default {
data(){
return {
cssArr:["smallFont"]
}
}
}
</script>
<style>
.smallFont{
font-size:0.75em;
}
</style>
绑定在computed里
:class
绑定在computed
里,返回一个数组
<template>
<p :class="cssArr">hello world</p>
</template>
<script>
export default {
computed:{
cssArr:function(){
return ["smallFont"];
}
}
}
</script>
<style>
.smallFont{
font-size:0.75em;
}
</style>
数组元素是一个对象
在数组中使用对象,:class="[{key:value}]"
<template>
<p :class="[{smallFont:true}]">hello world</p>
</template>
<style>
.smallFont{
font-size:0.75em;
}
</style>
<template>
<p :class="[{smallFont:isSmall}]">hello world</p>
</template>
<script>
export default {
data(){
return {
isSmall:true
}
}
}
</script>
<style>
.smallFont{
font-size:0.75em;
}
</style>
源码理解
const text = "hello world"
const textNode = document.createTextNode(text);
const p = document.createElement("p");
p.appendChild(textNode);
const oldVnode = new VNode(
"",/**tag */
{},/**data */
[],/**children */
undefined,/**text */
undefined/**elm */
);
const vnode = new VNode(
"p",/**tag */
{ /**data */
class:[
{smallFont:true}
]
},
[/**children */
new VNode(
undefined,
undefined,
undefined,
text,
textNode
)
],
undefined,/**text */
p/**elm */
)
updateClass(oldVnode,vnode);
function VNode(tag,data,children,text,elm){
this.tag = tag;
this.data = data;
this.children = children;
this.text = text;
this.elm = elm;
}
function updateClass(oldVnode,vnode){
var el = vnode.elm;
var data = vnode.data;
var oldData = oldVnode.data;
var cls = genClassForVnode(vnode);
if(cls!==el._prevClass){
el.setAttribute('class',cls);
el._prevClass = cls;
}
}
function genClassForVnode(vnode){
var dynamicClass = vnode.data.class;
if(isDef(dynamicClass)) return stringifyClass(dynamicClass);
return '';
}
function stringifyClass(value){
if(Array.isArray(value)){
return stringifyArray(value);
}
if(isObject(value)){
return stringifyObject(value);
}
if(typeof value==="string"){
return value;
}
return '';
}
function stringifyArray(value){
var res = '';
var stringified;
for(var i=0,l=value.length;i<l;i++){
stringified = stringifyClass(value[i]);
if(isDef(stringified) && stringified!==''){
if(res) res+=' ';
res += stringified;
}
}
return res;
}
function stringifyObject(value){
var res = '';
for(var key in value){
if(value[key]){
if(res) res+=' ';
res+=key;
}
}
return res;
}
function isDef(v){
return v!==undefined && v!==null;
}
function isUndef(v){
return v===undefined || v===null;
}
function isObject(obj){
return obj!==null && typeof obj === "object";
}
:style与style共存
<body>
<div id="root">
<div style="font-size:14px;" v-bind:style='{color:"red"}'>{{message}}</div>
</div>
</body>
import Vue from "vue";
const vm = new Vue({
el:"#root",
data:{
message:"attacking",
}
});
:style
:style="js表达式"
表达式是一个对象
内联在模板里
:style="{属性名1:属性值变量1,属性名2:属性值变量2}"
<template>
<p :style="{color:'red',fontSize:'14px'}">hello world</p>
</template>
<template>
<p :style="{color:fontColor,fontSize:fontSize}">hello world</p>
<!-- <p :style="{color:fontColor,'font-size':fontSize}">hello world</p> -->
</template>
<script>
export default {
data(){
return {
fontColor:"red",
fontSize:"14px"
}
}
}
</script>
绑定在data对象里
:style
绑定在data
对象里,返回一个对象。
<template>
<p :style="styleObj">hello world</p>
</template>
<script>
export default {
data(){
return {
styleObj:{
color:"red",
fontSize:"14px"
// "font-size":"14px"
}
}
}
}
</script>
绑定在computed里
:style
绑定在computed
里,返回一个对象
<template>
<p :style="styleObj">hello world</p>
</template>
<script>
export default {
computed:{
styleObj:function(){
return {
color:"red",
fontSize:"14px"
// "font-size":"14px"
}
}
}
}
</script>
表达式是一个数组
数组元素必须是对象
内联在模板里
<template>
<p :style="[{color:'red'},{fontSize:'14px'}]">hello world</p>
</template>
<template>
<p :style="[{color:fontColor},{fontSize:fontSize}]">hello world</p>
</template>
<script>
export default {
data(){
return {
fontColor:"red",
fontSize:"14px"
}
}
}
</script>
绑定在data对象里
绑定在data
对象里,返回一个数组,数组中每个元素必须是对象。
<template>
<p :style="[styleObj1,styleObj2]">hello world</p>
</template>
<script>
export default {
data(){
return {
styleObj1:{
color:"red"
},
styleObj2:{
fontSize:"14px"
}
}
}
}
</script>
绑定在computed里
绑定在computed
里,返回一个数组,数组中每个元素必须是对象
<template>
<p :style="[styleObj1,styleObj2]">hello world</p>
</template>
<script>
export default {
computed:{
styleObj1:function(){
return {
color:"red"
}
},
styleObj2:function(){
return {
fontSize:"14px"
}
}
}
}
</script>
源码理解
const text = "hello world"
const textNode = document.createTextNode(text);
const p = document.createElement("p");
p.appendChild(textNode);
const oldVnode = new VNode(
"",/**tag */
{},/**data */
[],/**children */
undefined,/**text */
undefined/**elm */
);
const vnode = new VNode(
"p",/**tag */
{ /**data */
style:[
{color:"red"},
{fontSize:"14px"}
]
},
[/**children */
new VNode(
undefined,
undefined,
undefined,
text,
textNode
)
],
undefined,/**text */
p/**elm */
)
updateStyle(oldVnode,vnode);
function VNode(tag,data,children,text,elm){
this.tag = tag;
this.data = data;
this.children = children;
this.text = text;
this.elm = elm;
}
function updateStyle(oldVnode,vnode){
var el = vnode.elm;
var style = normalizeStyleBinding(vnode.data.style) || {};
var oldStyle = oldVnode.data.style || {};
var name,cur;
for(name in oldStyle){
if(isUndef(style[name])){
setProp(el,name,'')
}
}
for(name in style){
cur = style[name];
if(cur !== oldStyle[name]){
setProp(el,name,cur===null?'':cur);
}
}
}
function normalizeStyleBinding(bindingStyle){
if(Array.isArray(bindingStyle)){
return toObject(bindingStyle);
}
return bindingStyle;
}
function toObject(arr){
var res = {};
for(var i=0;i<arr.length;i++){
if(arr[i]){
extend(res,arr[i]);
}
}
return res;
}
function extend(to,_from){
for(var key in _from){
to[key] = _from[key];
}
return to;
}
function setProp(el,name,val){
el.style[name] = val;
}
function isDef(v){
return v!==undefined && v!==null;
}
function isUndef(v){
return v===undefined || v===null;
}
render函数实现组件
//index.html
<body>
<div id="root">
</div>
</body>
//index.css
.smallFont{
font-size:0.75em;
}
//index.js
import Vue from "vue";
import App from "./app.vue";
import "./index.css";
Vue.component("MyComponent",{
render:function(createElement){
return createElement(
'p',
{
style:{
color:"red"
},
class:{
smallFont:true
}
},
'have a nice day'
);
}
})
const vm = new Vue({
render:function(createElement){
return createElement(App)
}
}).$mount('#root');
//app.vue
<template>
<MyComponent/>
</template>