vue 學習記錄 [記錄]

 

 

 

vue-cli 腳手架


vue-router 管理視圖

    安裝 + 嵌套 + 視圖切換 + 按需加載

    開始使用vue-router
        i.安裝模塊 npm install vue-router --save
        ii.引入模塊 import VueRouter from 'vue-router'
        iii.做爲Vue插件 Vue.use(VueRouter)
        iv.建立路由實例對象 new VueRouter({...配置參數})
        v.注入vue選項參數 new Vue({router})
        vi.告訴路由渲染位置 <router-view></router-view>


Vuex 狀態管理


axios 數據請求

    攔截 + promise + api





*****************************************************************************************************************
*****************************************************************************************************************

<router-link to='/path'></router-link>
<router-link :to='動態字段名url'></router-link>
<router-link :to='{path:"/path"}'></router-link>

<router-link to='/path' tag='div'></router-link>  生成div 而不是a  (最多見 ul>li tag=li)

改變行爲 event 鼠標移入切換而不是點擊 <router-link to='/path' event='mouseover'></router-link>

new VueRouter
    mode  history
    linkActiveClass  你想要的激活className   (單個要求別的顏色<router-link to='/path' active-class="你要的激活className"></router-link>)

設置統同樣式
    <router-view class='統同樣式className'></router-view>  組件根節點div上(template>div) 繼續加

重定向
    path:*  component:404
    path:*  redirect:'/home'  =  redirect:{path:'/home'}  =   redirect:{name:'Home'} 
            動態設置目標 redirect:(to)=>{
                動態設置目標  console.log(to)
                to = 目標路由對象,就是訪問的路徑的路由信息
                to.path
                return 一個目標 '/home' || {path}  ||  {name}
            }
別名
    alias:'/index'
exact
    / = home  激活狀態 <router-link to='/' exact></router-link> exact精確匹配


<router-link to='/path' tag='li'><a>111</a></router-link>  to裏面的路徑會自動到a上

子路由 children:[]
    不要斜槓  /是以跟路由來的(若是須要 /a/b = /b  則加/)
    設置默認子路由 path:''  直接空
    name 能夠直接給默認子路由
    <router-link :to='{name:"防止過多層路徑/a/b/c/d"}' tag='li'><a>111</a></router-link> 


多視圖
    一個路徑對應多個組件 components:{defalut沒名字的視圖:組件名,視圖名:組件名}   <router-view name='視圖名'></router-view>

滾動行爲
    router裏面  scrollBehavior(to,from,savePosition){
        點擊瀏覽器的前進後退或者切換導航觸發
        to 要進入的目標路由對象 | from 離開的路由對象 | savePosition 滾動條座標  點擊前進後退的時候纔有值
        I. if(savePosition){ return savePosition; }else{ return {x:0,y:0} }
        II. 定位到錨點 if(to.hash){ return { selector: to.hash } }   /a#id
    }


動態路徑
    /a/:id   獲取參數:路由對象的params
    path:'/user/:userId?'  = /a/1 /a  /a/2   '/user:vip?/:userId?' 
    獲取  編譯以前拿 created(){ this.$router   this.$router.params.userId }
        query url查詢對象 | params 動態路由參數

created
    組件複用  created 不在進行一次 - 解決 監聽
    當訪問user  組件會生成一次  生成一次以後  leo1,2,3 都處於複用  鉤子函數 不會執行
    watch:{
        $route(){  // 路徑發生變化 $route 會從新賦值 監控這個屬性 會執行這個函數
            console.log(this.$router.params.userId)
            getData()
        }
    },
    created(){...getData()}   created 
    // 渲染這個組件會調用一次這個生命週期 
    // + 複用這個組件 這個函數不會再次被調用 
    // + 地址一旦發生變化 $route會從新生成一個路由信息對象
    methods:{
        共同方法放置  getData(){}
    }

查詢字符串
    /a?info=follow    /a?info=share
    <router-link exact to='?info=follow'></router-link>
    <router-link exact :to='{path:'',query:{info:'follow'}}'></router-link>     $route.query


過渡動畫
    tansition + 添加刪除css
    v-enter
    <transition>包上要運動元素router-view</transition>
    .v-enter{opacity:0} + .v-enter-to{opacity:1} + .v-enter-active{transition:1s}    ----+ .v-leave{opacity:1} + .v-leave-to{opacity:0} + .v-enter-leave{transition:2s}    ----  出

     一個還沒消失 一個就已經出現 - 解決:定位在同一個位置  (離開和進入同時進行)
    過分模式:in-out(新元素過渡--完成後當前元素過渡離開)
              out-in(當前元素--後新元素進入)
              <transition mode='out-in'>

     .left-enter{transform:translateX(100%)} + .left-enter-to{transform:translateX(0)} + .left-enter-leave{transition:1s}    ----  右入
     ...  0  -100%  1s      0兩個目標能夠不用寫 默認
     <transition name='left'>  會把left作成前綴 去找enter enter-to enter-leave  | mode='out-in' 不要 同時運行

     左右滑 - 下標 或  router設置本身的meta   $.route.meta
     watch:{
        $route(to,from){
            to.meta.index  比較  from.meta.index  給個動態name
        }
    },


前進後退
    back 回退一步   this.$router.back()
    forward 前進一步
    go 指定前進後退步數 this.$router.go(-1)   超出無效  this.$router.go(2)   0刷新當前頁
    push 控制指定的導航(新添加一條記錄) this.$router.push('/home')   ({})
    repalace 替換當前history棧中當前記錄 this.$router.repalace({path:'/home'})


導航鉤子函數
    router.beforeEach((to,from,next)=>{
        console.log('beforeEach')  想要進入導航須要執行next()
        next裏面能夠傳參   (false)不執行
        login可進入  meta打標籤是否須要登陸  to.meta.login --  next('/login')  重定向去login
    })
    router.afterEach((to,from)=>{
        console.log('afterEach')  改變title    window.document.title = to.meta.title
    })
    全局鉤子(beforeEach+afterEach) +單個路由裏面 beforeEnter+ 單個組件鉤子(beforeRouteEnter  .vue裏面export default裏面 同樣寫)
    vue頁面裏面的 beforeRouteEnter 裏面的this指向問題  -  路由鉤子先執行而後組件鉤子 組件實例沒建立 this==undefined
        解決:寫回調   beforeRouteEnter(to,from,next){next(vm=>{vm.test='改變test'})}
        當一級導航裏面擁有二級導航 此時 導航更新 beforeRouteUpdate(to,from,next)
        離開組件 beforeRouteLeave(to,from,next)


項目
    assets > css建議抽離出 + img    css抽離後  @import  css包含css  | import  js包含css
    components > 公共組件
    view > 視圖頁面  + layout
    lib > 庫 + 公共utils
    router > 路由
    
    登陸
        每一個頁面都須要引入utils - 解決:做爲vue插件引入   用this去訪問
         => Vue.use(Router)  this.$router   放在根實例上  new Vue({el:#app....})
         => main.js Vue.prototype.$自定義屬性名uuu = '自定義屬性名uuu'   在組件裏面  this.自定義屬性名uuu 能夠獲取到
         => 那麼   let obj={可是要遵循原則key  install:function(Vue,options){}}  Vue.use(obj,能夠帶本身參數) options爲本身參數
             install:function(Vue,options){
                 Vue.prototype.$uuu = 'uuu'
             }

         Vue插件 用來獲取和設置localStorage存儲
         let local={
             save(key,value){localStorage.setItem(key,JSON.stringify(value))},
             fetch(key){return JSON.parse(localStorage.getItem(key))||{}}
         }
         export default{
             install:function(vm){
                 vm.prototype.$local = local  把東西掛於原型身上
             }
         }
         用  import引入Untils  Vue.use(Untils)   -- 組件上 this.$local

    vue中input 經過ref='nameUUU'找到這個元素  
        獲取input值 this.$refs.nameUUU
        存儲this.$local.save('key',{login:true,userName:username})
        以後跳轉首頁this.$router.push('/')

    
    是否須要登陸 router.beforeEach
    + meta
        本身meta + 父級meta   router.beforeEach(to.matched.some(item=>item.meta,login)?(登陸?next():登陸):next())
        some 只要有一個匹配 返回true
        是否登陸  不能用this  -- 解決:router.app指向根實例 router.app.$local.fetch('key')
    + 記住登陸前的頁面
        router.push({
            path:'/login',
            query:{
                redirect:to.path.slice(1)
            }
        })

    滾動動畫
        <router-link :to="{path:'#abc'}">1111</router-link>
        doc a id=abc href=#abc
        mpn i tween.js --save
        beforeRouteUpdate(to,from,next){
            this.animate(to);next();
        }
        methods:{
            animate(to){
                function animateFunc(time){
                    requestAnimationFrame(animateFunc)
                    TWEEN.update(time)
                }
                if(to.hash){
                    var el = document.getElementById(to.hash.slice(1))
                    var doc = document.getElementByClassName("doc")[0]
                    if(el){
                        animateFunc()
                        new TWEEN.Tween({number:doc.scrollTop開始位置}).to({number:el.offsetTop結束位置},持續500).onUpdate(function(){doc.scrollTop=this.number.toFixed(0)}).start()
                    }
                }
            }
        }

    懶加載 按需加載
        當路由被訪問的時候才加載對應的組件
        如 layout 裏面的 header
            components:{
                headerNav:(resolve)=>{
                    setTimeout(()=>{
                        // i import Header + resolve(Header)
                        resolve(Header)
                        // ii require
                        resolve(require('url'))
                    },2000)
                }
            }
        如 router裏面懶加載
            layout = resolve => require.ensure(['./page/linkParamsQuestion.vue']依賴是數組, ()=>{resolve(require(url))})
        按功能切 兩個組件切成一個組件
            layout = resolve => require.ensure(['./page/linkParamsQuestion.vue']依賴是數組, ()=>{resolve(require(url))},'abc')
            當看到trunk abc  將都爲abc的打包在一塊兒
        能夠直接使用import!!!
            layout = resolve => import('組件url')  可是 import不支持第二個參數 沒辦法將兩個組件js打包成爲一個

    打包的時候若是須要將路徑配置進去
        config>index.js > assetsPublicPath:'/根據本身需求更改'
        單頁面應用只有一個index.html http:sss/uuu 須要指向index -- 解決:服務端配置
        Nginx配置:
            location /{
                root /home/個人應用根目錄
                try_files $uri $uri/ /index.html =404
            }


Vuex 兄弟組件共享數據
    什麼狀況使用:多視圖依賴同一個狀態 || 來自不一樣視圖須要變動同狀態
    仿select  下拉菜單
    F   :is-show.sync='listShow'
    C   this.$emit('update:is-show','uuu')
        獲取初始值 props:['isShow']  --> 計算初始 computed:{ initShow(){return this.isShow} } --> 操做 this.$emit('update:is-show',!this.initShow())
    F -> C  :data="data"  props:['data']
    C 觸發 F 組件事件  this.$emit('事件名',傳值)

    npm install vuex --save  +  Vue.use(Vuex)  + 定義容器 new Vuex.Store()  +  注入根實例 {store}
    store > index.js
    new Vuex.Store({state:{count:100}})   子組件獲取值 this.$store.state.count
    改變值 store 不能直接改變store中的狀態 惟一途徑提交mutations
    new Vuex.Store({
        state:{
            count:100
        },
        mutations:{
            add(state){state.count++}
        }
    })
    頁面提交mutation   this.$store.commit("add")
        this.$store.commit("add",本身參數)   add(state,n){state.count+=n}  參數儘可能爲{} 防止多參數
        或者直接傳對象 this.$store.commit({type:'add',n:5})   add(state,payload)
    提交mutation 必須是同步的 必須立馬變化 若是必定要經過ajx改變狀態 -- 解決:actions
        actions:{
            addA(context){
                setTimeout(()=>{
                    // 改變狀態 提交 mutation
                    context.commit('add',{n:5})
                    還能夠繼續觸發 context.dispatch('addA2',{n:5})
                },1000)
            }
        } 那麼點擊以後不能直接觸發commit而是觸發action   this.$store.dispatch('addA')
        能夠解構賦值
            addA({commit,dispatch}){
                setTimeout(()=>{
                        commit('add',{n:5})
                        dispatch('addA2',{n:5})
                    },1000)
            }
    getters:{
        對狀態進一步處理 超過120再也不加
        函數filterCount(state){
            return state.count>=120?120:state.count 
        }
    }那麼組件裏面 num2(){return this.$store.getters.filterCount} 去getters取值
    Vuex 流程圖


    輔助函數
    要用到輔助函數  import {mapState,mapGetters,mapActions,mapMutation } from 'vuex'  解構賦值 引入
    computed:mapState({
        // num:state=>state.count
        // num:'count'
        // num(state){return state.count + 100}
        // count:'count'
    })
    computed:mapState(['count'])
    computed:{
        abc(){return 123},
        ...mapState(['count'])
        ...mapState({num2:'filterCount'})
    }
    methods:{
        ...mapActions({
            clickName:'要觸發的name addA'
        }),
        ...mapMutation({
            clickName:'要觸發的name add'   傳參@clickName(這裏能夠直接傳參)
        })
    }

    axios   - npm run axios
        import axios from 'axios'
        爲了別的地方也要用 + 寫異步裏  axios.get(url).then((data)=>{console.log(data)}).catch((error)=>{錯誤})







*****************************************************************************************************************
*****************************************************************************************************************



Vue

//https://segmentfault.com/a/1190000009651628
config/index.js
    port
    assetsPublicPath ./


組件懶加載
    component: resolve => require(['./page/linkParamsQuestion.vue'], resolve)
    不用import 訪問到這個頁面的時候纔會去加載相關資源,提升頁面的訪問速度


router傳參數
    1.路由匹配參數
        { path: '/user/:id', component: User }
        對 /user/的路徑作攔截,後面的內容會被映射成id參數
        let id = this.$route.params.id;
        /user/:username/post/:post_id
    2.Get請求傳參
        http://localhost:8080/linkParamsQuestion?age=18
        let age = this.$route.query.age;


編程式導航
    1.<router-link>建立可跳轉連接
        <router-link to="/linkParams/xuxiao">a連接</router-link>
    2.方法裏this.$router.push('xxx')跳轉
        I. this.$router.push('home')
            // 字符串,這裏的字符串是路徑path匹配,不是router配置裏的name
        II. this.$router.push({ path: 'home' })
            // 對象
        III. this.$router.push({ name: 'user', params: { userId: 123 }})
             = this.$router.push({path: `link/${id}`})
            // 命名的路由 這裏會變成 /user/123
        IV. this.$router.push({ path: 'register', query: { plan: 'private' }})
            // 帶查詢參數,變成 /register?plan=private

導航鉤子
    導航跳轉的時候作一些操做(eg:登陸的攔截 | 權限)
    1.全局
        router.js - 全局性的路由攔截
        router.beforeEach((to, from, next)=>{do something;next();});
        router.afterEach   沒有next函數
        能夠配合 meta  作標記 (eg:哪些頁面須要登陸)
    2.路由獨享
        單個路由的跳轉攔截
        {path: '/foo',component: Foo,beforeEnter: (to, from, next) => {...}}
    3.組件內
        beforeRouteEnter | beforeRouteUpdate | beforeRouteLeave


computed
    computed: {
        // 區別在於 method   
        // 若是 name 沒有被修改,下次 get 不會進行重複計算,而 method 則每次調用都會從新計算
        hdlName: function () {  // `this` 指向 vm 實例
          return this.name + '---- 這是 處理以後的字段'
        },
        fullName: {
            // getter setter 解釋: http://www.cnblogs.com/chinajins/p/5996835.html
            // ≈ watch | Watcher主要應用場景是異步或耗時操做
            get: function () { 
                // getter
            },
            set: function (newValue) { 
                // setter 
            }
          }

    }

methods
    methods: {
        go: function () {
          this.$router.push({path: `link/123`})
        }
      }


<input type="text" v-model="name">
class
    v-bind:class="[activeClass, errorClass]"
    v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"
v-if
    01. v-if 是 lazy 的,不會渲染沒有走到的條件
    02. 切換後原來的 dom 會被 destroyed
    <h1 v-if="ok">Yes</h1>
    <h1 v-else>No</h1>
    <template v-if="ok">...</template>
v-show
    <h1 v-show="ok">Hello!</h1>  | v-show 不支持 template 和 v-else
v-for
    <li v-for="(item, index) in items">...</li>
    <template v-for="item in items">...</template>
    v-for 遍歷對象:
        屬性value:<li v-for="value in object">{{ value }}</li>
        key: <div v-for="(value, key) in object">{{ key }} : {{ value }}</div>
        index:<div v-for="(value, key, index) in object">{{ index }}. {{ key }} : {{ value }}</div>
    v-for="n in 10"
    處理 過濾/排序
        ≈  computed + filter
        <li v-for="n in even(numbers)">{{ n }}</li>
        methods: {
          even: function (numbers) {
            return numbers.filter(function (number) {
              return number % 2 === 0
            })
          }
        }
v-on 
    調用 methods 中定義的事件
        $event 
    事件修飾符
        <input v-on:keyup.13="submit">
        <input v-on:....13="submit">
    Key 修飾符
        <a v-on:click.stop="doThis"></a>
        <a v-on:click....="doThis"></a>
表單
    v-model="message"
        修飾符
        <input v-model.lazy="msg" > 加上 lazy 修飾符後就會在 change 事件後才同步
        v-model.number
        v-model.trim
    Checkbox   
        <input type="checkbox" value="Mike" v-model="checkedNames">Mike
        <input type="checkbox" value="John" v-model="checkedNames">John
        <input type="checkbox" v-model="toggle" v-bind:true-value="666" v-bind:false-value="999">----{{toggle}}    
    Radio
        <input type="radio" value="One" v-model="picked">One
        <input type="radio" value="Two" v-model="picked">Two
    Select
        <select v-model="selected">
          <option>A</option>
          <option>B</option>
        </select>
        多選 multiple
        v-for <option v-for="option in options" v-bind:value="option.value">{{ option.text }}</option>


<style></style>屬性可進行配置,scoped表此樣式只在當前頁面有效。lang="xxx"支持less/sass語法規則


created () {
    /* 這個是vue的鉤子函數,當new Vue()實例建立完畢後執行的函數 */
    this.$http.get('/api/goods').then((data) => {
      /* 調用vue的ajax來請求數據,promise語法,並用es6的箭頭函數 */
      this.items = data.body.data
    })
  }







https://segmentfault.com/a/1190000008010666






案例學習:
    head + body + foot
    body > ul > li   -->   li 爲一個組件 傳參入

    li 做爲組件
        template > li  props
        {{ price|dTofixed|dCurrency }}
    html
        import XXX from 'XXX'
        const appData = require('goods.json')
            created () {this.items = appData.goods}
        template v-for="item in items"
            <list :price="item.price" :title="item.title" :img="item.img"></list>
    notice
        <template lang="html">
        <style lang="css" scoped>
        src > assets + components + pages

 

# install vue-cli
$ npm install -g vue-cli
# create a new project using the "webpack" boilerplate
$ vue init webpack my-project
# install dependencies and go!
$ cd my-project
$ npm install
$ npm run dev
CLI

 

 

 https://segmentfault.com/a/1190000008010666css

 

---------------------------------------------------------------------------------------------------------html

 

yarnvue

  http://blog.csdn.net/guoquanyou/article/details/61199935webpack

  npm install -g yarnios

 

 淺學Vuegit

  index html  |    由於在 index.html 裏面定義了<div id="app"></div>因此就以這個組件做爲主入口es6

  main js   |github

    import 導入相關內容  vue  + app.vue 頁面   +  相關路由 + webpack配置文件web

    相關配置ajax

 

     路由器會建立一個 App 實例,而且掛載到選擇符 #app 匹配的元素上。

  路由  router  |

    引入模塊  ---   註冊

    引入頁面  ---  配置路由        

      import 'element-ui/lib/theme-chalk/index.css'
      import vuetest01 from '@/components/th/vuetest01' 

    引入css  報錯  |  webpack 打包的時候沒法識別並轉換成 js,因此就須要配置才能讀取 css 和字體文件  |   yarn add style-loader --save-dev  +  yarn add css-loader --save-dev + yarn add file-loader --save-dev

    定義組件 1  

      const First = { template: '<div><h2>我是第 1 個子頁面</h2></div>' }

 

使用路由搭建單頁應用

  安裝vue-router    ----   yarn add vue-router --save

      import Router from 'vue-router'     註冊   Vue.use(Router)

  ajax請求 請求外部數據以動態改變頁面內容   -------------   yarn add vue-resource --save

      import VueResource from 'vue-resource'  註冊  Vue.use(VueResource)

 

package.json 裏 devDependencies和dependencies的區別

  npm install 安裝模塊或插件 命令把他們寫入到 package.json 文件裏

  --save-dev   安裝的 插件,被寫入到 devDependencies 對象裏面  |  devDependencies  裏面的插件只用於開發環境,不用於生產環境  |  開發的時候須要的依賴項,像一些進行單元測試之類的包。

  --save  安裝的插件,責被寫入到 dependencies 對象裏面  |  dependencies  是須要發佈到生產環境的。 |  依賴的項該是正常運行該包時所須要的依賴項

 

版本號

  github  packageJson

相關文章
相關標籤/搜索