Vue学习与研究

作者: MrSong | 来源:发表于2018-03-15 17:36 被阅读7次

    title: Vue学习与研究
    notebook: 编程
    tags: Vue


    没办法,必须学点其他的了,好多移动端朋友都向前端靠拢了。还有不少直接转行的,在一棵树上吊死不可行。

    Vue 基本语法

    • el 绑定标签
    • data 绑定数据
    • methods 绑定事件,界面刷新一次执行一次
    • computed 计算属性,有缓存,数据更改时执行
    • catch 监听数据变化 ,newValue 新数据
    • filters 过滤属性
    <div id="app">
    
    <ul >
      <li v-for='item in formatMovie'>{{item}}</li>
    </ul>
    
    <button v-on:click='add'>添加电影</button>
    
    </div>
    
    <script>
      var vm = new Vue({
        // Vue实例绑定的标签
        el: '#app',
    
        // 数据绑定
        data:{
          movies:[
            {
              name:'捉妖记',
              year:'2016'
            },
            {
              name:'黑豹',
              year:'2018'
            },
            { name:'费事',
              year:'2015'
            }
          ]
        },
        // 监听数据变化 ,newValue 新数据
        watch:{
          movies:function (newValue) {
            console.log(newValue[newValue.length-1].name);
          }
        },
        // 计算属性,与缓存,数据更改是执行
        computed:{
          formatMovie:function () {
            return this.movies.map(function (movie) {
               return movie.name+"("+movie.year+")"
            })
          }
       },
       // 方法,界面刷新一次执行一次
       methods:{
        add:function () {
            this.movies.push({name:'前任',year:'2055'})
        }
       }
    });
    
    
    </script>
    

    filters

    <div id="app">
    
    <div>{{msg | upper(true)}}</div>
    
    </div>
    
    <script>
      var vm = new Vue({
        // Vue实例绑定的标签
        el: '#app',
    
        // 数据绑定
        data:{
          msg:'hello world'
        },
        // 过滤属性
        filters:{
          upper:function (val,isFirstWord) {
            if(isFirstWord) {
              return val.charAt(0).toUpperCase() + val.slice(1);
            }else {
                return val.toUpperCase()
            }
            
          }
        }
       
    });
    
    
    </script>
    

    修改样式style

    • 修改单个属性
    <div style="height:200px;width:200px;" v-bind:style='{backgroundColor:color}'></div>
    <script>
      var vm = new Vue({
        // Vue实例绑定的标签
        el: '#app',
        // 数据绑定
        data:{
          color:'red'
        },
        )}
    </script>
    
    • 修改多个属性
    <div style="height:200px;width:200px;" v-bind:style='styles'></div>
      <script>
      var vm = new Vue({
        // Vue实例绑定的标签
        el: '#app',
        // 数据绑定
        data:{
             styles:{
            backgroundColor:'red',
            'border-radius':'20px'
          }
        },
        )}
        </script>
    
    • 绑定多个style
    <div style="height:200px;width:200px;" v-bind:style="[styles1,styles2]"></div>
    
    <script>
     var vm = new Vue({
        // Vue实例绑定的标签
        el: '#app',
    
        // 数据绑定
        data:{
          color:'yellow'
        },
        computed:{
            styles1:function () {
              return {
                backgroundColor:this.color
              }
            },
              styles2:function () {
              return {
                'border-radius':'10px'
              }
            }
        },
        methods:{
          changeColor:function () {
            if (this.backgroundColor ==='yellow') {
              this.backgroundColor = 'red'
            }else {
               this.backgroundColor = 'yellow'
            }
           
          }
        }
       
    });
    </script>
    

    绑定class

    • 传递单个Class,使用{circle:shape.isRound}
    <style>
      .circle{
              background-color:red;
              width:30px;
              height:30px;
              float:left;
              margin:10px;
              border-radius:15px;
      }
        .square{
              background-color:blue;
              width:30px;
              height:30px;
              float:left;
              margin:10px;
              /*border-radius:15px;*/
      }
        .up{
              background-color:yellow;
              width:30px;
              height:30px;
              float:left;
              margin:10px;
              /*border-radius:15px;*/
      }
    </style>
    
    
    
    <div v-for='shape in shapes' class ='shape' v-bind:class='{circle:shape.isRound,square:!shape.isRound}' ></div>
    
    <script>
      var vm = new Vue({
        // Vue实例绑定的标签
        el: '#app',
    
        // 数据绑定
        data:{
          shapes:[
            {isRound:true},
            {isRound:false}
          ],
    
        }
       
    });
    </script>
    
    • 传递多个Class,使用数组[shape.type]
    
    <div v-for='shape in shapes' class ='shape' v-bind:class='[shape.shape]' ></div>
    
    <script>
      var vm = new Vue({
        // Vue实例绑定的标签
        el: '#app',
    
        // 数据绑定
        data:{
          shapes:[
            {shape:'circle'},
            {shape:'square'}
          ],
    
        }
       
    });
    </script>
    
    • 带有动画的class
    <style>
    // 三角形
     .triangle{
              /*background-color:yellow;*/
              width:0;
              height:0;
                   float:left;
      }
      
      .up{
              border-left: 100px solid transparent;
              border-right: 100px solid transparent;
              border-bottom: 150px solid red;
              /*border-radius:15px;*/
      }
        .down{
    
              border-left: 100px solid transparent;
              border-right: 100px solid transparent;
              border-top: 150px solid blue;
              /*border-radius:15px;*/
      }
      .animation{
        animation: strentch 1.0s ease-out
      }
      @keyframes strentch{
        0%{
          transform: scale(0.4);
        }
        100%{
          transform: scale(1);
        }
    
      }
    </style>
    
    <div v-for='shape in shapes' class ='shape' v-bind:class="[shape.shape,shape.direction?shape.direction:'',{animation:shape.animation}]" >
    </div>
    
    <script>
      var vm = new Vue({
        // Vue实例绑定的标签
        el: '#app',
    
        // 数据绑定
        data:{
          shapes:[
            {shape:'circle',animation:true},
            {shape:'square'},
            {shape:'triangle',direction:'up'},
            {shape:'triangle',direction:'down',animation:true},
          ],
    
        }
       
    });
    </script>
    

    组件

    • 注册一个全局组件
    <div id="app">
      <my-component></my-component>
    </div>
    
    </div>
    
    <script>
      // 注册一个组件
      Vue.component('my-component',{
        template:'<div><button>{{count}}</button></div>',
    
        // data 必须写成函数方式
        data:function () {
          return {count:0}
        }
      })
    
      var vm = new Vue({
        el: '#app'
    });
    </script>
    
    • 局部组件,在哪里用就在哪里引入
    <script>
      // 注册一个组件
      var component = {
        template:'<div><button @click="clickMe">{{count}}</button></div>',
    
        // data 必须写成函数方式
        data:function () {
          return {count:0}
        },
        methods:{
          clickMe:function () {
            this.count ++;
          }
        }
    
      }
      // Vue.component('my-component',component)
    
      var vm = new Vue({
        el: '#app',
        // 局部组件
        components:{
          'my-component':component
      }
    });
    </script>
    

    Vue-cli 目录分析

    image
    • build: 项目构建(webpack)相关代码

    • config: 配置目录

    • node_modules: npm 加载的项目依赖模块

    • src: 这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:

      • api: 封装工具类,如网络等
      • assets: 放置一些图片,如logo等
      • businesses: 各模块的js文件(ps:不同模块需要建不同文件夹进行管理)
      • components: 目录里面放了一个自定义组件文件,如搜索框等
      • less: 共用样式文件
      • plugin: 封装的插件
      • router: 路由,各个界面的分发
      • views: 各界面代码就写在这里(ps:不同模块需要建不同文件夹进行管理)
      • App.vue: 项目入口文件
      • main.js: 项目的核心文件
    • static: 静态资源目录,如图片、字体等

    • test: 初始测试目录,可删除

    • .xxxx文件: 这些是一些配置文件,包括语法配置,git配置等

    • index.html: 首页入口文件,你可以添加一些 meta 信息或统计代码等

    • package.json: 项目配置文件

    • README.md: 项目的说明文档,markdown 格式

    main.js 解惑

    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app-box')
    
    • 上面render: h => h(App)是个简写

    • 来源如下

    • The answer (for anyone else who comes across this), is that render: h => h(App) is shorthand for:

    render: function (createElement) {
        return createElement(App);
    }
    
    • Which can be shortened to:
    render (createElement) {
        return createElement(App);
    }
    
    • Which can again be shortened to (with h being an alias to createElement as noted above):
    render (h){
        return h(App);
    }
    
    • Which is then shortened further to (using ES6 "fat arrow" syntax):
    render: h => h(App);
    

    App.vue 分析

    // 界面模板,提供给外部使用的
    <template>
      <div id="app">
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    // 因为要提供给外部使用,所以要导出
    // 可以在这里提供接口给外部使用
    export default { 
      name: 'app'
    }
    </script>
    
    // 全局样式
    <style lang="less">
    @import '~vux/src/styles/reset.less';
    @import url('./less/common.less');
    body {
      background-color: #fbf9fe;
    }
    </style>
    // </style scoped> 添加scoped定义样式为局部样式
    
    

    index.html

    • 这是项目入口文件
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
        <title>cid</title>
      </head>
      <body>
        <div id="app-box"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    

    package.json

    • 这是项目配置文件,里面包含项目版本信息。依赖相关信息。

    package-lock.json

    • 这个也是配置文件,包含所有的依赖关系

    组件传值

    • 子组件接受传递过来的数据,接受多个
    <template>
        <div>
            <h2>标题:{{msg}}</h2>
        </div>  
    </template>
    
    <script type="text/javascript">
        export default{
            props:['msg','name'] // 接受信息,关键字props
    
            // props:{ // 接受信息,关键字props,可以指定类型
            //     msg:String
            // } 
                // props : { // 接受信息,关键字props,可以指定类型
                // msg : {
                //     type : [String,Number],// 接受多种类型数据
                //     required : true // 必填
                // }
            } 
        }
    </script>
    
    
    <style type="text/css" scoped> // 局部样式
        *{
            color: red;
        }
    </style>
    
    • 父组件向子组件传值
    <template>
      <div id="app-box">
        <MyComponent msg='号可怕' name='昵称'></MyComponent>
        <div>内容来了</div>
      </div>
    </template>
    
    • 子组件想父组件传值
    <template>
        <div>
            <button @click = 'clickBtn'>点我点我</button>
        </div>
    </template>
    
    <script>
        export default {
            methods : {
                clickBtn(){
                    console.log('clickBtn')
                    this.$emit('foClick')// 关键是这个地方
                    // this.$emit('foClick','传递数据到上一级')// 后面的参数传递数据到上一级
                }
            }
        }
    </script>
    
    <template>
      <div id="app-box">
        <div>分享次数:{{count}}</div>
        <div>内容来了</div>
        <myButton @clickBtn = 'foClick'></myButton>
      </div>
    </template>
    
    <script>
    import Vue from 'vue'
    import ButtonComp from './components/ButtonComp'
    Vue.component('myButton',ButtonComp)
      export default {
        data () {
         return {
           count : 0
         }
        },
        methods : {
          foClick () { // 接受子组件的点击事件
            this.count ++;
          }
        }
      }
    </script>
    

    slot 卡槽

    • 在子组件中定义slot可以在使用时替换标签
    • 第一种情况下,不管你在标签中间写什么数据都不会显示
    • 第二种情况下,添加的数据会自动加载到标签里
    // 子组件
    <template>
        <div>标题:{{msg}}</div>  // 1
        <!-- <div><slot>标题:{{msg}}</slot></div> // 2-->
    </template>
    
    // 父组件
        <MyComponent><p>啦啦啦</p></MyComponent> //1
        <MyComponent><p>啦啦啦</p></MyComponent> //2
    
    // 结果
        <h2 data-v-7920ea77="">标题:哈哈哈哈</h2> // 1
        <div data-v-7920ea77=""><p data-v-7920ea77="">啦啦啦</p></div> // 2
    
    • slot 也可以指定名字
    // 定义
    <template>
        <!-- <h2>标题:{{msg}}</h2>  -->
        <div>
            <slot name = 'one'>标题:{{msg}}</slot>
            <slot name = 'two'>标题:{{msg}}</slot>
        </div>
    </template>
    
    
    // 引用
    <MyComponent>
        <p slot = 'one'>啦啦啦111</p>
        <p slot = 'two'>啦啦啦222</p>
    </MyComponent>
    

    Vue错误

    • image
    • 找不到属性,很有可能是this指向有问题,在函数内部再次调用其他函数时最好不要直接写this
      可以考虑下面写法。

    methods: {
      clickToSearch: function () {
        console.log('value' + this.value)
        // 模拟查询数据,获取数据后刷新界面
        var self = this;
        setTimeout(function () {
          // 刷新界面
          self.datas.push('哈哈哈');
          console.log( self.datas)
    
        }, 2000)
    
      }
    }
    
    

    相关文章

      网友评论

        本文标题:Vue学习与研究

        本文链接:https://www.haomeiwen.com/subject/hjghqftx.html