VueJs

读音 viewJs, 一个mvvm前端框架,和angular类似,但是比较小巧,容易上手。
特点:模板渲染(双向绑定)、模块化(组件)、路由、ajax、数据流、轻量快速
中文官网:https://cn.vuejs.org
2016年10月份发布的2.0版本
 
Vue 不支持Ie8及以下版本,因为Vue使用了IE8无法模拟的ECMAScript 5 特性。
 
浏览器插件 Vue Devtools 方便调试
2.下载好后进入vue-devtools-master工程  执行npm install ----->npm run build.
3.进入shells chrome 修改manifest.json 中的persistent为true
4.打开谷歌浏览器更多工具--->扩展程序—》加载已解压的扩展程序---》添加工程中的shells-->chrome的内容。
 
引入方式:
script标签引入 ,vue会被注册为一个全局变量
NPM安装 npm install vue 需要nodejs
 
vue-cli  官方提供的脚手架
1.安装
npm install vue-cli -g
2.初始化项目
vue init webpack my-project
3.安装项目依赖
npm install  //在my-project文件夹下执行
npm run dev 在localhost启动测试服务器
npm run build 生成线上目录 dist
权限不足的话用sudo
 
语法
Vue实例对象
var vm = new Vue({ //全局构造函数
    el:’#myApp’,  //选取数据作用范围 可id class
    data:{
        message:’hello vue’ //创建message变量
    }
});
 
实例生命周期
        beforeCreate:function(){
            console.log("实例创建前");
        },
        created:function(){
            console.log("实例创建完毕后执行");
        },beforMount(挂载)…mounted…beforeUpdate(数据更新)…updated…beforeDestroy(销毁前后)..destroyed...
 
全局API
Vue.set 设置vue对象的属性
Vue.delete 删除vue对象的属性
Vue.component 添加全局组件
Vue.use 使用插件
 
实例选项
el:设置作用范围
data:数据设置 get set
props:接收父组件的数据
Computed:即使计算
method:创建函数
watch:监控
template:模板
filters:过滤器
componts:子组件
reander: h=>h(app) es6 相当于 reder:function(h){ return h(app) } h接受了app方法
 
实例属性
vm.$data 实例的数据对象
vm.$props 当前组件收到的props
vm.$el 实例使用的根dom元素
vm.$parent 父实例
vm.$root 当前组件树的根Vue实例
vm.$children 当前实例的直接子组件
 
实例方法
vm.$watch 监视一个表达式或计算属性函数,回调新值旧值
vm.$set 全局Vue.set
vm.$delete 全局Vue.delete
 
实例事件
 
实例生命周期方法
 
模板语法
文本
{{ data }}  输出变量 双向
<h1 v-text=“message”</h1> 输出变量 双向
<h1 v-html="message"></h1> //输出html内容
<h1 v-once>单向绑定:   {{ message }}</h1> 单向
<h1 v-bind:title=“message”></h1> 属性渲染 简写:title 动态绑定 改变时同步
表达式
{{ number + 1 }}
{{ result ? ’YES’ : ’NO'}}
指令
v-model 双向数据绑定 绑定form元素
v-show 符合表达式时显示 页面是display:none
v-if  符合表达式显示 页面是没有的
提交事件
v-on:submit=“submitForm”   简写@submit=“submitForm"
el:’app’,
methods:{
    submitForm:function(e){
        //事件处理
        e.preventDefault();//阻止提交 如果不写需要在表单处$submit.prevent=“submitForm” 使用修饰符 效果是一样的 阻止提交
    }
}
点击事件
v-on:click
v-bind缩写  v-bind:class => :class
v-on缩写 v-on:click => @click
 
实时计算
computed 
<div id="app">
        <h1>computed</h1>
        {{ username }}
        <input type="text" v-model="first">
        <input type="text" v-model="last">
    </div>
new Vue({
        el: '#app',
        data: {
            first: 'david',
            last: 'bai'
        },
        computed: {
            username: function() {
                return this.first + '-' + this.last;
            }
        }
    });
 
计算setter
computed: {
fullName: {
    get: function () {
return this.firstName + ' ' + this.lastName
    },
    set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
    }
  }
}
 
监视watch
data: {
question: '',
answer: 'I cannot give you an answer until you ask a question!'
  },
watch: {
    // 如果 question 发生改变,这个函数就会运行
    question: function (newQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.getAnswer()
    }
  }
 
绑定css
<div v-bind:class=“{active : isActive}"></div> 表达式为真时显示
<li :class="task.status == 1 ? 'red' : '' " v-for='task in tasks’>
<li :class=“{‘class1’,’class2’,status?’abc’:’’}”  //两个样式加一个条件判断样式
绑定style
<div v-bind:style=“{color:activeColor,fontSize:fontsize+’px'}">
 
条件
      <p v-if='number==1'>1</p>
      <p v-else-if='number==3'>3</p>
      <p v-else>default</p>
key唯一值
<template v-if="loginType === 'username' ">
<label>Username</label>
<inputplaceholder="Enter your username" key="username-input" >
</template>
<templatev-else>
<label>Email</label>
<inputplaceholder="Enter your email address" key="email-input" >
</template>
 
遍历
v-for 
   <li v-for='item in items’> {{item}}<li> //数组
    <li v-for=‘item in items'>{{item.title}}</li> //对象集合 
    <li v-for=‘(item,index) in items’>{{index}} . {{item.title}}</li> //第二个参数作为索引
    <li v-for=‘obj in object’>{{ value }}</li> //遍历对象
    <li v-for=‘(value,key) in object’>{{key}}:{{value}}</li> //第二个参数键名
    <li v-for=‘(value,key,index) in object’>{{index}}</li> //第三个参数为索引
    <li v-for=‘item in items’ :key=’item.id’></li>  //:key 类似于track-by=$index
    <li v-for=‘item in items’ v-if=‘!item.isComplete’></li> 只传递false的
也可以用of 替代in item of items 这是javascript迭代器的语法 
 
v-pre 不需要编译
v-cloak 隐藏未编译的{{}}标签 配合样式使用 [v-cloak]{display:none}
 
组件
//全局组件
Vue.component('my-header',{
  template:'<p>this is my-header </p>'
})
//组件树
//孙子组件
var myheaderChild={
  template:'<p>this is my header Child {{ name }}</p>',
  data (){ //es6 类似data:function(){} 避免引用赋值
    return { name:'mao' }
  }
}
 
//子组件
var myheader={
  template:'<p><my-header-Child></my-header-Child> this is my header </p>',
  components:{
    'my-header-Child':myheaderChild
  }
}
//实例对象
new Vue({
  el:'#app',
  components:{
    'my-header':myheader
  }
})
 
//静态数据传递
<david heading=“usps"></david>
<david heading=“fedex"></david>
<template id=“david-template”>
    {{heading}}
    {{count}}
</teamplate>
//全局注册
Vue.component(‘david’,{
    template:’#david-template’, //模板id
    props:[‘heading’] //变量用作模板内
});
 
因为html不区分大小写 所以驼峰命名用-分开 不要些comA
<com-a number='5'></com-a>
子组件中使用props:['number'], 接受一下 就可以使用了
 
//动态数据传递
<com-a :my-value='myVal'></com-a>
props:['number','my-value’],  {{ myValue }}
 
子组件事件传递
子组件中
this.$emit('my-event',this.msg)
父组件
<com-a number='5' :my-value='myVal' @my-event='getMyEvent'></com-a>
  methods:{
    getMyEvent(param){
      alert(param) //param 从子组件中拿到的数据
    }
  }
 
父组件向子组件插入模版
    <com-a number='5' :my-value='myVal' @my-event='getMyEvent'>
      <p>我来自父组件</p>
    </com-a>
子组件中使用
<slot></slot>
 
插入多个slot 命名插入
      <div slot='header'>我来自header</div>
      <p>我来自父组件</p>
      <div slot='footer'>我来自footer</div>
子组件中
    <slot name='header'></slot>
    <slot></slot>
    <slot name='footer'></slot>
 
动态组件
根据currentView的改变而动态改变组件 类似路由
<p :is="currentView"></p>
data (){
    return{
      currentView:'com-a',
      myVal: 10
    }
  },
 
Keep-alive
    <keep-alive>
      <p :is="currentView"></p>
    </keep-alive>
如果使用keep-alive包含起来,进行切换组件时会将模版缓存起来
 
Css过渡效果
使用transtition组件
    <transition name="fade">
      <p v-show='show'> i am show</p>
    </transition>
 
css过渡
transition组件会根据不同阶段给不同的类名
 进入阶段
V-enter 完全不显示
V-enter-active 进入显示阶段 
 离开阶段
V-leave 已经显示
V-leave-active 到完全不显示
设置样式
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s
}
.fade-enter, .fade-leave-to {
  opacity: 0
}
 
也可以使用animate.css
    <transition
    name="custom-classes-transition"
    enter-active-class="animated tada"
    leave-active-class="animated bounceOutRight"
    >
来自定义样式
 
js过渡
通过事件钩子 来实现过渡
<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"
  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
</transition>
js中
methods: {
  // 进入中
  beforeEnter: function (el) {
    // ...
  },
  // 此回调函数是可选项的设置
  // 与 CSS 结合时使用
  enter: function (el, done) {
    // ...
    done()
  },
  afterEnter: function (el) {
    // ...
  },
  enterCancelled: function (el) {
    // ...
  },
  // 离开时
  beforeLeave: function (el) {
    // ...
  },
  // 此回调函数是可选项的设置
  // 与 CSS 结合时使用
  leave: function (el, done) {
    // ...
    done()
  },
  afterLeave: function (el) {
    // ...
  },
  // leaveCancelled 只用于 v-show 中
  leaveCancelled: function (el) {
    // ...
  }
}
el 当前transition里的元素
 
自定义指令
<p v-color="'red'">v-color自定义指令</p>
directives:{
    color:function(el,binding){
      el.style.color=binding.value
    },
    color2:function(){
 
    }
  },
写在组件中 作用域只在组件中 写在全局vue实例中 则全组件可用
 
mixins
复用混合对象
// 定义一个混合对象
var myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
    }
  }
}
// 定义一个使用混合对象的组件
var Component = Vue.extend({
  mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
 
过滤器
自定义过滤器
<!-- in mustaches -->
{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="rawId | formatId"></div>
 
new Vue({
  filters: {
capitalize: function (value) {
if (!value) return ''
      value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})
 
 
单文件组件
*.vue 结尾 
css使用scoped 则只在组件中使用,否则全局都有这个样式 泄漏到父级
<style scoped></style>
 
vue-router插件
npm install vue-router 
路由
//引入路由
import VueRouter from 'vue-router’
//引入子组件
import about from './components/about'
import news from './components/news'
//使用全局使用
Vue.use(VueRouter)
//实例化router
let router = new VueRouter({
  routes: [
    {
      path:'/about',
      component:about
    },
    {
      path:'/news',
      component:news
    }
  ]
})
//实例Vue
new Vue({ 
  el: '#app',
  router:router
})
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
 <router-link :to="{path:’about’}">about</router-link>
 <router-link :to="{path:'news'}">news</router-link>
<!-- 路由出口 -->
 <router-view></router-view>
 
路由参数
path:'/about/:id’,  http://localhost:8080/#/about/1
:设置id参数 /:id/detail/:color 就必须严格输入detail /about/3/detail/red
获取参数
this.$route.params
添加参数后 路径中必须输入参数 否则无法访问到about
 
router默认使用hash模式 
/#/about
mode: 'history’, 会显示正常的页面url
/about
 
嵌套路由
routes: [
    {
      path:'/about/', //path:'/about/:id',
      component:about,
      children:[
        {
          path:'about1',
          component:about1
        }
      ]
    },
    {
      path:'/news',
      component:news
    }
  ]
子组件只会渲染到第一个父组件 所以about.vue也要增加router-view
about下
<router-link :to="{path:'/about/about1'}">about_about1</router-link>
<router-link to="/about/about1">等于path</router-link>
<router-view></router-view>
 
路由重定向
{ path: '/a', redirect: '/b’ }
 
命名路由
routes: [ { path: '/user/:userId', name: 'user', component: User }
 
命名视图
<router-view class="view two" name="a"></router-view>
 
vuex 状态管理插件
store统一管理中心
component每一个组件更新 通知 store 再从stroe通知每个调用他的更新
npm install vuex
import Vuex from 'vuex'
Vue.use(Vuex)
//实例化store
let store =  new Vuex.Store({
  state:{
    totalPrice:0
  },
  mutations:{
    increment(state,price){
      state.totalPrice +=price
    },
    decrement(state,price){
      state.totalPrice -=price
    }
  }
})
//实例化vue
new Vue({ //只有一个实例
  el: '#app',
  store
})
app.vue页面中访问属性
{{ this.$store.state.totalPrice }}
子组件中
    <button @click="add">add</button>
    <button @click="minus">minus</button>
methods:{
    add(){
      this.$store.commit('increment',this.price)
    },
    minus(){
      this.$store.commit('decrement',this.price)
    }
  }
 
也可以通过action的方式
//实例化store
let store =  new Vuex.Store({
  state:{
    totalPrice:0
  },
  mutations:{
    increment(state,price){
      state.totalPrice +=price
    },
    decrement(state,price){
      state.totalPrice -=price
    }
  },
  actions:{
    increase(context,price){
      //context 当前store
      //api(pic,function(){
          //请求api后 再回调
      //})
      context.commit('increment',price)
    }
  }
})
Add方法中需要调用dispatch actionname
add(){
      //this.$store.commit('increment',this.price)
      this.$store.dispatch('increase',this.price)
},
这样的好处是actions可以和后端接口操作
 
使用getters
let store =  new Vuex.Store({
  state:{
    totalPrice:0
  },
  mutations:{
    increment(state,price){
      state.totalPrice +=price
    },
    decrement(state,price){
      state.totalPrice -=price
    }
  },
  actions:{
    increase(context,price){
      //context 当前store
      //api(pic,function(){
        //请求api后 再回调
      //})
      context.commit('increment',price)
    }
  },
  getters:{
    getTotal(state){
      return 'getters里的' + state.totalPrice
    }
  }
})
前台拿数据{{ this.$store.getters.getTotal }}
这样是一个方法可以加一些判断
 
Modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}
 
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}
 
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
 
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
 
vue-resource插件
npm install vue-resource
import VueResource in ‘vue-resource’
Vue.user(VueResource)
就可以在全局使用this.$http
 
//get请求
this.$http.get(‘getList’).then(function(response){
    //sucuss
    response.data
},function(error){
    //error
})
 
//post请求
this.$http.post(‘update’,{userId:111}).then((response) => { this.newsList = response.data })
 
 
json-server 模拟api数据 
 
Vue-slide 幻灯片插件
Vue-datepicker 日期插件
 
反向代理 https 的有问题 改为http
 
axios http请求
axios.get('user?id=1')
.then(funciton()){
}
 
 
 
 
posted @ 2018-03-28 17:43  海盗船长  阅读(254)  评论(0编辑  收藏  举报