Vue.js(1) 基础使用

起步

引入 vue.js

核心: 声明式渲染

这里的声明式渲染表示整个Vue实例都是基于数据+模型组成的, Vue本身就是一个数据的载体, 通过双向绑定渲染到DOM中, 其中还可以添加一些方法或是计算属性来响应式修改DOM,基础非常简单易懂
Vue的真正能力是高度组件化, 路由, 高效状态管理,不过通过学习Vue基础就可以很好的将Vue应用在一些简单页面并享受到双向绑定的优势

<div id="app">
    {{message}}
    <!--使用{{}}的方式引入vue中的属性-->
</div>
var app = new Vue({
    el: '#app', // 选取的dom元素, 获得vue特性
    data: {//给予该dom的数据,即本身拥有的属性
        message: 'Hello Vue'
    }
})

执行函数

<div id="app">
    <p>{{message}}</p>
    <button v-on:click="dosometing">click</button>
    <!--使用v-on:click绑定点击事件-->
</div>
var app = new Vue({
    el: '#app',
    data: {
        message: 'Hello World'
    },
    methods: {//声明该dom携带的函数(function)
         dosometing: function() {
            this.message = 'Hello Vue'
         }
    }
})

注册组件

<div id="app">
    <ul>
        <todo
            v-for = "item in list"
            v-bind:todo = "item"
            v-bind:key = "item.id"
        ></todo><!--从父组件中获取数据及添加到子组件的属性(props)中-->
    </ul>
</div>
Vue.component('todo', {//这里的todo是需要注册的组件的name,即标签名
    props: ['todo'],//这里绑定的是该组件所携带的props,即属性,也就是从父组件中获取到的数据
    template: '<li>{{todo.text}}</li>'//这里为改组件所渲染的dom元素及相应的模板
})
    
var app = new Vue({
    el: '#app',
    data: {
        list: [//父组件拥有的数据
            {id: 0, text:'第一项'},
            {id: 1, text:'第二项'},
            {id: 2, text:'第三项'},
            {id: 0, text:'第一项'}
        ]
    }
})

Vue实例

一个new Vue()便是一个新的Vue应用实例

数据与方法

这里vm的data是来源于变量data,vm.data指向data.data,同时可以通过添加前缀$来区分用户自定义属性

var data = { data: 'data' }//初始化Vue应用数据
var vm = new Vue({
    data: data
})

console.log(vm.$data === data.data);
vm.$data = 'datas';
console.log(data.data);

更深入的探讨

生命周期(钩子函数)

Vue使用虚拟DOM算法, 即DOM元素会以最小消耗插入到html中, 在这期间提供的钩子函数,可以插入自己的代码

模板语法

  1. 文本 {{}}
    采用Mustache{{}}的插值方式
  2. 原始HTML v-html
    使用v-html渲染html, 容易导致xss攻击
<div v-html="rawHtml">{{rawHtml}}</div>
  1. 为DOM添加属性 v-bind
    可以使用v-bind为DOM添加相应的属性, 同样的,这里的数据也是来源于Vue实例中的data
<div v-html="rawHtml" v-bind:id="raw">{{rawHtml}}</div>

注意

//这些falsy值都将转为false
if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
//这些truthy值都将转为true
if (true)
if ({})
if ([])
if (42)
if ("foo")
if (new Date())
if (-42)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)
  1. javascript表达式
    Vue的模板支持简单的表达式,只支持单个表达式
<div v-bind:id="'list-' + id"></div>
{{ number + 1}}
{{ ok ?'YES': 'NO'}}
{{ messsage.split('').reverse().join('')}}

指令

Vue带有大量的指令, 用于控制DOM, 如

<p v-if="seen">现在你看到我了</p>
  1. 参数
    某些指令可以添加参数, 可以响应式更新DOM属性
<a v-bind:href="url">Link</a>
<a v-on:click="click">Click</a>
  1. 修饰符
    修饰符(Modifiers), 用于让某一指令应该以特殊方式绑定, 非常有用
    如,这里的.provent代表触发onSubmit事件时调用event.preventDefault()
<form v-on:submit.prevent="onSubmit">Submit</form>
  1. 缩写
    v-本身是用来识别Vue的特性, 不过Vue.js是用于开发单页面(SPA)时, 过长的指令还是比较繁琐
<a :href="url">Link</a>
<a @click="click">Click</a>

计算属性

对于复杂逻辑, 使用计算属性是Vue推荐的方式
计算属性声明在Vue实例中的computed中,使用方式与普通的渲染一致

<div id="app">
    <p>{{reversedMessage}}</p>
</div>
var vm = new Vue({
    el: '#app',
    data: {
        message: 'Hello World'
    },
    computed: {
        //在这里声明
        reversedMessage: function(){
            //在这里处理
            return this.message.split('').reverse().join('');
        }
    }
})

与methods相比, 计算属性是基于它们的依赖,比如上方的message来进行缓存的, 即message不改变的情况下, 计算属性能立即返回值, 而methods定义的方法则每次都需要调用, 相应的, 如果不需要缓存, 则使用methods更好

VUe提供了一种侦听属性来观察相应的数据变动

计算属性默认只提供getter, 不过需要的时候也可以提供一个setter

//...
computed: {
    fullName: {
        get: function() {
            return this.firstName + '' + this.lastName
        },
        set: function() {
            var names = newValue.split(' ');
            this.firstName = names[0];
            this.lastName = names[names.length -1];
        }
    }
}
//...

Class及Style

  1. 绑定HTML Class
    通过传入v-bind:class一个对象, 可以动态切换class
<div v-bind:class="{ active: isActive }"></div>
<div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div><!--可以与普通的class共存-->

当isActive为true时则绑定.active样式
相应的, 这里的数据可以绑定在Vue实例中

data: {
    classObject: {
        active: true,
        "text-danger": false
    }
}

同时也可以绑定一个返回对象的计算属性,常用而有效,推荐使用

<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'
    }
  }
}
  1. 数组语法
    v-bind:class可以接收一个数组
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

写法还有多种

<!--三元表达式-->
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
<!--对象语法-->
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
<!--使用在组件上-->
<my-component v-bind:class="{ active: isActive }"></my-component>
  1. 绑定内联样式
    v-bind:style与绑定class相似,同样传入对象绑定, 不过css属性名必须使用小驼峰写法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

相应的也可以使用对象及数组语法, 而且Vue能自动检测浏览器并自动添加内核前缀

<!--data对象写法-->
<div v-bind:style="styleObject"></div>
<!--数组语法-->
<div v-bind:style="[baseStyles, overridingStyles]"></div>
<!--多重值 v2.3.0+-->
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

条件渲染 v-if

Vue提供v-ifv-else-if(2.1.0+)v-else指令执行条件渲染

<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>

Vue会自动复用已有的元素,而非进行重新渲染, 另外可以通过添加唯一key属性来让Vue不复用该元素

<!--不添加key-->
<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>
<!--添加key-->
<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

v-if外, 还提供了一个v-show, 用法相同, 不过后者的元素始终会被渲染并保留在DOM中

列表渲染 v-for

v-for指令需要使用item in items形式的特殊语法

  1. 迭代渲染一个数组
<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>
<!--使用of代替in-->
<div v-for="item of items"></div>
var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

v-for支持一个可选的第二个参数为当前项的索引

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
  1. 迭代渲染一个对象
<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
<!--可选的第二个参数,键名-->
<div v-for="(value, key) in object">
  {{ key }}: {{ value }}
</div>
<!--可选的第三个参数,索引-->
<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }}: {{ value }}
</div>
var example1 = new Vue({
  el: '#v-for-object',
  data: {
    object: {
      firstName: 'John',
      lastName: 'Doe',
      age: 30
    }
  }
})

同样的,为Vue能获取每个节点而非简单复用原有的元素, 添加key是一个更加方便的写法

<div v-for="item in items" :key="item.id">
  <!-- 内容 -->
</div>

数组更新检测

Vue能观察数组的变化而触发视图更新,即数组更新时,视图随着更新
不过部分情况下,Vue不能检测变动的数组

//通过索引直接设置一项
vm.items[indexOfItem] = newValue
//相应的解决方法
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)
//修改数组长度
vm.items.length = newLength
//相应的解决方法
example1.items.splice(newLength)

相应的,Vue 也不能检测对象属性的添加或删除
不过可以通过Vue.set添加新的属性

Vue.set(vm.userProfile, 'age', 27);
//使用Object.assgin()时
this.userProfile = Object.assign({}, this.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

显示过滤排序结果

通过计算属性

<li v-for="n in evenNumbers">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

通过methods

<li v-for="n in even(numbers)">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

v-forv-if可以同时使用

<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>

事件处理 v-on

可以使用v-on来绑定事件

 <button v-on:click="counter += 1">增加 1</button>

相应的,可以将事件写在methods中

 <button v-on:click="greet">Greet</button>
 <!--添加参数-->
 <button v-on:click="say('what')">Say what</button>
 <!--原生DOM事件-->
 <button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
methods: {
    greet: function (event) {
      // `this` 在方法里指当前 Vue 实例
      alert('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
        alert(event.target.tagName)
      }
    },
    say: function (message) {
      alert(message)
    },
    warn: function (message, event) {
        // 现在我们可以访问原生事件对象
        if (event) event.preventDefault()
        alert(message)
    }
  }

事件修饰符

Vue提供一些事件修饰符来解决DOM事件细节

<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身 (比如不是子元素) 触发时触发回调 -->
<div v-on:click.self="doThat">...</div>

键值修饰符

Vue提供一些键值修饰符来监听键盘事件

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">

同时也有相应的别名

<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
//由Vue提供的别名
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right

可以通过全局 config.keyCodes 对象自定义键值修饰符别名

// 可以使用 v-on:keyup.f1
Vue.config.keyCodes.f1 = 112

系统修饰键

2.1.0
可以用如下修饰符开启鼠标或键盘事件监听,使在按键按下时发生响应

.ctrl
.alt
.shift
.meta
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

鼠标按钮修饰符

2.1.0

.left
.right
.middle

表单输入绑定 v-model

  1. 文本
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
  1. 多行文本
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
  1. 复选框
<!--单个勾选框-->
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<!--多个勾选框-->
<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>
new Vue({
  el: '#example-3',
  data: {
    checkedNames: []
  }
})
  1. 单选按钮
<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <br>
  <span>Picked: {{ picked }}</span>
</div>
new Vue({
  el: '#example-4',
  data: {
    picked: ''
  }
})
  1. 选择列表
<div id="example-5">
  <select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
<!--多选列表-->
<div id="example-6">
  <select v-model="selected" multiple style="width: 50px;">
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <br>
  <span>Selected: {{ selected }}</span>
</div>
<!--动态渲染-->
<select v-model="selected">
  <option v-for="option in options" v-bind:value="option.value">
    {{ option.text }}
  </option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
  el: '#example-5',
  data: {
    selected: ''
  }
})
//动态渲染
new Vue({
  el: '...',
  data: {
    selected: 'A',
    options: [
      { text: 'One', value: 'A' },
      { text: 'Two', value: 'B' },
      { text: 'Three', value: 'C' }
    ]
  }
})

后边的查文档吧,不想写了, 大同小异

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容