• 【一起来烧脑】一步学会Vue.js系统


    Vuejs是一个构建数据驱动的web界面的库,通过api实现响应的数据绑定和组合的视图组件,Vue.js的核心是一个响应的数据绑定系统,它让数据与DOM保持同步非常简单,一旦创建了绑定,DOM 将与数据保持同步。


    Vue.js 安装

    <script> 标签
    CDN
    NPM

    # 最新稳定版本
    $ npm install vue
    # 最新稳定CSP兼容版本
    $ npm install vue@csp
    

    vue.js提供了一个官方命令工具,可以快速搭建大型单页应用。

    # 全局安装 vue-cli
    $ npm install -g vue-cli
    # 创建一个基于 "webpack" 模板的新项目
    $ vue init webpack my-project
    # 安装依赖
    $ cd my-project
    $ npm install
    $ npm run dev
    

    开发版本

    git clone https://github.com/vuejs/vue.git node_modules/vue
    cd node_modules/vue
    npm install
    npm run build
    

    Bower

    # 最新稳定版本
    $ bower install vue
    

    语法格式如下:

    var vm = new Vue({
      // 选项
    })
    
    <div id="vue_det">
        <h1>site : {{site}}</h1>
        <h1>url : {{url}}</h1>
        <h1>{{details()}}</h1>
    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: '#vue_det',
            data: {
                site: "",
                url: "",
                alexa: ""
            },
            methods: {
                details: function() {
                    return  this.site + " 程序员";
                }
            }
        })
    </script>
    

    Vue构造器中有一个el参数
    它是DOM元素中的id

    <div id = "vue_det"></div>
    
    <div id="vue_det">
        <h1>site : {{site}}</h1>
        <h1>url : {{url}}</h1>
        <h1>Alexa : {{alexa}}</h1>
    </div>
    <script type="text/javascript">
    // 数据对象
    var data = { site: "", url: "", alexa: 10000}
    var vm = new Vue({
        el: '#vue_det',
        data: data
    })
    // 它们引用相同的对象
    document.write(vm.a === data.a) // true
    document.write("<br>")
    // 设置属性也会影响到原始数据
    vm.site = "imooc"
    document.write(data.site + "<br>") // imooc
    // ……反之亦然
    data.alexa = 1234
    document.write(vm.alexa) // 1234
    </script>
    

    Vue 实例
    提供了一些有用的实例属性与方法

    前缀 $

    <div id="vue_det">
        <h1>site : {{site}}</h1>
        <h1>url : {{url}}</h1>
        <h1>Alexa : {{alexa}}</h1>
    </div>
    <script type="text/javascript">
    // 数据对象
    var data = { site: "", url: "", alexa: 10000}
    var vm = new Vue({
        el: '#vue_det',
        data: data
    })
    document.write(vm.$data === data) // true
    document.write("<br>") // true
    document.write(vm.$el === document.getElementById('vue_det')) // true
    </script>
    

    目录

    [外链图片转存失败(img-jDOJm1Ph-1563338047361)(https://upload-images.jianshu.io/upload_images/11158618-6a1fbaa8fb8a4d59.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)]

    模板语法

    文本插值

    <div id="app">
      <p>{{ message }}</p>
    </div>
    

    HTML

    <div id="app">
        <div v-html="message"></div>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        message: '<h1></h1>'
      }
    })
    </script>
    

    属性

    <div id="app">
      <label for="r1">修改颜色</label><input type="checkbox" v-model="class1" id="r1">
      <br><br>
      <div v-bind:class="{'class1': class1}">
        directiva v-bind:class
      </div>
    </div>
    <script>
    new Vue({
        el: '#app',
      data:{
          class1: false
      }
    });
    </script>
    

    表达式

    <div id="app">
        {{5+5}}<br>
        {{ ok ? 'YES' : 'NO' }}<br>
        {{ message.split('').reverse().join('') }}
        <div v-bind:id="'list-' + id"></div>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        ok: true,
        message: '',
        id : 1
      }
    })
    </script>
    

    指令

    <div id="app">
        <p v-if="seen">现在你看到我了</p>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        seen: true
      }
    })
    </script>
    

    参数

    <div id="app">
        <pre><a v-bind:href="url"></a></pre>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        url: ''
      }
    })
    </script>
    
    <a v-on:click="doSomething">
    

    修饰符

    <form v-on:submit.prevent="onSubmit"></form>
    

    用户输入

    <div id="app">
        <p>{{ message }}</p>
        <input v-model="message">
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        message: 'imooc'
      }
    })
    </script>
    
    <div id="app">
        <p>{{ message }}</p>
        <button v-on:click="reverseMessage">反转字符串</button>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        message: 'coding'
      },
      methods: {
        reverseMessage: function () {
          this.message = this.message.split('').reverse().join('')
        }
      }
    })
    </script>
    

    过滤器

    <!-- 在两个大括号中 -->
    {{ message | capitalize }}
    <!-- 在 v-bind 指令中 -->
    <div v-bind:id="rawId | formatId"></div>
    
    <div id="app">
      {{ message | capitalize }}
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        message: 'coding'
      },
      filters: {
        capitalize: function (value) {
          if (!value) return ''
          value = value.toString()
          return value.charAt(0).toUpperCase() + value.slice(1)
        }
      }
    })
    </script>
    

    过滤器可以串联:

    {{ message | filterA | filterB }}
    

    过滤器是JavaScript函数,可以接受参数:

    {{ message | filterA('arg1', arg2) }}
    

    v-bind 缩写

    <!-- 完整语法 -->
    <a v-bind:href="url"></a>
    <!-- 缩写 -->
    <a :href="url"></a>
    

    v-on 缩写

    <!-- 完整语法 -->
    <a v-on:click="doSomething">
    </a><!-- 缩写 -->
    <a @click="doSomething"></a>
    

    条件语句

    <div id="app">
        <p v-if="seen">现在看到了这句话</p>
        <template v-if="ok">
          <h1></h1>
          <p></p>
          <p></p>
        </template>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        seen: true,
        ok: true
      }
    })
    </script>
    

    v-else

    <div id="app">
        <div v-if="Math.random() > 0.7">
          Sorry
        </div>
        <div v-else>
          Not sorry
        </div>
    </div>
    <script>
    new Vue({
      el: '#app'
    })
    </script>
    

    v-else-if

    <div id="app">
        <div v-if="type === 'A'">
          A    </div>
        <div v-else-if="type === 'B'">
          B    </div>
        <div v-else-if="type === 'C'">
          C    </div>
        <div v-else>
          Not A/B/C
        </div>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        type: 'C'
      }
    })
    </script>
    

    v-show

    <h1 v-show="ok">Hello!</h1>
    

    循环语句

    v-for可以绑定数据到数组来渲染一个列表

    <div id="app">
      <ol>
        <li v-for="site in sites">
          {{ site.name }}
        </li>
      </ol>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        sites: [
          { name: 'course' },
          { name: 'class' },
          { name: 'coding' }
        ]
      }
    })
    </script>
    

    v-for可以通过一个对象的属性来迭代数据

    <div id="app">
      <ul>
        <li v-for="value in object">
        {{ value }}
        </li>
      </ul>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        object: {
          name: '慕课网',
          url: 'http://www.imooc.com',
          slogan: '程序员的梦工厂!'
        }
      }
    })
    </script>
    

    v-for也可以循环整数

    <div id="app">
      <ul>
        <li v-for="n in 10">
         {{ n }}
        </li>
      </ul>
    </div>
    

    计算属性

    <div id="app">
      <p>原始字符串: {{ message }}</p>
      <p>计算后反转字符串: {{ reversedMessage }}</p>
    </div>
    <script>
    var vm = new Vue({
      el: '#app',
      data: {
        message: 'imooc'
      },
      computed: {
        // 计算属性的 getter
        reversedMessage: function () {
          // `this` 指向 vm 实例
          return this.message.split('').reverse().join('')
        }
      }
    })
    </script>
    

    computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值

    methods ,在重新渲染的时候,函数总会重新调用执行

    var vm = new Vue({
      el: '#app',  
      data: {
        name: '',
        url: ''
      },
       computed: {
        site: {
          // getter
          get: function () {
            return this.name + ' ' + this.url
          },
          // setter
          set: function (newValue) {
            var names = newValue.split(' ')
            this.name = names[0]
            this.url = names[names.length - 1]
          }
        }
      }})
    // 调用 setter, vm.name 和 vm.url 也会被对应更新
    vm.site = '实战 https:';
    document.write('name: ' + vm.name);
    document.write('<br>');
    document.write('url: ' + vm.url);
    

    监听属性

    可以通过watch来响应数据的变化

    <div id = "computed_props">
        千米 : <input type = "text" v-model = "kilometers">
        米 : <input type = "text" v-model = "meters">
    </div>
    <p id="info"></p>
    <script type = "text/javascript">
        var vm = new Vue({
        el: '#computed_props',
        data: {
            kilometers : 0,
            meters:0
        },
        methods: {
        },
        computed :{
        },
        watch : {
            kilometers:function(val) {
                this.kilometers = val;
                this.meters = val * 1000;
            },
            meters : function (val) {
                this.kilometers = val/ 1000;
                this.meters = val;
            }
        }
        });
        // $watch 是一个实例方法
        vm.$watch('kilometers', function (newValue, oldValue) {
        // 这个回调将在 vm.kilometers 改变后调用
        document.getElementById ("info").innerHTML = "修改前的值" + oldValue + ",修改后的值" + newValue;
    })
    </script>
    

    样式绑定

    Class 与 Style 绑定

    <div class="static" v-bind:class="{ 'class-a': isA, 'class-b': isB }"></div>
    data: {
      isA: true,
      isB: false
    }
    
    <div v-bind:class="classObject"></div>
    data: {
      classObject: {
          'class-a': true,
          'class-b': false
      }
    }
    
    <div v-bind:class="[classA, classB]">
    data: {
      classA: 'class-a',
      classB: 'class-b'
    }
    
    <div v-bind:class="[classA, isB ? classB : '']">
    

    绑定内联样式

    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
    data: {
      activeColor: 'red',
      fontSize: 30
     }
    
    <div v-bind:style="styleObject"></div>
    data: {
      styleObject: {
        color: 'red',
        fontSize: '13px'
      }
    }
    
    <div v-bind:style="[styleObjectA, styleObjectB]">
    

    事件处理器

    v-on指令

    <div id="app">
      <button v-on:click="counter += 1">增加1</button>
      <p>这个按钮被点击了 {{ counter }} 次。</p>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        counter: 0
      }
    })
    </script>
    
    <div id="app">
       <!-- `greet` 是在下面定义的方法名 -->
      <button v-on:click="greet">Greet</button>
    </div>
    <script>
    var app = new Vue({
      el: '#app',
      data: {
        name: 'Vue.js'
      },
      // 在 `methods` 对象中定义方法
      methods: {
        greet: function (event) {
          // `this` 在方法里指当前 Vue 实例
          alert('Hello ' + this.name + '!')
          // `event` 是原生 DOM 事件
          if (event) {
              alert(event.target.tagName)
          }
        }
      }
    })
    // 也可以用 JavaScript 直接调用方法
    app.greet() // -> 'Hello Vue.js!'
    </script>
    
    <div id="app">
      <button v-on:click="say('hi')">Say hi</button>
      <button v-on:click="say('what')">Say what</button></div>
    <script>
    new Vue({
      el: '#app',
      methods: {
        say: function (message) {
          alert(message)
        }
      }
    })
    </script>
    

    事件修饰符

    <!-- 阻止单击事件冒泡 -->
    <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>
    <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
    <div v-on:click.self="doThat">...</div>
    <!-- click 事件只能点击一次,2.1.4版本新增 -->
    <a v-on:click.once="doThis"></a>
    

    按键修饰符

    <!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
    <input v-on:keyup.enter="submit">
    <!-- 缩写语法 -->
    <input @keyup.enter="submit">
    
    按键别名:
    .enter、.tab、.delate、.esc、.space、.up、.down、.left、.right、.ctrl、.alt、.shift、.meta
    

    表单

    <div id="app">
      <p>input 元素:</p>
      <input v-model="message" placeholder="编辑这里">
      <p>消息是: {{ message }}</p>    
      <p>textarea 元素:</p>
      <p style="white-space: pre">{{ message2 }}</p>
      <textarea v-model="message2" placeholder="多行文本输入"></textarea>
    </div>
    <script>
    new Vue({
      el: '#app',
      data: {
        message: '',
        message2: ''
      }
    })
    </script>
    
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
      <select v-model="selected" name="fruit">
        <option value="">选择一个网站</option>
        <option value=""></option>
        <option value=""></option>
      </select>
     
      <div id="output">
          选择的网站是: {{selected}}
      </div>
    </div>
    
    <script>
    new Vue({
      el: '#app',
      data: {
    	selected: '' 
      }
    })
    </script>
    </body>
    </html>
    
    <div id="app">
      <input type="radio" id="" value="" v-model="picked">
      <label for=""></label>
      <br>
      <input type="radio" id="" value="" v-model="picked">
      <label for=""></label>
      <br>
      <span>选中值为: {{ picked }}</span></div>
    <script>
    new Vue({
      el: '#app',
      data: {
        picked : 'coding'
      }
    })
    </script>
    
    <div id="app">
      <p>单个复选框:</p>
      <input type="checkbox" id="checkbox" v-model="checked">
      <label for="checkbox">{{ checked }}</label>
         
      <p>多个复选框:</p>
      <input type="checkbox" id="course" value="course" v-model="checkedNames">
      <label for="course">course</label>
      <input type="checkbox" id="class" value="class" v-model="checkedNames">
      <label for="class">class</label>
      <input type="checkbox" id="coding" value="coding" v-model="checkedNames">
      <label for="coding">coding</label>
      <br>
      <span>选择的值为: {{ checkedNames }}</span></div>
     <script>new Vue({
      el: '#app',
      data: {
        checked : false,
        checkedNames: []
      }
    })
    </script>
    

    过渡

    <div v-if="show" transition="my-transition"></div>
    

    组件

    封装可重用的代码

    注册一个全局组件语法格式如下:

    Vue.component(tagName, options)
    

    tagName 为组件名,options 为配置选项

    <tagName></tagName>
    

    全局组件

    所有的实例都能用全局组件

    <div id="app">
        <w></w>
    </div>
    <script>
    // 注册
    Vue.component('w', {
      template: '<h1>自定义组件!</h1>'
    })
    // 创建根实例
    new Vue({
      el: '#app'
    })
    </script>
    

    局部组件

    <div id="app">
        <w></w>
    </div>
    <script>
    var Child = {
      template: '<h1>自定义组件!</h1>'
    } 
    // 创建根实例
    new Vue({
      el: '#app',
      components: {
        // <> 将只在父模板可用
        'w': Child
      }
    })
    </script>
    

    Prop

    Prop是父组件用来传递数据的一个自定义属性
    父组件的数据需要通过props把数据传给子组件

    子组件需要显式的用props选项声明prop

    <div id="app">
        <child message="hello!"></child>
    </div>
    <script>
    // 注册
    Vue.component('child', {
      // 声明 props
      props: ['message'],
      // 同样也可以在 vm 实例中像 "this.message" 这样使用
      template: '<span>{{ message }}</span>'
    })
    // 创建根实例
    new Vue({
      el: '#app'
    })
    </script>
    

    动态prop

    <div id="app">
        <div>
          <input v-model="parentMsg">
          <br>
          <child v-bind:message="parentMsg"></child>
        </div>
    </div>
    <script>
    // 注册
    Vue.component('child', {
      // 声明 props
      props: ['message'],
      // 同样也可以在 vm 实例中像 "this.message" 这样使用
      template: '<span>{{ message }}</span>'
    })
    // 创建根实例
    new Vue({
      el: '#app',
      data: {
        parentMsg: '父组件内容'
      }
    })
    </script>
    
    <div id="app">
        <ol>
        <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
          </ol>
    </div>
    <script>
    Vue.component('todo-item', {
      props: ['todo'],
      template: '<li>{{ todo.text }}</li>'
    })
    new Vue({
      el: '#app',
      data: {
        sites: [
          { text: 'course' },
          { text: 'class' },
          { text: 'coding' }
        ]
      }
    })
    </script>
    
    <div id="app">
        <ol>
        <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
          </ol>
    </div>
    <script>
    Vue.component('todo-item', {
      props: ['todo'],
      template: '<li>{{ todo.text }}</li>'
    })
    new Vue({
      el: '#app',
      data: {
        sites: [
          { text: 'course' },
          { text: 'class' },
          { text: 'coding' }
        ]
      }
    })
    </script>
    

    prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来

    type可以是下面几种原生构造器:

    String、Number、Boolean、Function、Object、Array

    自定义指令

    bind:只调用一次
    unbind:只调用一次,在指令从元素上解绑时调用

    Vue.directive(id, definition) 方法注册一个全局自定义指令

    Vue.directive('my-directive', {
      bind: function () { 
        // 准备工作
        // 例如,添加事件处理器或只需要运行一次的高耗任务
      },
      update: function (newValue, oldValue) { 
        // 值更新时的工作
        // 也会以初始值为参数调用一次
      },
      unbind: function () {  
        // 清理工作
        // 例如,删除 bind() 添加的事件监听器
      }
    })
    
    <div v-my-directive="someValue"></div>
    
    Vue.directive('my-directive', function (value) {
      // 这个函数用作 update()
    })
    

    自定义过滤器

    Vue.filter()注册一个自定义过滤器

    Vue.filter('reverse', function (value) { 
     return value.split('').reverse().join('')
    })
    

    Vue.js允许通过简单的方法来自定义过滤器,即,利用管道“|”来完成过滤

    混合

    分布复用功能

    // 定义一个混合对象
    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!"
    

    插件

    install

    第一个参数是 Vue 构造器
    一个可选的选项对象

    MyPlugin.install = function (Vue, options) {  
      // 1. 添加全局方法或属性
      Vue.myGlobalMethod = ... 
      // 2. 添加全局资源
      Vue.directive('my-directive', {}) 
      // 3. 添加实例方法
      Vue.prototype.$myMethod = ...
    }
    

    Vue.use()全局方法使用插件:

    // 调用 `MyPlugin.install(Vue)`
    Vue.use(MyPlugin)
    
    也可以传入一个选项对象:
    
    Vue.use(MyPlugin, { someOption: true })
    
    // 通过 Browserify 或 Webpack 使用 CommonJS 兼容模块
    var Vue = require('vue')
    var VueRouter = require('vue-router')
    // 不要忘了调用此方法
    Vue.use(VueRouter)
    

    路由

    通过不同的HRL访问不同的内容

    Vue.js路由需要载入vue-router库

    CDN

    https://unpkg.com/vue-router/dist/vue-router.js
    

    Vue.js + vue-router 可以很简单的实现单页应用

    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <!-- 使用 router-link 组件来导航. -->
        <!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>
    

    请点赞!因为你们的赞同/鼓励是我写作的最大动力!

    欢迎关注达叔小生的简书!

    这是一个有质量,有态度的博客

    [外链图片转存失败(img-BroAgdip-1563338047364)(https://upload-images.jianshu.io/upload_images/11158618-9ab0d3fef85d80ce?imageMogr2/auto-orient/strip|imageView2/2/w/1240)]

  • 相关阅读:
    c# 如何利用异或运算进行简单加密解密
    五分钟读懂UML类图
    深入浅出UML类图
    WPF中DPI的问题
    .NET调用JAVA的WebService方法
    动态调用WebService(C#) (非常实用)
    Docker入门
    idea开发shell脚本并运行
    SpringEl表达式解析
    Navicate 许可证
  • 原文地址:https://www.cnblogs.com/dashucoding/p/11932360.html
Copyright © 2020-2023  润新知