vue官方实例

 vue实例:

head
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
    <style>
        .active {
            color: skyblue;
        }

        .text-danger {
            color: red;
        }

        div {
            font-size: 14px;
            font-weight: normal;
            color: grey;
        }

        .title {
            font-size: 22px;
            font-weight: bolder;
            color: skyblue;
        }
    </style>
</head>


实例1:
  <div id="app1">
        <div class="title">(1) app1 插值表达式</div>
        {{message}}
    </div>


  var app = new Vue({
            el: "#app1",
            data: {
                message: 'hello vue'
            }
  })


实例2:
 <div id="app2">
        <div class="title">(2) app2 v-bind</div>
        <span v-bind:title="message">鼠标悬停几秒看效果</span>
</div>


   var app2 = new Vue({
            el: "#app2",
            data: {
                message: '页面加载于 ' + new Date().toLocaleString()
            }
   })


实例3:
<div id="app3">
        <div class="title">(3) app3 v-if</div>
        <p v-if="seen">现在你看到我了</p>
</div>


  var app3 = new Vue({
            el: "#app3",
            data: {
                seen: true
            }
 })


实例4:
<div id="app4">
        <div class="title">(4) app4 v-for</div>
        <ol>
            <li v-for="todo in todos">{{todo.text}}</li>
        </ol>
</div>


  var app4 = new Vue({
            el: "#app4",
            data: {
                todos: [
                    { id: 1, text: '学习js' },
                    { id: 2, text: '学习vue' },
                    { id: 3, text: '学习node' },
                ]
            }
  })


实例5:
 <div id="app5">
        <div class="title">(5) app5 v-on:click</div>
        <p>{{message}}</p>
        <button v-on:click="reverseMessage">逆转消息</button>
</div>


   var app5 = new Vue({
            el: '#app5',
            data: {
                message: 'hello vue'
            },
            methods: {
                reverseMessage: function () {
                    this.message = this.message.split('').reverse().join('')
                }
            }
        })


实例6:
 <div id="app6">
        <div class="title">(6) app6-双向数据绑定</div>
        <p>{{message}}</p>
        <input v-model="message">
 </div>


       var app6 = new Vue({
            el: '#app6',
            data: {
                message: 'klll dss'
            }
        })

实例7:
    <div id="app7">
        <div class="title">(7) app7-v-html-组件-绑定class对象</div>
        <div v-bind:class="{active:isActive}">1样式测试-绑定的数据对象定义在模板里</div>
        <div v-bind:class="classObj">2样式测试-绑定的数据对象定义在data中</div>
        <div v-bind:class="classObj1">3样式测试-绑定的数据对象是一个返回对象的计算属性</div>
        <div v-bind:class="[activeClass,errorClass]">4样式测试-把数组传给v-bind:class以应用一个class列表</div>
        <div v-bind:class="[isActive?activeClass:'',errorClass]">5样式测试-根据条件切换列表中的class</div>
        <div v-bind:class="[{active:isActive},errorClass]">6样式测试-根据条件切换列表中的class-数组语法中可以使用对象语法简单</div>
        <div v-bind:style="{color:activeColor,fontSize:fontSize+'px'}">7样式测试-绑定内联样式-对象语法</div>
        <div v-bind:style="styleObject">8样式测试-绑定内联样式对象</div>
        <ol>
            <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"></todo-item>
        </ol>
        <p>Using mustaches: {{ rawHtml }}</p>
        <!-- v-html把其当成html进行解析,span内容将会替换成属性值rawHtml,直接作为html,忽略解析属性值中的数据绑定 -->
        <p>Using v-html directive: <span v-html="rawHtml"></span></p>
    </div>


  // 全局注册组件,app7内的地方都可以引用
        Vue.component('todo-item', {
            props: ['todo'],
            template: `<li v-bind:id="todo.id">{{todo.text}}</li>`
        })


    var app7 = new Vue({
            el: '#app7',
            data: {
                groceryList: [
                    { id: 2, text: '蔬菜' },
                    { id: 3, text: '奶酪' },
                    { id: 4, text: '随便时代开始的但是' }
                ],
                rawHtml: "<span style='color:red'>this should be red</span>",
                isActive: true,
                classObj: {
                    active: false,
                    'text-danger': true
                },
                isActive: true,
                error: null,
                activeClass: 'active',
                errorClass: 'text-danger',
                activeColor: 'red',
                fontSize: 30,
                styleObject: {
                    color: 'red',
                    fontSize: '21px'
                }
            },
            computed: {
                classObj1: function () {
                    return {
                        active: this.isActive && !this.error,
                        'text-danger': this.error && this.error.type === 'fatal'
                    }
                }
            }
        })


实例8:
   <!-- 计算属性 -->
    <div id="app8">
        <div class="title">(8) app8-计算属性</div>
        <p>Original msg:"{{message}}"</p>
        <p>Computed reversed message:"{{reverseMessage}}"</p>
    </div>


 var app8 = new Vue({
            el: '#app8',
            data: {
                message: 'ddd fff'
            },
            computed: {
                // 计算属性的getter
                reverseMessage: function () {
                    return this.message.split('').reverse().join('')
                }
            }
        })


实例9:
 <div id="app9">
        <div class="title">(9) app9-watch</div>
        {{fullName}}
</div>


 var app9 = new Vue({
            el: '#app9',
            data: {
                fName: 'ff',
                lName: 'll',
                // fullName:'ff ll'
            },
            // 可以选择watch监听可以选择computed计算属性,推荐计算属性
            computed: {
                fullName: function () {
                    return this.fName + ' ' + this.lName
                }
            },
            watch: {
                fName: function (val) {
                    this.fullName = val + ' ' + this.lastName
                },
                lName: function (val) {
                    this.fullName = this.fName + ' ' + val
                }
            }
        })


实例10:
  <div id="app10">
        <div class="title">(10) app10-setter</div>
        {{fullNames}}
  </div>


  var app10 = new Vue({
            el: '#app10',
            data: {
                fNames: 'ff',
                lNames: 'll',
                // fullNames:'ff ll'
            },
            // 可以选择watch监听可以选择computed计算属性,推荐计算属性
            computed: {
                fullNames: {
                    get: function () {
                        return this.fNames + ' ' + this.lNames
                    },
                    set: function (newValue) {
                        var names = newValue.split(' ');
                        this.fNames = name[0];
                        this.lNames = names[names.length - 1];
                    }
                }
            }
        })


实例11:
  <div id="app11">
        <div class="title">(11) app11-watch</div>
        <p>
            Ask a yes/no question:
            <input v-model="question">
        </p>
        <p>{{ answer }}</p>
   </div>


     var app11 = new Vue({
            el: '#app11',
            data: {
                question: '',
                answer: 'i cannot give you an answer until you ask a question'
            },
            watch: {
                question: function (newQuestion, oldQuestion) {
                    this.answer = 'waiting for you to stop typing...'
                    this.debouncedGetAnser()
                }
            },
            created() {
                this.debouncedGetAnser = _.debounce(this.getAnswer, 500)
            },
            methods: {
                getAnswer: function () {
                    if (this.question.indexOf('?') === -1) {
                        this.answer = 'Questions usually contain a question mark. ;-)'
                        return
                    }
                    this.answer = 'thisingk...'
                    var vm = this
                    axios.get('https://yesno.wtf/api')
                        .then(function (response) {
                            vm.answer = _.capitalize(response.data.answer)
                        })
                        .catch(function (error) {
                            vm.answer = 'error ' + error
                        })
                }
            }
        })



实例12:
  <div id="app12">
        <div class="title">(12) app12-v-for</div>
        <ul>
            <li v-for="item in items"> {{item.msg}} </li>
        </ul>
        <ul>
            <!-- 唯一key -->
            <li v-for="(item,index) in itemss" v-bind:key="index">{{parentMsg}} - {{index}} - {{item.msg}} </li>
        </ul>
        <div>计算属性computed-数组过滤或排序后的结果</div>
        <ul>
            <li v-for="n in evenNumbers">{{n}}</li>
        </ul>
        <div>methods-数组过滤或排序后的结果</div>
        <ul>
            <li v-for="n in even(numbers)">{{n}}</li>
        </ul>
        <div>将只渲染未完成的todo</div>
        <ul>
            <li v-for="todo in todos" v-if="!todo.isComplete">
                {{todo}}
            </li>
        </ul>
    </div>


     var app12 = new Vue({
            el: '#app12',
            data: {
                items: [
                    { msg: 'fj' },
                    { msg: 'fdss' }
                ],
                parentMsg: 'parent',
                itemss: [
                    { msg: 'dssd' },
                    { msg: 'dsdsde' }
                ],
                numbers: [1, 2, 3, 4, 5],
                todos: [
                    { isComplete: true, value: '12' },
                    { isComplete: false, value: '22' },
                    { isComplete: false, value: '33' }
                ]
            },
            computed: {
                evenNumbers: function () {
                    // filter过滤出能被2整除的元素
                    return this.numbers.filter(function (number) {
                        return number % 2 === 0
                    })
                }
            },
            methods: {
                even: function (numbers) {
                    return numbers.filter(function (number) {
                        return number % 2 === 0
                    })
                }
            }
        })


实例13:
    <div id="app13">
        <div class="title">(13) app12-v-for-todo</div>
        <form v-on:submit.prevent="addNewTodo">
            <label>Add a todo</label>
            <input v-model="newTodoText" id="new-todo" placeholder="E.G. Feed the cat">
            <button>Add</button>
        </form>
        <ul>
            <li is="todo-item" v-for="(todo,index) in todos" v-bind:key="todo.id" v-bind:title="todo.title"
                v-on:remove="todos.splice(index,1)"></li>
        </ul>
    </div>


   Vue.component('todo-item', {
            template: `
                <li>\
                    {{title}}\
                    <button v-on:click="$emit(\'remove\')">Remove</button>\
                </li>\
            `,
            props: ['title']
        })


 var app13 = new Vue({
            el: '#app13',
            data: {
                newTodoText: '',
                todos: [
                    {
                        id: 1,
                        title: 'Do the dishes',
                    },
                    {
                        id: 2,
                        title: 'Take out the trash',
                    },
                    {
                        id: 3,
                        title: 'Mow the lawn'
                    }
                ],
                nextTodoId:4
            },
            methods:{
                addNewTodo:function(){
                    this.todos.push({
                        id:this.nextTodoId++,
                        title:this.newTodoText
                    })
                    this.newTodoText = ''
                }
            }
        })

  

 

  vue-router:

vue router功能:
    嵌套的路由/视图表
    模块化的/基于组件的路由配置
    路由参数/查询/通配符
    基于vue.js过渡系统的视图过渡效果
    细粒度的导航控制
    带有自动激活的css class的链接
    h5历史模式或hash模式,在IE9中自动降级
    自定义的滚动条行为


<router-view> 是最顶层的出口,渲染最高级路由匹配到的组件。同样地,一个被渲染组件同样可以包含自己的嵌套 <router-view>


以/开头的嵌套路径会被当作根路径,则使用嵌套路径无须设置嵌套的路径。

  vue-router传参:

router传参方式:路由匹配参数;query方式传参;params方式传参;
(1)动态路由匹配,路由匹配参数:
     // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
    // 获取参数
     let name = this.$route.params.id; // 链接里的id被封装进了 this.$route.params       
  (2) query  
     this.$router.push('/login/' + this.id);
     this.$route.query.id 
    
    this.$router.push({
      path: '/payment/recharge',
      query: {
        amount: that.amount
      }
    });
    this.$route.query.amount
    
    完全可以在链接后加上?进行传参 
    http://localhost:8080/?id=18
    this.$route.query.id
    
   (3) params
    this.$router.push({
      name: '确认图片',
      params: {
       amount: that.amount
      }
    })
    this.$route.params.amount 

ps:若提供了path,则params会被忽略
 $router && $route:
 $router:router实例,用于路由跳转,
(1)this.$router.push({
      path: '/payment/recharge',
      query: {
        amount: that.amount
      }
    });
(2)this.$router.push({
      name: '确认图片',
      params: {
       amount: that.amount
      }
    })
    
$route:当前激活的路由信息对象,用于获取参数,
(1)this.$route.query.amount
(2)this.$route.params.amount 

  嵌套路由:

嵌套路由:
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
          // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

 编程式导航::

导航方式:
(1)<router-link>创建a标签来定义导航链接(声明式导航)
(2)router.push(location, onComplete?,onAbort?) (编程式导航)
(3)router.replace(location, onComplete?,onAbort?) (编程式导航)
(3)router.go(n) (编程式导航)

 ps:想要导航到不同的URL,则使用router.push方法,该方法会向history栈添加一个新的记录,当用户点击浏览器回退按钮时则回到之前的url。   
 该方法的参数可以是一个字符串路径或者一个描述地址的对象。router.replace不会向history添加新记录,只是替换当前的history记录。
 router.go在history记录中向前或向后后退多少步。
 
 // 字符串,路径path匹配
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由 /register/userId=123
router.push({ name: 'user', params: { id: '1' }})
// 带查询参数,变成 /register?id=1
router.push({ path: 'register', query: { id: '1' }})        
ps:若提供了path,则params会被忽略

  命名路由:

在创建router实例的时候,在routes配置中给某个路由设置名称。
const router = new VueRouter({
    routes: [
        {
            path:'/user/:userId',
            name:'user',
            component:User
        }
    ]
})
// 链接到命名路由方式(1)给router-link的to属性传递一个对象(2)给router.push传递一个对象
<router-link :to="{name:'user', params:{userId:123}}">User</router-link>
router.push({name:'user', params: {userId:123}})

  重定向:

重定向:
    { path: '/a', redirect: '/b' }
    { path: '/a', redirect: { name: 'foo' }}

  导航守卫:

导航守卫:主要用来通过跳转或取消的方式守卫导航。登录的拦截,权限的校验,等
ps:参数或查询的改变并不会触发进入或离开的导航守卫。可以通过$route对象来应对这些变化或使用beforeRouteUpdate的组件内守卫。

全局前置守卫:
const router = new VueRouter({...})
router.beforeEach((to, from, next)=>{
    next()
})
ps:一定要调用next方法来resolve这个钩子,执行效果依赖next方法的调用参数。进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed 
next(false) 中断当前导航,可以判断某些条件下如url改变了则中断,url会重置到from路由对应的地址;
next('/) next({path:'/'}) 跳转到一个不同的地址,当前导航被中断,然后进行一个新的导航;

全局后置钩子:
const router = new VueRouter({...})
router.afterEach((to, from, next)=>{
})

路由独享的守卫:
const router = new VueRouter({
    routes:[
        {
            path:'/foo',
            component:Foo,
            beforeEnter: (to, from, next) => {
                //...
            }
        }
    ]
})

组件内钩子:
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当钩子执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}



完整的导航解析流程:
导航被触发。
在失活的组件里调用离开守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

  路由元信息:

路由元信息:路由配置里的一个属性meta,其是一个对象,可以存放一些key-value,通过路由元信息meta实现不同路由展现不同页面(带不同的meta信息,展示不同页面布局)
routes 配置中的每个路由对象为 路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,他可能匹配多个路由记录
例如,根据上面的路由配置,/foo/bar 这个 URL 将会匹配父路由记录以及子路由记录。
一个路由匹配到的所有路由记录会暴露为 $route 对象 (还有在导航守卫中的路由对象) 的 $route.matched 数组。因此,我们需要遍历 $route.matched 来检查路由记录中的 meta 字段

直接在路由配置的时候,给每个路由添加一个自定义的meta对象,在meta对象中可以设置一些状态,来进行一些操作。用它来做登录校验再合适不过了。

  路由懒加载:

路由懒加载:
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,能提高页面的访问速度。
路由和组件的常用两种懒加载方式:
1.vue异步组件实现路由懒加载  component:resolve => (['需要加载的路由的地址',resolve]) 如component: resolve => require(['./page/linkParamsQuestion.vue'], resolve)
2.es提出的import  const HelloWorld = () => import('需要加载的模块地址')

  

import Vue from 'vue'

import 'normalize.css/normalize.css'// A modern alternative to CSS resets
// 引入animated动画
import '@/styles/lib/animate.min.css'
import '@/styles/lib/layer.css'

import MintUI from 'mint-ui'
import 'mint-ui/lib/style.css'

import './styles/index.scss' // global css
import App from './App'
import router from './router'
import store from './store'
import * as allFilters from './filters/allFilters'
Object.keys(allFilters).forEach(key => {
  Vue.filter(key, allFilters[key])
})

import '@/icons' // icon
// import FastClick from 'fastclick'
// FastClick.attach(document.body);

Vue.filter('changeMemberNum', function(val) {
  return val.replace(/\s/g, '').replace(/(.{4})/g, '$1 ');
})
// import '@/permission' // permission control

// 使用代理的方式请求URLaxios request
// import Axios from 'axios'
// import VueAxios from 'vue-axios'
// Vue.use(VueAxios, Axios)

// 微信js-sdk
const $wx = require('weixin-js-sdk');
Vue.prototype.$wechat = $wx;

import VueQrcode from '@chenfengyuan/vue-qrcode';
Vue.component(VueQrcode.name, VueQrcode);

// 页面加载进度条显示NProgress
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
router.beforeEach((to, from, next) => {
  NProgress.start() // 开启Progress
  NProgress.configure({ ease: 'ease', speed: 500 }); // 配置进度条
  next();
  NProgress.done()
})
router.afterEach(() => {
  NProgress.done() // 结束Progress
})

Vue.use(MintUI)

Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

 

 

  参考 & 感谢:vue官网 & 各路大神

 https://segmentfault.com/a/1190000009651628
posted @ 2019-08-28 21:28  安静的嘶吼  阅读(303)  评论(0)    收藏  举报