一,渐进式框架
1.vue 按需引入
mvvm module view view-module 数据驱动
2. vue 模块化
什么是模块化开发
单页面应用 spa 路由
3.模板输出
{{}} 可以进行简单的计算或者换算处理
4.创建实例
html:
<div id="box">
{{a}}
</div>
js:
<script>
//第一步
var lee = new Vue({
el:'#box',
data:{
a:12
}
})
</script>
结果:
二,两种开发
1.简单的几个页面
使用srcript引用
<script src="vue.js"></script>
2. 商城
vue-cli 框架式
三,指令
用之前需要先声明 实例
属性 | 作用 | 实际操作 |
---|---|---|
v-text | text输出 | <div v-text="<p style="color:red;">hello</p>"></div> 输出 <p style="color:red;">hello</p> |
v-html | html输出 | <div v-text="<p style="color:red;">hello</p>"></div> 输出 hello |
v-show | 显示/隐藏 | v-show = true/false 布尔值 v-show 都会加载 没有缓存 消耗相对低 |
v-if | 判断 | v-if 只会加载真的部分 有缓存 消耗高 适合偶尔的显示隐藏切换 |
v-else | 判断 | v-else只会加载真的部分 有缓存 消耗高 适合偶尔的显示隐藏切换 |
v-else-if | 判断 | v-else-if 只会加载真的部分 有缓存 消耗高 适合偶尔的显示隐藏切换 |
v-for | 循环 | 数组 <p v-for="(i,$index) in arr"></p> json数据 <p v-for="(i,$key,$index) in arr"></p> |
v-model | 双向绑定 | 多用于下拉框 value>text |
v-bind | 属性绑定 | <div :style="{'color':‘red’}"></div> |
四,实例方法
data、methods、computed三者名字不可以重复
new Vue({
el:'' >绑定的作用域
data: 放数据的
methods:事件函数
computed:计算属性
})
五,生命周期钩子
beforeCreate (){} | 创建前 |
created(){} | 创建后 |
beforeMount(){} | 渲染前 |
mounted(){} | 渲染后 |
beforeUpdate(){} | 数据更新前 |
updated(){} | 数据更新后 |
beforeDestroy(){} | 销毁前 |
destroyed (){} | 销毁后 |
六,计算属性和侦听器
1.侦听属性 :侦听某一项数据的变化,this是vue实例,可以监控到计算属性的变化
2.生命周期:侦听所有的数据变化,this是vue实例
3.计算属性:没有调用不会触发,this是vue实例
4.watch
可以和data重名
可以和methods重名
可以和computed重名
5.数组,通过下标去修改数据,是不会被索引检测的,所以视图不会更新
当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
解决方法
1.this.arr.splice(1,1,23)
2.this.$set(this.arr,1,23)
七,ajiax
1.安装
npm install vue-resourc
使用命令符窗口进行安装,快捷键:window键+R;输入cmd确定
2.安装完后找到 node_modules/vue-resource/dist/vue-resource.js
打开node_modules找到vue-resource文件夹打开再找到dist打开
找到vue-resource.js或vue-resource.min.js
vue-resource.min.js是压缩过后的
3.引用
<script src=" node_modules/vue-resource/dist/vue-resource.js"></script>
4.使用实例
<script>
//post获取
var vm = new Vue({
el: "#box",
data:{},
methods:{
ajaxs(){
this.$http.$.post('', {data}, {emulateJSON:true}).then((data) {
//成功
},(data)=>{
//失败
});
}
}
})
//get获取
var vm = new Vue({
el: "#box",
data:{},
methods:{
ajaxs(){
this.$http.get('',{params:{data}}).then((data)=>{
//成功
},(data)=>{
// 失败
})
}
}
})
jsonp跨越
var vm = new Vue({
el: "#demo",
data:{
},
methods:{
ajaxs(){
this.$http.$.jsonp('', {params:{},jsonp:'cb'}).then({
// 成功
},(data)=>{
});
}
}
})
</script>
八,自定义过滤
全局 Vue.filter( id, [definition] )
参数:
{string} id
{Function} [definition]
用法:
1.注册或获取全局过滤器。
// 注册
Vue.filter('my-filter', function (value) {
// 返回处理后的值
})
// getter,返回已注册的过滤器
var myFilter = Vue.filter('my-filter')
2.你可以在一个组件的选项中定义本地的过滤器:
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
过滤器函数总接收表达式的值 (之前的操作链的结果) 作为第一个参数。在上述例子中,capitalize
过滤器函数将会收到 message
的值作为第一个参数。
3.过滤器可以串联:
{{ message | filterA | filterB }}
在这个例子中,filterA
被定义为接收单个参数的过滤器函数,表达式 message
的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB
,将 filterA
的结果传递到 filterB
中。
九,自定义指令
Vue.directive( id, [definition] )
参数:
{string} id
{Function | Object} [definition]
用法:
注册或获取全局指令。
// 注册
Vue.directive('my-directive', {
bind: function () {},
inserted: function () {},
update: function () {},
componentUpdated: function () {},
unbind: function () {}
})
// 注册 (指令函数)
Vue.directive('my-directive', function () {
// 这里将会被 `bind` 和 `update` 调用
})
// getter,返回已注册的指令
var myDirective = Vue.directive('my-directive')
当页面加载时,该元素将获得焦点 (注意:autofocus
在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。现在让我们用指令来实现这个功能:
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
如果想注册局部指令,组件中也接受一个 directives
的选项:
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
然后你可以在模板中任何元素上使用新的 v-focus
属性,如下:
<input v-focus>
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
-
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 -
inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。 -
update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。 -
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。 -
unbind
:只调用一次,指令与元素解绑时调用。
接下来我们来看一下钩子函数的参数 (即 el
、binding
、vnode
和 oldVnode
)。
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作 DOM 。binding
:一个对象,包含以下属性:name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
十,插槽
Vue 实现了一套内容分发的 API,这套 API 基于当前的 Web Components 规范草案,将 <slot>
元素作为承载分发内容的出口。
它允许你像这样合成组件:
<navigation-link url="/profile">
Your Profile
</navigation-link>
然后你在 <navigation-link>
的模板中可能会写为:
<a
v-bind:href="url"
class="nav-link"
>
<slot></slot>
</a>
当组件渲染的时候,这个 <slot>
元素将会被替换为“Your Profile”。插槽内可以包含任何模板代码,包括 HTML:
<navigation-link url="/profile">
<!-- 添加一个 Font Awesome 图标 -->
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
如果 <navigation-link>
没有包含一个 <slot>
元素,则任何传入它的内容都会被抛弃。
具名插槽
有些时候我们需要多个插槽。
对于这样的情况,<slot>
元素有一个特殊的特性:name
。这个特性可以用来定义额外的插槽:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
在向具名插槽提供内容的时候,我们可以在一个父组件的 <template>
元素上使用 slot
特性:
<base-layout>
<template 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 slot="footer">
<p>Here's some contact info</p>
</template>
</base-layout>
你可以在组件模板里的 <slot>
标签内部指定默认的内容来做到这一点。
<button type="submit">
<slot>Submit</slot>
</button>
如果父组件为这个插槽提供了内容,则默认的内容会被替换掉。
当你想在插槽内使用数据时,例如:
navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
该插槽可以访问跟这个模板的其它地方相同的实例属性 (也就是说“作用域”是相同的)。但这个插槽不能访问 <navigation-link>
的作用域。例如尝试访问 url
是不会工作的。牢记一条准则。
十一,组件
基本实例
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 <button-counter>
。我们可以在一个通过 new Vue
创建的 Vue 根实例中,把这个组件作为自定义元素来使用:
<div id="components-demo">
<button-counter></button-counter>
</div>
new Vue({ el: '#components-demo' })
因为组件是可复用的 Vue 实例,所以它们与 new Vue
接收相同的选项,例如 data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像 el
这样根实例特有的选项。
组件的复用·
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
</div>
data必须是个函数
当我们定义这个 <button-counter>
组件时,你可能会发现它的 data
并不是像这样直接提供一个对象:
|
取而代之的是,一个组件的 data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
|
如果 Vue 没有这条规则,点击一个按钮就可能会影响到其它所有实例
为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。至此,我们的组件都只是通过 Vue.component
全局注册的:
Vue.component('my-component-name', { // ... options ... })
全局注册的组件可以用在其被注册之后的任何 (通过 new Vue
) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
Prop 是你可以在组件上注册的一些自定义特性。当一个值传递给一个 prop 特性的时候,它就变成了那个组件实例的一个属性。为了给博文组件传递一个标题,我们可以用一个 props
选项将其包含在该组件可接受的 prop 列表中:
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data
中的值一样
<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>
十二,子级向父级传值
1创建一个子组件
<lee :num='a'>我是父级{{a}}</lee>
<template id="lee">
<div>
<button>+</button>
<slot></slot>
<button>-</button>
</div>
</template>
<script>
Vue.component('lee',{
template:'#lee',
props:['num']
})
new Vue({
el:'#box',
data:{
a:12
}
})
</script>
在响应该点击事件的函数中使用$emit来触发一个自定义事件,并传递一个参数
<div id="box">
<lee :num='a'>
{{a}}
</lee>
</div>
<template id="lee">
<div>
<button @click="jia">+</button>
<slot></slot>
<button @click="jian">-</button>
</div>
</template>
<script>
Vue.component('lee',{
template:'#lee',
props:['num'],
data(){
return{
a:this.num
}
},
methods:{
jia(){
this.a++
this.$emit('lee',this.a)//创建的自定义事件
},
jian(){
this.a--
this.$emit('lee',this.a)
}
}
})
new Vue({
el:'#box',
data:{
a:12
}
})
</script>
3.在父组件中的子标签中监听该自定义事件并添加一个响应该事件的处理方法
<div id="box">
//用刚才创建的事件绑定这个函数即可
<lee :num='a' @lee="lee">我是父级{{a}}</lee>
</div>
<template id="lee">
<div>
<button @click="jia">+</button>
<slot></slot>
<button @click="jian"> -</button>
</div>
</template>
<script>
Vue.component('lee',{
template:'#lee',
props:['num'],
data(){
return{
a:this.num
}
},
methods:{
jia(){
this.a++
this.$emit('lee',this.a)
},
jian(){
this.a--
this.$emit('lee',this.a)
}
}
})
new Vue({
el:'#box',
data:{
a:12
},
methods:{
//响应事件的处理方法建一个函数来接受子级穿的数据
lee(a){
this.a = a
}
}
})
4.保存修改的文件,在浏览器中点击按钮
子组件向父组件传值成功
总结一下:
子组件中需要以某种方式例如点击事件的方法来触发一个自定义事件
- 将需要传的值作为$emit的第二个参数,该值将作为实参传给响应自定义事件的方法
- 在父组件中注册子组件并在子组件标签上绑定对自定义事件的监听
在通信中,无论是子组件向父组件传值还是父组件向子组件传值,他们都有一个共同点就是有中间介质,子向父的介质是自定义事件,父向子的介质是props中的属性。抓准这两点对于父子通信就好理解了
十三,vue bus
有时候两个组件也需要通信(非父子关系)。当然Vue2.0提供了Vuex,但在简单的场景下,可以使用一个空的Vue实例作为中央事件总线。
参考:http://blog.csdn.net/u013034014/article/details/54574989?locationNum=2&fps=1
例子:https://segmentfault.com/q/1010000007491994
<div id="app">
<c1></c1>
<c2></c2>
</div>
var Bus = new Vue(); //为了方便将Bus(空vue)定义在一个组件中,在实际的运用中一般会新建一Bus.js
Vue.component('c1',{ //这里已全局组件为例,同样,单文件组件和局部组件也同样适用
template:'<div>{{msg}}</div>',
data: () => ({
msg: 'Hello World!'
}),
created() {
Bus.$on('setMsg', content => {
this.msg = content;
});
}
});
Vue.component('c2',{
template: '<button @click="sendEvent">Say Hi</button>',
methods: {
sendEvent() {
Bus.$emit('setMsg', 'Hi Vue!');
}
}
});
var app= new Vue({
el:'#app'
})
在实际运用中,一般将Bus抽离出来:
Bus.js
const Bus = new Vue()
组件调用时先引入
组件1
Vue.component:{
data() {
return {
.........
}
},
methods: {
....
Bus.$emit('log', 120)
},
}
组件2
import Bus from './Bus'
4 {
data() {
return {
.........
}
},
mounted () {
Bus.$on('log', content => {
console.log(content)
});
}
}
但这种引入方式,经过webpack打包后可能会出现Bus局部作用域的情况,即引用的是两个不同的Bus,导致不能正常通信
实际运用二(推荐):
当然也可以直接将Bus注入到Vue根对象中,
import Vue from 'vue'
const Bus = new Vue()
var app= new Vue({
el:'#app',
data:{
Bus
}
})
十四,安装 vue-cli
全局安装
安装 vue-cli前先安装以下插件
cnpm i webpack webpack-cli webpack-dev-server -g
好了在安装以下插件
cnpm i vue-cli -g
vue-cli有三个版本,分别为
- simple 简单的
- webpack webpack版本 复杂的’
- webpack-simple 中和
教程
vue init webpack webpack
//安装的版本 后边的是名字,名字不定
你会看到以下情况 一直按enter即可
在这里可能需要一些时间,需要等待
接下来再看已经安装好了
cd webpack 通过这段代码进入你创建的文件夹
npm run dev 通过这段代码运行这个实例 ,在页面输入http://localhost:8080打开页面
当你把页面写完! 通过npm run build 进行打包
会打包在一个叫dist的文件夹中
当然你再打开打包好后index.html的时候会报错应该是以下所示
解决方法 以下图所示在 /dist/build.js前面加一个点
在子组件中通过this.$root.Bus.$on(),this.$root.Bus.$emit()来调用