Vue基础入门

vue基础

开发文档

开发文档肯定要比本人写的好,放在最上边。

Vue.js (vuejs.org)

此文档链接以下的内容均为个人见解,如有错误敬请指正!!!

基础学习

在学习阶段,没有配置脚手架:

vue.js //开发版本包含完整的警告和调试模式

vue.min.js //生产版本没有警告

学习思想

我相信学到vue一般都会有一定的编程基础了,有mvc的思想,也就是对数据模型,视图,控制器有所了解。

在传统开发中,我们通过控制器来实现对数据的控制。但是这样有一个弊端,我们需要通过一系列比较麻烦的操作来控制数据在视图中的变化。而在vue中我们需要了解的是MVVM模式,M,V依旧是数据模型,但是控制方式发生了改变,由我们的vm来自动控制。通过这个可以实现数据与模型的实施变化。

说到这里就不得不说一下虚拟dom了,我们在js中通过操作dom树来对标签进行改变,但是这样的改变是费时费力的,我们每一个元素都要通过先获取后更改,也就是需要一步一步走。虚拟dom相当于内存中放了一个集合,把需要渲染的数据一次性拿出,按顺序渲染。

多少无益,我们看例子。

初步入门

<body>
    <div id="app">
        <!-- 插值表达式 内容 data中对象的属性 view -->
        <h1>{{hello}}</h1>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        //新规定:  1.结尾的;号可以省略   2.字符一般使用'单引号'

        //1.实例化VUE对象   函数式编程 vm
        const vm = new Vue({
            //1.定义el元素 要在哪个位置使用vue进行渲染
            el: "#app",
            //2.定义数据对象 model
            data: {
                hello: 'VUE入门案例!!!!'
            }
        })
    </script>
</body>

上述例子中,vm对象会对id为app的标签的innerHtml属性做遍历寻找{{dataname}}这样的东西,来进行一次性渲染。

数据渲染

<body>
  <div id="app">
    <h1>v-cloak未完成渲染不显示</h1>
    <p v-cloak>{{hello}}</p>
    <h1>以优化后的效果进行展现 内部兼容了v-cloak</h1>
    <p v-text="msg"></p>
    <h1>以html解析之后的效果进行展现</h1>
    <p v-html="html"></p>
    <h1>v-pre指令 跳过vue的解析的过程,直接展现数据</h1>
    <p v-pre>{{name}}</p>
    <h1>v-once指令 元素只被解析一次 once后续改变也不会再重新渲染</h1>
    <h3 v-once>{{once}}</h3>
    <h1>v-model 测试双向数据绑定 </h1>
      <!-- 1.服务器将数据给用户展现  2.用户需要传给数据给服务器 -->
    双向数据绑定: <input name="model" v-model="model"/>
    <h1>简单的表达式应用</h1>
    <p>{{isVip?"是":"不是"}}</p>
  </div>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        hello: 'vue案例',
        msg: '测试v-text指令',
        html: '<h1>html效果展现</h1>',
        once: '测试解析次数',
        model: '测试双向数据绑定',
        name: '跳过vue的解析的过程,直接展现数据',
        className1: 'a',
        className2: 'b',
        isVip: true
      }
    })
  </script>
</body>

条件渲染

v-if

<body>
  <div id="app">
    <h1>{{name}}</h1>
    <h2 v-if="age>18">24小时上网</h2>
    <h2 v-else-if="age>12">8小时上网</h2>
    <h2 v-else>不能上网</h2>
  </div>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        name: '张三',
        age: 20
      }
    })
  </script>
</body>

v-show

<body>
  <div id="app">
    <h1>{{name}}</h1>
    <h2 v-show="age>18">24小时上网</h2>
    <h2 v-show="age>12&&age>18">8小时上网</h2>
    <h2 v-show="12>age">不能上网</h2>
  </div>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        name: '张三',
        age: 20
      }
    })
  </script>
</body>

注意两点:

  1. v-if是第一次不符合条件就不渲染,后几次从dom中去除,v-show是不符合条件隐藏(如果需要频繁显示/消失用v-show)。
  2. 在条件判断的时候,目前仅仅支持大于>号

循环渲染

<body>
  <div id="app">
    <h1>循环数组&nbsp; 此处index为下标</h1>
    <p v-for="hobby,index in hobbies">{{index}}.{{hobby}}</p>
    <h1>循环对象&nbsp; 此处index为属性名</h1>
    <p v-for="item,index in users[0]">{{index}}.{{item}}</p>
    <h1>循环对象&nbsp; 此处index为属性名</h1>
    <p v-if="item.age%2==0" v-for="item,index in users">{{index}}.{{item}}</p>
    <h1>循环对象&nbsp; 此处:key为元素标签</h1>
    <p v-for="item,index in users" :key="index">{{index}}.{{item}}</p>
  </div>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        w: 'w',
        hobbies: ['敲鼠标','敲键盘','敲电脑'],
        users:[{
          name: '张三',
          age: 18,
          sex: '男'
        },{
          name: '李四',
          age: 17,
          sex: '男'
        },{
          name: '王五',
          age: 18,
          sex: '男'
        },{
          name: '赵六',
          age: 17,
          sex: '男'
        }]
      }
    });
  </script>
</body>

在Vue2中,v-if的优先级小于v-for

key

具体说一下key吧,在循环中我们引入了:key,他的作用在于:为该元素加上一个唯一的标签。vue有时候会偷懒,就是如果一个地方的值不一样,他可能仅仅更改了值而不去渲染整个标签。我们通常可以把会引起冲突的地方加入key。同时注意:上文中之所以用:key是因为此时的key值是动态的,所谓的双向绑定。如果仅仅是一个固定的可以用固定的标签。

<input key="in"/>

计算属性

计算属性最大的特点在于,缓存计算结果,这样当我们多次调用的时候提高效率(只有参与计算的变量改变才会重新计算)

计算属性默认情况下仅有get,但是我们也可以加入set

<body>
  <div id="app">
    <p>{{fn}}</p>
    <p>{{ln}}</p>
    <h1>{{fullname}}</h1>
    <p v-for="item,index in oddusers" :key="index">{{item}}</p>
  </div>
  <script src="./js/vue.js"></script>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        fn: '张',
        ln: '三',
        users:[{
          name: '张三',
          age: 18,
          sex: '男'
        },{
          name: '李四',
          age: 17,
          sex: '男'
        },{
          name: '王五',
          age: 18,
          sex: '男'
        },{
          name: '赵六',
          age: 17,
          sex: '男'
        }]
      },
      // 在计算后会对缓存,在fn,ln未改变的情况下就不会改变
      computed: {
        fullname:{
          get:function(){
            return this.fn+this.ln;
          },
          set:function(val){
            var names = val.split('')
            this.fn = names[0]
            this.ln = val.substring(1,val.length);
          }
        } ,
        oddusers: function(){
          let res = this.users.filter(function(item,index,arr){
            console.log(index)
            return item.age%2==0
          });
          return res;
        }
      }
    });
  </script>
</body>

侦听属性

<body>
  <div id="app">
    {{msg}}<br>
    {{gsm}}
  </div>
  <script src="./js/vue.js"></script>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        msg: 'hello',
        gsm: ''
      },
      watch:{
        msg:function(val){
          this.gsm = val.split('').reverse().join('');
        }
      }
    });
  </script>
</body>

在侦听和计算属性中,个人感觉如果仅仅是做数字计算,字符拼凑用计算属性可能是一个更好的选择。

样式获取

v-bind:class等同于:class

 <style>
    .page{
      width: 200px;
      height: 200px;
    }
    .a{
      background-color: red;
    }
    .b{
      background-color: seagreen;
    }
    .c{
      border: 2px black solid;
    }
  </style>
</head>
<body>
  <div id="app">
    <h1>变量方式</h1>
    <div class="page" v-bind:class="{a:isTrue}"></div>
    <h1>对象方式</h1>
    <div class="page" v-bind:class="styObj"></div>
    <h1>数组方式</h1>
    <div class="page" v-bind:class="styArr"></div>
    <h1>字符串方式</h1>
    <div class="page" v-bind:class="styStr"></div>
  </div>
  <script src="./js/vue.js"></script>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        isTrue: true,
        styObj: {a: true,c: true},
        styArr: ['b','c'],
        styStr: 'b c'
      }
    });
  </script>
</body>

事件属性

常见的事件属性最常见的是鼠标事件,键盘事件,事件修饰符

点击事件及修饰符
 <style>
    .parent{
      width: 100px;
      height: 100px;
      background-color: skyblue;
    }
    button{
      margin-bottom: 20px;
    }
  </style>
</head>
<body>
  <div id="app">
    <h1>点击事件</h1>
    <button v-on:click="count++">点击增加{{count}}</button>
    <h1>调用无参方法</h1>
    <button v-on:click="sayhi()">无参调用</button>
    <h1>调用有参方法</h1>
    <button v-on:click="saymsg(count)">说出输入信息</button>
    <h1>传入dom事件 $event</h1>
    <button v-on:click="warn('Form cannot be submitted yet.', $event)">
      Submit
    </button>
    <h1>事件属性</h1>
    <!-- 阻止单击事件向上冒泡 -->
    <div class="parent" v-on:click="parent()">
      <button v-on:click.stop="son()">
        不冒泡
      </button>
    </div>

    <!-- 提交事件去除默认事件 -->
    <form action="" method="GET">
      <input type="submit" v-on:click.prevent="onSubmit" value="提交表单"></input>
    </form>

    <!-- 仅触发一次修饰符 -->
    <button v-on:click.once="one">我只触发一次</button>

    <!-- 添加事件监听器时使用事件捕获模式 -->
    <!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
    <div class="parent" v-on:click.capture="parent()">
      <button v-on:click="son()">
        父先动
      </button>
    </div>

    <!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
    <!-- 即事件不是从内部元素触发的 -->
    <div class="parent" v-on:click.self="parent()">
      <button v-on:click="son()">
        自己动
      </button>
    </div>


    </div>
  </div>
  <script>
    let vm = new Vue({
      el: "#app",
      data:{
        count: 0
      },
      methods: {
        sayhi(){
          alert("hi");
        },
        saymsg(msg){
          alert(msg);
        },
        warn: function (message, event) {
    // 现在我们可以访问原生事件对象
          if (event) {
            event.preventDefault()
          }
          alert(message)
        },
        parent(){
          console.log("parent");
        },
        son(){
          console.log("son");
        },
        one(){
          console.log("我只触发一次")
        },
        onsubmit(){
          console.log("表单不能提交");
        }
      }
    });
  </script>
</body>
建盘鼠标事件

请看文档

事件处理 — Vue.js (vuejs.org)

表单属性

<body>
  <div id="app">
    <div>
      <span>姓名:</span>
      <input type="text" name="username" v-model="username"><br>
      <span>单选框:</span>
      <input type="radio" v-for="item,index in sex"  name="username" v-model="usersex" :key="index" :value="item"><br>
      <span>复选框:</span>
      <input type="checkbox" v-for="item,index in hobbies" name="hobbies" v-model="userhobbies" :key="index" :value="item"><br>
      <span>所在城市:</span>
      <select name="cities" v-model="usercity">
        <option value="">无</option>
        <option v-for="item,index in cities" :key="index" :value="item">{{item}}</option>
      </select><br>
      <span>喜欢的城市:</span>
      <select name="cities" multiple v-model="userlikecity">
        <option value="">无</option>
        <option v-for="item,index in cities" :key="index" :value="item">{{item}}</option>
      </select><br>
      <span>备注:</span>
      <textarea name="text" v-model="text"></textarea><br>
      <span>lazy</span>
      <input type="text" v-model.lazy="lazy"><br>
      <span>number</span>
      <input type="text" v-model.number="number"><br>
      <span>trim</span>
      <input type="text" v-model.number="trim"><br>
    </div>
    <div>
      <p>姓名:{{username}}</p>
      <p>性别:{{usersex}}</p>
      <p>爱好:{{userhobbies}}</p>
      <p>所在城市:{{usercity}}</p>
      <p>喜欢的城市:{{userlikecity}}</p>
      <p>备注:{{text}}</p>
      <p>lazy:{{lazy}}</p>
      <p>number:{{number}}</p>
      <p>trim:{{trim}}</p>
    </div>

  </div>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        username: "张三",
        sex: ['男','女'],
        hobbies: ['游泳','读书','跳舞'],
        cities: ['上海','北京','杭州'],
        text: '',
        userhobbies: [],
        usersex: '',
        usercity: '',
        userlikecity: [],
        lazy: ''
      }
    })
  </script>
</body>

v-model

<body>
  <div id="app">
    <input-com :username="username" @childin="change"></input-com>
    <input-com :username="username" @childin="username=$event"></input-com>
    <!-- 此种方式,事件名称把必须是input -->
    <input-com v-model="username"></input-com>
    <h1>{{username}}</h1>
  </div>
  <script>
    Vue.component('input-com',{
      template: `<input type="text" @input="$emit('childin',$event.target.value)" :value="username"/>`,
       //template: `<input type="text" @input="$emit('input',$event.target.value)" :value="username"/>`,
      data:function(){
        return {

        }
      },
      props:['username']
    })
    let vm = new Vue({
      el: "#app",
      data: {
        username: ''
      },
      methods:{
        change:function(data){
          this.username=data;
        }
      }
    });
  </script>
</body>

动画属性

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

通过

  • enter-class

  • enter-active-class

  • enter-to-class (2.1.8+)

  • leave-class

  • leave-active-class

  • leave-to-class (2.1.8+)

    几条来自定义属性。

      <style>
        .context{
          width: 50px;
          height: 50px;
          background-color: springgreen;
          margin: 0 auto;
          margin-bottom: 50px;
        }
        .movie-enter-active, .movie-leave-active {
          transition: opacity .5s;
          width: 100px;
          height: 100px;
        }
        .movie-enter, .movie-leave-to  {
          opacity: 0;
          width: 100px;
          height: 100px;
        }
      </style>
    </head>
    <body>
      <div id="app">
        <button v-on:click="show = !show">
          展示
        </button>
        <transition  name="slider" enter-active-class="animated fadeInRight" leave-active-class="animated fadeOutRight">
          <div v-if="show" class="context"></div>
        </transition>
        <transition  name="movie">
          <div v-if="show" class="context"></div>
        </transition>
      </div>
      <script>
        let vm = new Vue({
          el: "#app",
          data:{
            show: true
          }
        });
      </script>
    </body>
    

组件

入门
<body>
  <div id="app">
    <simple-com></simple-com>
  </div>
  <script>
    let SimpleCom = Vue.component('simple-com',{
      data: function(){
        return {
          msg: 'SimpleCom1'
        }
      },
      // 父元素对子元素传值
      // 组件外边必须包有一层
      template: "<div><h1>msg</h1><h1>msg</h1></div>"
    });
    let vm = new Vue({
      el: "#app",
      data:{
      },
      components:{
        'simple-com':SimpleCom
      }
    });
  </script>
</body>
父传子值
<body>
  <div id="app">
    <!-- 注意传值的参数保存在props中,组件自己的数据保持在data中,两者的命名不能重复 -->
    <!-- 静态属性赋值 -->
    <user-table user-name="张三"></user-table>
    <!-- 动态属性赋值 -->
    <!-- 注意如果user是驼峰命名,例如props是userInfo 则此处属性应为 user-info -->
    <user-table :user-name="'李四'" :user-age="'18'"></user-table>
    <!-- 父值子传 -->
    <user-table :user-name="userName"></user-table>
    <!-- 循环传递类 -->
    <user-table :user-name="userName"  v-for="item,index in users" :key="index" :user="item"></user-table>
  </div>
  <script>
    let userTable =('user-table',{
      props: ['userName','userAge','user'],
      template: '<div><h1>{{msg}}{{userName}}{{userAge}}</h1><h1>我是类传过来的{{user.sex}}</h1></div>',
      data: function(){
        return {
          msg: '姓名:',
        }
      }
    });
    let vm = new Vue({
      el: "#app",
      data: {
        userName: '王五',
        users:[{
          name: '张三',
          age: 18,
          sex: '男'
        },{
          name: '李四',
          age: 17,
          sex: '男'
        },{
          name: '王五',
          age: 18,
          sex: '男'
        },{
          name: '赵六',
          age: 17,
          sex: '男'
        }]
      },
      components: {
        'user-table':userTable
      }
    });
  </script>
</body>
子传父值

通过事件监听,子向父传递参数

<body>
  <div id="app">
    <!--父组件 监听事件并做出反应 -->
    <user-table v-for="item,index in users" @suser='change()' :key="index" :user-name="item"></user-table>
    {{userName}}
  </div>
  <script>
    let userTable =('user-table',{
      props: ['userName'],
      template: `<div>
        <h2>{{userName}}</h2>
        <button @click="select(userName)">选择</button>
        </div>`,
      data: function(){
        return {
          msg: '姓名:',
        }
      },
      methods: {
        select:function(userName){
          // 写入事件并传入值
          this.$emit('suser',userName);
        }
      }
    });
    let vm = new Vue({
      el: "#app",
      data: {
        userName: '王五',
        users:[ '张三','李四', '王五','赵六']
      },
      components: {
        'user-table':userTable
      },
      methods: {
        // 对事件做出反应
        change:function(data){
          this.userName=data;
        }
      }
    });
  </script>
</body>

通过父向子传递方法,子再更改父值

<body>
  <div id="app">
    <!--父组件 监听事件并做出反应 -->
    <user-table v-for="item,index in users" :action='change' :key="index" :user-name="item"></user-table>
    {{userName}}
  </div>
  <script>
    let userTable =('user-table',{
      props: ['userName','action'],
      template: `<div>
        <h2>{{userName}}</h2>
        <button @click="select(userName)">选择</button>
        </div>`,
      data: function(){
        return {
          msg: '姓名:',
        }
      },
      methods: {
        select:function(userName){
          // 写入事件并传入值
          this.action(userName);
        },
      }
    });
    let vm = new Vue({
      el: "#app",
      data: {
        userName: '王五',
        users:[ '张三','李四', '王五','赵六']
      },
      components: {
        'user-table':userTable
      },
      methods: {
        // 对事件做出反应
        change:function(data){
          this.userName=data;
        }
      }
    });
  </script>
</body>
$属性

注意:$children在vue2中有所使用但是vue3已经废弃。

<body>
  <div id="app">
    <!--父组件 监听事件并做出反应 -->
    <user-table v-for="item,index in users" :key="index" :user-name="item"></user-table>
    {{userName}}
  </div>
  <script>
    let userTable =('user-table',{
      props: ['userName'],
      // $root是获取根组件
      // $parent是获取父组件
      template: `<div>
        <h2>{{userName}}</h2>
        <button @click="select(userName)">select选择</button>
        <button @click="$parent.change(userName)">$parent选择</button>
        <button @click="$root.change(userName)">$root选择</button>
        </div>`,
      data: function(){
        return {
          msg: '姓名:',
        }
      },
      methods: {
        select:function(userName){
          // $parent指的是该组件的父组件
          this.$parent.change(userName);
        },
      }
    });
    let vm = new Vue({
      el: "#app",
      data: {
        userName: '王五',
        users:[ '张三','李四', '王五','赵六']
      },
      components: {
        'user-table':userTable
      },
      methods: {
        // 对事件做出反应
        change:function(data){
          this.userName=data;
        }
      }
    });
  </script>
</body>
动态组件
<body>
  <div id="app">
    <!-- 实现动态组件 -->
    <button @click="c(1)">1</button>
    <button @click="c(2)">2</button>
    <button @click="c(3)">3</button>
    <button @click="c(4)">4</button>
    <component :is="com"></component>
    <c5></c5>
  </div>
  <!-- 此种方式写template会轻松一点 -->
  <script type="text/x-template" id="SimpleCom">
    <p>123</p>
  </script>
  <script>
    let c1 = Vue.component('c1',{
      template: "<div><p>1</p></div>"
    });
    let c2 = Vue.component('c2',{
      template: "<div><p>2</p></div>"
    });
    let c3 = Vue.component('c3',{
      template: "<div><p>3</p></div>"
    });
    let c4 = Vue.component('c4',{
      template: "<div><p>4</p></div>"
    });
    let SimpleCom = Vue.component('c5',{
      template: "#SimpleCom"

    });
    let vm = new Vue({
      el: "#app",
      data:{
        com: c1
      },
      components:{
        c1,c2,c3,c4
      },
      methods:{
        c:function(i){
          this.com=this.$options.components['c'+i];
        }
      }
    });
  </script>
</body>

生命周期

我把生命周期放到基础阶段的最后一章,是因为学习到此时看生命周期可能会有更多的了解。尤其是组件化学完后才可以进行看到销毁前和销毁后。

<body>
  <div id="app">
    <button @click="show=!show">点击</button>
    <simple-com v-if="show"></simple-com>
    <div v-bind:class="className">{{msg}}</div>
  </div>
  <script>
      let SimpleCom = Vue.component('simple-com',{
      data: function(){
        return {
          msg: 'SimpleCom1'
        }
      },
      template: "<h1>{{msg}}</h1>",
      beforeDestroy(){
        console.log("销毁前");
      },
      destroyed(){
        console.log("销毁后");
      }
    });
    let vm = new Vue({
      el: "#app",
      data: {
        msg: 'Vue你好',
        className: "aaa",
        show: true
      },
      components:{
        'simple-com':SimpleCom
      },
      methods:{
        w(){
          console.log("w");
        }
      },
      beforeCreate(){
        // data和method尚未挂载
        console.log("初始化前");
        console.log(this.msg)
        console.log(this.w)
      },
      created(){
        // data和method已经挂载
        // 还未进行渲染
        console.log("初始化后");
        console.log(this.msg)
        console.log(this.w)
        console.log(document.querySelector('.aaa'))
      },
      beforeMount(){
        console.log("渲染前");
        console.log(this.msg)
        console.log(this.w)
        console.log(document.querySelector('.aaa'))
      },
      mounted(){
        console.log("渲染后");
        console.log(this.msg)
        console.log(this.w)
        console.log(document.querySelector('.aaa'))
      },
      beforeUpdate(){
        console.log("更新前");
        console.log(this.msg)
      },
      updated(){
        console.log("更新后");
        console.log(this.msg)
      }
    });
  </script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值