vue筆記

vue筆記

一.vue實例

vue的生命周期

  • beforeCreate(創建前),

  • created(創建后),

  • beforeMount(載入前),

  • mounted(載入后),

  • beforeUpdate(更新前),

  • updated(更新后),

  • beforeDestroy(銷毀前),

  • destroyed(銷毀后)

  • (1).beforeCreae(){}

  • (2).created(){}

  • (3).beforMount(){}

  • (4).mounted(){}

    mounted: function () {
    this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
    })
    }

  • (5).beforeUpdate(){}

  • (6).updated(){}

  • (7).不常用周期 activated deactivated beforeDestroy destroyed(Vue 實例銷毀后調用) errorCaptured

二.模板語法

1.插值(是vue實例data里面的數據才能同步到頁面展示)

  • (1).文本
    {{msg}}
    v-text="msg"

    v-model='msg'

    <input type="checkbox" id="checkbox" v-model="checked">

    <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>


    <span>Checked names: {{ checkedNames }}</span>
    </div>

    <div id="example-4">
    <input type="radio" id="one" value="One" v-model="picked">
    <label for="one">One</label>


    <input type="radio" id="two" value="Two" v-model="picked">
    <label for="two">Two</label>


    <span>Picked: {{ picked }}</span>
    </div>
    new Vue({
    el: '#example-4',
    data: {
    picked: ''
    }
    })

    <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>
    new Vue({
    el: '...',
    data: {
    selected: ''
    }
    })
  • (2).原始HTML(后臺渲染的數據通過這種方法插入html,css如果包含scoped則會樣式失效)
    v-html="msg"
  • (3).特性(Mustache 語法不能作用在 HTML 特性上,遇到這種情況應該使用 v-bind 指令:用于一些屬性的綁定)
    :disabled="msg"
    :href="url"
  • (4).使用js
    {{ number + 1 }}
    {{ ok ? 'YES' : 'NO' }}
    {{ message.split('').reverse().join('') }}

2.指令

  •   @click="getInfo()"
    

3.修飾符

  • (1).lazy
    <input v-model.lazy="msg" >
  • (2).number
    <input v-model.number="age" type="number">
  • (3).trim
    <input v-model.trim="msg">

4. 數組的變異方法(mutation method,會改變被這些方法調用的原始數組)會觸發視圖更新,有以下七個

  • push()/pop()/shift()/unshift()/splice()/sort()/reverse()

三.計算屬性和偵聽器

1.計算屬性

  • 對于任何復雜邏輯,你都應當使用計算屬性(計算屬性是基于它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時才會重新求值。可以監聽多個值從而改變)
    var vm = new Vue({
    el: '#example',
    data: {
    message: 'Hello'
    },
    computed: {
    // 計算屬性的 getter
    reversedMessage: function () {
    // 'this' 指向 vm 實例
    return this.message.split('').reverse().join('')
    }
    }
    })
    computed: {
    fullName: {
    // getter
    get: function () {
    return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
    var names = newValue.split(' ')
    this.firstName = names[0]
    this.lastName = names[names.length - 1]
    }
    }
    }

2.偵聽屬性

    watch: {
         firstName: function (val) {
           this.fullName = val + ' ' + this.lastName
         },
         lastName: function (val) {
           this.fullName = this.firstName + ' ' + val
         }
       }

四.class與Style綁定

  • 1.calss動態綁定(isActive取布爾值)
    :class="{className:isActive}"
    :class="{className:isActive,className1:isActive1}"
    :class="classObject"
    data: {
    classObject: {
    active: true,
    'text-danger': false
    }
    }
    :class="[activeClass, errorClass]"
    :class="[isActive ? activeClass : '', errorClass]"
    :class="[{ active: isActive }, errorClass]"
  • 2:style(樣式的動態綁定,vue會自動添加瀏覽器兼容屬性前綴)
    :style="{ color: activeColor, fontSize: fontSize + 'px' }"
    :style="styleObject"
    data: {
    styleObject: {
    color: 'red',
    fontSize: '13px'
    }
    }

五.條件渲染

  • 1.v-if v-else v-else-if 和js的if判斷類似

      <h1 v-if="type==A">Yes</h1>
      <h1 v-else-if="type==B">No</h1>
      <h1 v-else>Not A/B</h1>
    
  • 2.key(Vue 會盡可能高效地渲染元素,通常會復用已有元素而不是從頭開始渲染,如果復用它們就加key給元素添加唯一標識)

  • 3.v-show (v-show 不支持 template 元素,也不支持 v-else)

      <h1 v-show="ok">Hello!</h1>
    
  • 4.v-if和v-show的區別

    • v-if是真正的條件渲染會適當地被銷毀和重建而v-show不管初始條件是什么,元素總是會被渲染,并且只是簡單地基于 CSS 進行切換,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show 較好;如果在運行時條件很少改變,則使用 v-if 較好。

六.列表渲染

  • 1.v-for 指令根據一組數組的選項列表進行渲染。v-for 指令需要使用 item in items 形式的特殊語法,items 是源數據數組并且 item 是數組元素迭代的別名()可以隨便定義。
    <ul> <li v-for="item in items" :key='item.id'> {{ item.message }} </li> </ul> <ul> <li v-for="(item,index) in items" :key='item.id'> {{index+'.'+ item.message }} </li> </ul>

七.事件處理

  • 1.寫法
    @click="counter += 1"
    @:click="greet"
    @:click="greet(id,name)"
    @:click="greet($event)"

  • 2.事件修飾符

      <!-- 阻止單擊事件繼續傳播 -->
      <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>
    
      <!-- 只當在 event.target 是當前元素自身時觸發處理函數 -->
      <!-- 即事件不是從內部元素觸發的 -->
      <div v-on:click.self="doThat">...</div>
      <!-- 點擊事件將只會觸發一次 -->
      <a v-on:click.once="doThis"></a>
      <!-- 滾動事件的默認行為 (即滾動行為) 將會立即觸發 -->
      <!-- 而不會等待 `onScroll` 完成  -->
      <!-- 這其中包含 `event.preventDefault()` 的情況 -->
      <div v-on:scroll.passive="onScroll">...</div>
      <!-- 只有在 `keyCode` 是 13 時調用 `vm.submit()` -->
      <input v-on:keyup.13="submit">
      <!-- 同上 -->
      <input v-on:keyup.enter="submit">
    
      <!-- 縮寫語法 -->
      <input @keyup.enter="submit">
    

八.組件

  • 1.父組件向子組件傳值
    • 1.子組件
      <template> <div> <h2>子組件Child</h2> <p>{{ msg }}</p> </div> </template> <script> export default{ props:['msg'] } </script>
    • 2.父組件
      <template> <div id="app"> <child msg = "hello vue"> </child> </div> </template> <script> import child from './components/Child' export default{ name:'app', components:{ child } } </script>
  • 2.子組件向父組件傳值
    • 1.父組件
      <template> <div id="app"> <h2>父組件Child</h2> <child msg="hello vue" v-on:listenChildEvent="showMsg"></child> </div> </template> <script> export default{ name:'app', methods:{ showMsg:function(data){ alert(data); } } } </script>
    • 2.子組件
      <template> <div> <h2>子組件Child</h2> <p>{{ msg }}</p> <button v-on:click="sendMsgToParent"></button> </div> </template> <script> export default{ props:['msg'], methods:{ sendMsgToParent:function(){ this.$emit('listenChildEvent','this msg from child'); } } } </script>
  • 3.插槽(將自定義的內容插入到子組件中)

    <div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>

    <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>

九.過渡動畫

  • 1.過渡的類名
    • (1)v-enter 定義進入過渡的開始狀態
    • (2)v-enter-active 定義過渡的狀態
    • (3)v-enter-to 定義進入過渡的結束狀態。
    • (4)v-leave 定義離開過渡的開始狀態。
    • (5)v-leave-active 定義過渡的狀態。
    • (6)v-leave-to 定義離開過渡的結束狀態
     `<transition name="fade">
        <p v-if="show">hello</p>
      </transition>
      .fade-enter-active, .fade-leave-active {
        transition: opacity .5s;
      }
      .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
        opacity: 0;
      }`
  • 2.顯性的過渡持續時間
    <transition :duration="1000">...</transition> <transition :duration="{ enter: 500, leave: 800 }">...</transition>

  • 3.JavaScript 鉤子 (當只用 JavaScript 過渡的時候, 在 enter 和 leave 中,回調函數 done 是必須的 。否則,它們會被同步調用,過渡會立即完成。)
    <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>

  • 4.過渡模式

    • (1) in-out:新元素先進行過渡,完成之后當前元素過渡離開。
    • (2) out-in:當前元素先進行過渡,完成之后新元素過渡進入。

十.可復用性 & 組合

1.混入

  • 混入 (mixins) 是一種分發 Vue 組件中可復用功能的非常靈活的方式。同名鉤子函數將混合為一個數組,因此都將被調用。另外,混入對象的鉤子將在組件自身鉤子之前調用

      var mixin = {
                data: function () {
                  return {
                    message: 'hello',
                    foo: 'abc'
                  }
                }
           }
            new Vue({
                mixins: [mixin],
                data: function () {
                  return {
                    message: 'goodbye',
                    bar: 'def'
                  }
                },
                created: function () {
                  console.log(this.$data)
                  // => { message: "goodbye", foo: "abc", bar: "def" }
                }
           })
    
  • 全局混入

    • 也可以全局注冊混入對象。注意使用! 一旦使用全局混入對象,將會影響到 所有 之后創建的 Vue 實例。使用恰當時,可以為自定義對象注入處理邏輯。
      // 為自定義的選項 'myOption' 注入一個處理器。
      Vue.mixin({
      created: function () {
      var myOption = this.$options.myOption
      if (myOption) {
      console.log(myOption)
      }
      }
      })
      new Vue({
      myOption: 'hello!'
      })
      // => "hello!"
  • 2.自定義指令

    • (1)示例
      // 注冊一個全局自定義指令 v-focus
      Vue.directive('focus', {
      // 當被綁定的元素插入到 DOM 中時……
      inserted: function (el) {
      // 聚焦元素
      el.focus()
      }
      })
      //如果想注冊局部指令
      directives: {
      focus: {
      // 指令的定義
      inserted: function (el) {
      el.focus()
      }
      }
      }
      <input v-focus>
    • (2)鉤子函數
      • bind:只調用一次,指令第一次綁定到元素時調用。在這里可以進行一次性的初始化設置。
      • inserted:被綁定元素插入父節點時調用 (僅保證父節點存在,但不一定已被插入文檔中)。
      • update:所在組件的 VNode 更新時調用
      • componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調用。
      • unbind:只調用一次,指令與元素解綁時調用。
    • (3)鉤子函數參數
      • 除了 el 之外,其它參數都應該是只讀的
      • el:指令所綁定的元素,可以用來直接操作 DOM 。
        binding:一個對象,包含以下屬性:
      • vnode:Vue 編譯生成的虛擬節點。移步 VNode API 來了解更多詳情。
      • oldVnode:上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。
        Vue.directive('demo', {
        bind: function (el, binding, vnode) {
        var s = JSON.stringify
        el.innerHTML =
        'name: ' + s(binding.name) + '
        ' +
        'value: ' + s(binding.value) + '
        ' +
        'expression: ' + s(binding.expression) + '
        ' +
        'argument: ' + s(binding.arg) + '
        ' +
        'modifiers: ' + s(binding.modifiers) + '
        ' +
        'vnode keys: ' + Object.keys(vnode).join(', ')
        }
        })
        new Vue({
        el: '#hook-arguments-example',
        data: {
        message: 'hello!'
        }
        })
  • 3.渲染函數
    +運用render函數
    Vue.component('anchored-heading', {
    render: function (createElement) {
    return createElement(
    'h' + this.level, // tag name 標簽名稱
    this.$slots.default // 子組件中的陣列
    )
    },
    props: {
    level: {
    type: Number,
    required: true
    }
    }
    })

  • 4.插件的引入和調用
    // 用 Browserify 或 webpack 提供的 CommonJS 模塊環境時
    var Vue = require('vue')
    var VueRouter = require('vue-router')

              // 不要忘了調用此方法
              Vue.use(VueRouter)
    
  • 5.過濾器(格式:雙花括號插值和 v-bind 表達式 過濾器應該被添加在 JavaScript 表達式的尾部,由“管道”符號指示:)

    {{ message | capitalize }}

      <!-- 在 `v-bind` 中 -->
      <div v-bind:id="rawId | formatId"></div>
    
    • 定義過濾器
      • 過濾器函數總接收表達式的值 (之前的操作鏈的結果) 作為第一個參數。在上述例子中,capitalize 過濾器函數將會收到 message 的值作為第一個參數。

          <!-- 組件內定義 -->
          filters: {
            capitalize: function (value) {
              if (!value) return ''
              value = value.toString()
              return value.charAt(0).toUpperCase() + value.slice(1)
            }
          }
          <!-- 全局定義 -->
          Vue.filter('capitalize', function (value) {
            if (!value) return ''
            value = value.toString()
            return value.charAt(0).toUpperCase() + value.slice(1)
          })
          new Vue({
            // ...
          })
        

十一.路由系統(vue-router)

1.安裝,引入

  • npm install vue-router

  • 入口文件中引入路由配置
    import router from './router'
    new Vue({
    el: '#app',
    router, // 使用路由對象實例
    store, // 使用vuex對象實例
    template: '<App/>',
    components: {App}
    })

  • 路由配置文件

    import Vue from 'vue'
    import Router from 'vue-router'

    import index from '../components/index'

    Vue.use(Router)

    export default new Router({
    routes: [

    {path: "/", redirect: "/index"},

    {path: "/index",name:'index', component: index},

    {
    path: "/user", component: index,
    children:[
    path: 'one', component: UserHome },
    path: 'two', component: UserHome }
    ]
    },

    {
    path: '/',
    components: {
    default: Foo,
    a: Bar,
    b: Baz
    }
    },

    { path: '/a', redirect: '/b' },
    { path: '/a', redirect: { name: 'foo' }},
    { path: '/a', redirect: to => {
    // 方法接收 目標路由 作為參數
    // return 重定向的 字符串路徑/路徑對象
    }},
    ]
    });

  • 2.跳轉寫法

      `<!-- 路由占位符 -->
      <router-view></router-view>
      <!-- 路徑跳轉 -->
      <router-link to='/index'></router-link>
      <!-- name跳轉 -->
      <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>`
    
      <!--  push中使用path時params會被忽略-->
      this.$router.push({name:'/index',params: { userId: 123 }}})
      <!-- 等價于上面 -->
      router.push({ path: `/user/${userId}` })
      this.$router.push({path:'/index',query: { userId: 123 }}})
      <!-- router.replace用法和push一樣,但是他不會向history添加記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄。 -->
      <!-- router.go(n)參數是一個整數,意思是在 history 記錄中向前或者后退多少步 -->
      <!-- 設置 replace 屬性的話,當點擊時,會調用 router.replace() 而不是 router.push(),于是導航后不會留下 history 記錄。 -->
      <router-link :to="{ path: '/abc'}" replace></router-link>
      <!-- 設置 append 屬性后,則在當前(相對)路徑前添加基路徑。例如,我們從 /a 導航到一個相對路徑 b,如果沒有配置 append,則路徑為 /b,如果配了,則為 /a/b -->
      <router-link :to="{ path: 'relative/path'}" append></router-link>
      <!-- 有時候想要 <router-link> 渲染成某種標簽,例如 <li>。 于是我們使用 tag prop 類指定何種標簽,同樣它還是會監聽點擊,觸發導航。 -->
      <router-link to="/foo" tag="li">foo</router-link>
      <!-- 渲染結果 -->
      <li>foo</li>
    
  • 3.路由傳參


      1. { path: '/user/:id', component: User }

        this.$route.params.id`

      1. const User = {
        props: ['id'],
        template: '<div>User {{ id }}</div>'
        }

        const router = new VueRouter({
        routes: [
        { path: '/user/:id', component: User, props: true },

               // 對于包含命名視圖的路由,你必須分別為每個命名視圖添加 `props` 選項:
               {
                 path: '/user/:id',
                 components: { default: User, sidebar: Sidebar },
                 props: { default: true, sidebar: false }
               }
             ]
           })
           <!-- 布爾模式 -->
           <!-- 如果 props 被設置為 true,route.params 將會被設置為組件屬性 -->
           <!-- 對象模式 -->
           const router = new VueRouter({
             routes: [
               { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
             ]
           })
           <!-- 函數模式 -->
           const router = new VueRouter({
             routes: [
               { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
             ]
           })
        
  • 4.HTML5 History 模式
    +這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新加載頁面。(需要后臺配置支持)
    const router = new VueRouter({
    mode: 'history',
    routes: [...]
    })

  • 5.路由檢測

    watch: {
    '$route' (to, from) {
    // 對路由變化作出響應...
    }
    }

    beforeRouteUpdate (to, from, next) {

             next(vm=>{
                    console.log(44444);
                    vm.num=19;
                  })
          }
        }
    
  • 6.路由的滾動行為
    scrollBehavior (to, from, savedPosition) {
    return { x: 0, y: 0 }
    }

    scrollBehavior (to, from, savedPosition) {
    if (to.hash) {
    return {
    selector: to.hash
    }
    }
    }

十二.狀態管理(vuex)

  • 1.Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。(在所有組件都可以調用)

    • 1.npm install vuex --save
      1. main.js
        *import store from './vuex/index'
      1. vuex/index
      • import Vue from 'vue'; import Vuex from 'vuex'; import mutations from './mutations'; import actions from './action'; import getters from './getters'; Vue.use(Vuex); const state = { count:123, title:'', routs:'', info:{name:'高級用戶',phone:'1592****004'}, //個人信息 keyzt:false, //是否打開鍵盤輸入 popUps:false, //是否打開彈窗 routersArr:[1,2,3], //設置進入頁面的數組 saoyisao:true } export default new Vuex.Store({ state, getters, actions, mutations, })
  • 2.State (每個應用將僅僅包含一個 store 實例)

    • (1).在vue組件獲取state對象里面的屬性(可以直接賦值)

        this.$store.state.count
        <!-- 一般在計算屬性中檢測state -->
        computed: {
            count () {
              return this.$store.state.count
            }
      
    1. getter (可以認為是 store 的計算屬性,Getter 接受 state 作為其第一個參數)


      getters: {
      doneTodos: state => {
      return state.todos.filter(todo => todo.done)
      }
      }

      this.$store.getters.doneTodos

    1. Mutation (Vuex 中的 mutation 非常類似于事件,Mutation 接受 state 作為其第一個參數)


      mutations: {
      increment (state) {
      // 變更狀態
      state.count++
      }
      }

      this.$store.commit('increment')

    1. Action (Action 提交的是 mutation,而不是直接變更狀態。Action 可以包含任意異步操作)
      • 和mutations主要區別就是異步

          mutations: {
              increment (state) {
                state.count++
              }
            },
            actions: {
              increment (context) {
                context.commit('increment')
              }
            }
            <!-- 觸發 -->
          this.$store.dispatch('increment')
        
    1. Module (由于使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割:)

         `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 的狀態`
      

十三.axios (請求后臺接口插件)

  • 1.安裝和配置
    • (1). $ npm install axios

    • (2). main.js中配置全局
      import axios from 'axios'
      Vue.prototype.axios = axios; Vue.prototype.axios.defaults.withCredentials = true;

    • (3). 組件中調用axios

        this.$axios.post(url, data).then(function (response) {
                    <!-- 請求成功 -->
                  if (response.data.error != 0) {
                  } else if (response.data.error == 0) {
                  }
                }).catch(function (error) {
                    <!-- 請求失敗 -->
                      console.log(error);
                    });
      

十四.服務器端渲染

  • 1.安裝引入
    • npm install vue vue-server-renderer --save
      / 第 1 步:創建一個 Vue 實例
      const Vue = require('vue')
      const app = new Vue({
      template: <div>Hello World</div>
      })
      // 第 2 步:創建一個 renderer
      const renderer = require('vue-server-renderer').createRenderer()
      // 第 3 步:將 Vue 實例渲染為 HTML
      renderer.renderToString(app, (err, html) => {
      if (err) throw err
      console.log(html)
      // => <div data-server-rendered="true">Hello World</div>
      })

十五.vue項目遇到的一些問題

服務端渲染 多頁面

  • 1.vue打包后css前綴的丟失
    + optimize-css-assets-webpack-plugin 與 autoprefixer 之間互相沖突
    + 注釋webpack.prod.conf.js里面的
    new OptimizeCSSPlugin({
    cssProcessorOptions: config.build.productionSourceMap
    ? { safe: true, map: { inline: false } }
    : { safe: true }
    }),
  • 2.打包app的安卓機物理返回鍵處理(在引入h5+里面的js的時候回失效)

    backs(){/安卓手機返回鍵處理/
    var that = this
    document.addEventListener('plusready', function () {
    var webview = plus.webview.currentWebview();
    var first = null;
    plus.key.addEventListener('backbutton', function () {
    webview.canBack(function (e) {
    if (!first) {
    first = new Date().getTime();//記錄第一次按下回退鍵的時間
    webview.back();
    setTimeout(function () {//1s中后清除
    first = null;
    }, 1000);
    } else {
    if (new Date().getTime() - first < 1000) {//如果兩次按下的時間小于1s,
    that.$MessageBox.confirm('確定退出嗎?', '提示').then(action => {
    plus.runtime.quit();//那么就退出app
    }
    ).catch(() => {
    });
    }
    }
    }
    )
    })
    ;
    })
    ;
    }

    plus.key.addEventListener('backbutton', function() {
    var topWebview = plus.webview.getTopWebview();
    if(topWebview.id !== plus.runtime.appid) {
    topWebview.close('slide-out-right');
    } else {
    plus.nativeUI.confirm('是否退出應用', function(event) {
    var index = event.index;
    if(index === 1) {
    plus.runtime.quit();
    }
    }, '退出', ['取消', '確認']);
    }
    });
    3.火狐和ie的圖片儲存方式不同,(在驗證碼的url后面帶上時間參數)

4.H5app掃一掃功能實現(調用H5的plus方法)

  •           `seac(){
              //創建掃描控件
                          startRecognize() {
                          let that = this;
                          if (!window.plus) return;
                          scan = new plus.barcode.Barcode('bcid');
                          scan.onmarked = onmarked;
                                  function onmarked(type, result, file) {
                                    switch (type) {
                                      case plus.barcode.QR:
                                        type = 'QR';
                                        break;
                                      case plus.barcode.EAN13:
                                        type = 'EAN13';
                                        break;
                                      case plus.barcode.EAN8:
                                        type = 'EAN8';
                                        break;
                                      default:
                                        type = '其它' + type;
                                        break;
                                    }
                                    //掃描完成操作
                                    result = result.replace(/\n/g, '');
                                    if (result.substring(0, 4) != 'http') {
                                      var str = result.split('#')[1]
                                      var arr = str.split('?')
                                      var path = arr[0]
                                      var arr1 = arr[1].split('=')
                                      that.$router.push({path: path, query: {number: arr1[1]}})
                                      that.closeScan();
                                    } else {
                                      if (result.split('#')[0] == that.url) {
                                        var str = result.split('#')[1]
                                        var arr = str.split('?')
                                        var path = arr[0]
                                        var arr1 = arr[1].split('=')
                                        that.$router.push({path: path, query: {number: arr1[1]}})
                                        that.closeScan();
                                      } else {
                                        that.$router.push({path: '/scanurl', query: {url: result}})
                                        that.closeScan();
                                      }
                                    }
                                  }
                                },
                                //開始掃描
                                startScan() {
                                  if (!window.plus) return;
                                  scan.start();
                                },
                                //關閉掃描
                                cancelScan() {
                                  if (!window.plus) return;
                                  scan.cancel();
                                },
                                //關閉條碼識別控件
                                closeScan() {
                                  if (!window.plus) return;
                                  scan.close();
                                },
                                returnGo(){
                                  this.closeScan()
                                  this.$router.go(-1)
                                }
                                /* // 從相冊中選擇二維碼圖片
                                 scanPicture(){
                                 plus.gallery.pick(function (path) {
                                 plus.barcode.scan(path, onmarked, function (error) {
                                 plus.nativeUI.alert('無法識別此圖片');
                                 });
                                 }, function (err) {
                                 console.log('Failed: ' + err.message);
                                 });
                                 },
                                 //返回上一頁
                                 goIndex() {
                                 if (!window.plus) return;
                                 scan.close();
                                 this.$router.go(-1)
                                 },*/
              }`
    
  • 5.關于app狀態欄顏色修改的問題

    • 1.在manifest.json->plus節點下加:

      "statusbar": {
      "immersed": true,
      "background": "#D74B28"
      },

      "launchwebview": {
      "statusbar": {
      "background": "#FF3333"
      }
      },

      "statusbar": {
      "style": "dark"
      }
    • 2.頁面修改

      webview = plus.webview.create('test.html', 'test', {
      statusbar: {
      background: '#1478ee'
      }
      });

      webview = plus.webview.create('test.html', 'test', {
      titleNView: {
      titleText: '測試頁',
      backgroundColor: '#fb6f18'
      }
      });
  • 6.app內容分享功能實現

      mounted(){
            if (window.plus) {
              this.plusReady();
              this.plusBtn = true
            } else {
              this.plusBtn = false
            }
          },
      methods: {
            plusReady() {
              this.updateSerivces();
            },
            /*獲取分享服務列表*/
            updateSerivces() {
              var that = this
              plus.share.getServices(function (s) {
                for (var i in s) {
                  var t = s[i];
                  that.shares[t.id] = t;
                }
              }, function (e) {
                //outSet('獲取分享服務列表失敗:' + e.message);
              });
            },
            shareAction(sb, bh) {
              var that = this
              //outSet('分享操作:');
              if (!sb || !sb.s) {
                //outLine('無效的分享服務!');
                return;
              }
              var msg = {content: '這是一個分享測試', extra: {scene: sb.x}};
              if (bh) {
                msg.href = that.urls;  //分享鏈接
                msg.title = '瑞銀通';  //分享標題
                msg.content = '下載并安裝手機版';
                msg.thumbs = ['_www/logo.png'];
                msg.pictures = ['_www/logo.png'];
              }
              // 發送分享
              if (sb.s.authenticated) {
                //outLine('---已授權---');
                that.shareMessage(msg, sb.s);
              } else {
                //outLine('---未授權---');
                sb.s.authorize(function () {
                  that.shareMessage(msg, sb.s);
                }, function (e) {
                  //outLine('認證授權失敗:' + e.code + ' - ' + e.message);
                });
              }
            },
            shareMessage(msg, s) {
              //outLine(JSON.stringify(msg));
              s.send(msg, function () {
                outLine('分享到"' + s.description + '"成功!');
              }, function (e) {
                //outLine('分享到"' + s.description + '"失敗: ' + JSON.stringify(e));
              });
            },
    
            shareHref(inde) {
              var that = this
              var shareBts = [];
              // 更新分享列表
              var ss = that.shares['weixin'];
              if (navigator.userAgent.indexOf('qihoo') < 0) {  //在360流應用中微信不支持分享圖片
                ss && ss.nativeClient && (shareBts.push({
                  title: '微信好友',
                  s: ss,
                  x: 'WXSceneSession'
                }), shareBts.push({title: '微信朋友圈', s: ss, x: 'WXSceneTimeline'}));
              }
              ss = that.shares['qq'];
              ss && ss.nativeClient && shareBts.push({title: 'QQ', s: ss});
              ss = that.shares['sinaweibo'];
              ss && shareBts.push({title: '新浪微博', s: ss});
              if (shareBts.length > 0) {
                if ((inde == 1 || inde == 2) && shareBts[inde - 1].s.id == 'weixin') {
                  that.shareAction(shareBts[inde - 1], true)
                } else if (inde == 3 && shareBts[inde - 1].s.id == 'qq') {
                  that.shareAction(shareBts[inde - 1], true)
                } else if (inde == 4 && shareBts[inde - 1].s.id == 'sinaweibo') {
                  that.shareAction(shareBts[inde - 1], true)
                } else {
                  that.$Toast('分享失敗')
                }
              } else {
                plus.nativeUI.alert('當前環境無法支持分享鏈接操作!');
              }
            },
            shareBtn(x){
              var that = this
              that.$store.state.tit = that.name
              if (window.plus) {
                that.shareHref(x)
              } else {
                that.$Toast('該設備不支持分享功能')
              }
            }
          }
    
  • 7.app支付
    created(){
    this.plusReady()
    },
    methods: {
    /發送支付信息到后臺/
    postOrders(){
    var that = this
    var url = that.inter.apidomain + '/Recharge/openVip' var data = { info: JSON.parse(JSON.parse(that.resultObj.rawdata).result).alipay_trade_app_pay_response, } that.axios.post(url, data).then(function (response) {
    if (response.data.error != 0) {
    that.Toast(response.data.message) setTimeout(function () { that.router.push({path: '/index'})
    }, 2000)
    } else if (response.data.error == 0) {
    setTimeout(function () {
    that.router.push({path: '/index'}) }, 2000) } }) }, /*支付按鈕*/ /* submitBtn(){ var that = this var url = that.inter.apidomain + ' /Recharge/goToPay'
    var data = {id: that.idss}
    that.axios.post(url, data).then(function (response) { if (response.data.error != 0) { that.Toast(response.data.message)
    } else if (response.data.error == 0) {
    }
    })
    },*/
    plusReady() {
    var that = this
    // 獲取支付通道
    plus.payment.getChannels(function (channels) {
    var txt = '支付通道信息:';
    for (var i in channels) {
    var channel = channels[i];
    if (channel.id == 'alipay') {
    if (channel.id == 'qhpay' || channel.id == 'qihoo') { // 過濾掉不支持的支付通道:暫不支持360相關支付
    continue;
    }
    that.pays[channel.id] = channel;
    txt += 'id:' + channel.id + ', ';
    txt += 'description:' + channel.description + ', ';
    txt += 'serviceReady:' + channel.serviceReady + '; ';
    that.zfbid = channel.id
    that.checkServices(channel);
    }
    }
    }, function (e) {
    });
    },

            // 檢測是否安裝支付服務
            checkServices(pc) {
              if (!pc.serviceReady) {
                var txt = null;
                switch (pc.id) {
                  case 'alipay':
                    txt = '檢測到系統未安裝“支付寶快捷支付服務”,無法完成支付操作,是否立即安裝?';
                    break;
                  default:
                    txt = '系統未安裝“' + pc.description + '”服務,無法完成支付,是否立即安裝?';
                    break;
                }
                plus.nativeUI.confirm(txt, function (e) {
                  if (e.index == 0) {
                    pc.installService();
                  }
                }, pc.description);
              }
            },
            /*支付*/
            pay(id) {
              var that = this
              //檢查是否請求訂單中
              if (that.w) {
                return;
              }
              //outSet('----- 請求支付 -----');
              var url = that.PAYSERVER;
              if (id == 'alipay') {
                url += id;
              } else {
                plus.nativeUI.alert('當前環境不支持此支付通道!', null, '支付');
                return;
              }
              var appid = plus.runtime.appid;
              if (navigator.userAgent.indexOf('StreamApp') >= 0) {
                appid = 'Stream';
              }
              url += '&appid=' + appid + '&total=';
    
              that.w = plus.nativeUI.showWaiting();
              plus.payment.request(that.pays[id], that.orderInfo, function (result) {
                //that.resultObj = JSON.parse(result)
                that.resultObj = result
                plus.nativeUI.alert('支付成功', function () {
                  that.w.close();
                  that.postOrders()
                }, '支付');
              }, function (e) {
                plus.nativeUI.alert('錯誤', null, '支付失敗:' + e.code);
                that.w.close();
                that.$router.push({path: '/index'})
              });
              // 請求支付訂單
              /*var xhr = new XMLHttpRequest();
               xhr.onreadystatechange = function () {
               switch (xhr.readyState) {
               case 4:
               that.w.close();
               that.w = null;
               if (xhr.status == 200) {
               //                var order = xhr.responseText;
               plus.payment.request(that.pays[id], that.orderInfo, function (result) {
               plus.nativeUI.alert('支付成功', function () {
               back();
               }, '支付');
               }, function (e) {
               });
               } else {
               plus.nativeUI.alert('獲取訂單信息失敗!', null, '支付');
               }
               break;
               default:
               break;
               }
               }
               xhr.open('GET', url + 0.01);
               console.log(url + 0.01)
               xhr.send();*/
            }
          }
    
  • 8.對element插件的日期格式進行轉碼
    getSTime1(val) {
    var date = new Date(Date.parse(val));
    this.value1 = date.getFullYear() + "-" + (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + "-" + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
    },

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內容

  • ## 框架和庫的區別?> 框架(framework):一套完整的軟件設計架構和**解決方案**。> > 庫(lib...
    Rui_bdad閱讀 2,941評論 1 4
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,866評論 0 38
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,042評論 0 2
  • ####工作內容1. 自學__markdown__語法。2. 參加培訓課程,聽老師__講解考試題目__。3. 組織...
    djsecret閱讀 266評論 0 1
  • 下了快一個月的雨,整個小城都浸泡在水中,濕得要發霉了,難得今天太陽露了個臉,久違的陽光一掃多日的陰郁。 家鄉生活節...
    熙惜閱讀 344評論 0 0