Vue基础

Vue扩展插件

  1. vue-cli : vue脚手架
  2. vue-resource(目前使用axios): ajax请求
  3. vue-router : 路由
  4. vuex : 状态管理
  5. vue-lazyload: 图片懒加载
  6. vue-scroller: 页面滑动开关
  7. mint-ui : 基于vue的UI组件库(移动端)
  8. element-ui : 基于vue的UI组件库(PC端)

Vue基本使用


<div id="app">
	<input type="text" v-model="username">
	<p>Hello, {{username}}p>
div>
<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
	new Vue({
		el: '#app',
		data: {
			username: 'atguigu'
	})
script>

推荐安装google浏览器vue插件监测vue数据变化

模板语法



<div id="app">
  <h2>1. 双大括号表达式h2>
  <p>{{content}}p>
  <p>{{content.toUpperCase()}}p>

  <h2>2. 指令一: 强制数据绑定h2>
  <a href="url">访问指定站点a><br>
  <a v-bind:href="url">访问指定站点2a><br>
  <a :href="url">访问指定站点2a><br>

  <h2>3. 指令二: 绑定事件监听h2>
  <button v-on:click="test">点我button>
  <button @click="test">点我button>

div>


<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#app',
    data: {
      content: 'NBA I Love This Game',
      url: 'http://www.atguigu.com'
    },
    methods: {
      test () {
        alert('好啊!!!')
      }
    }
  })
script>

计算属性与监视


<div id="demo">
  姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
  名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
  
  姓名1(单向): <input type="text" placeholder="Full Name1" v-model="fullName1"><br>
  姓名2(单向): <input type="text" placeholder="Full Name2" v-model="fullName2"><br>
  姓名3(双向): <input type="text" placeholder="Full Name3" v-model="fullName3"><br>

  <p>{{fullName1}}p>
  <p>{{fullName1}}p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  const vm = new Vue({
    el: '#demo',
    data: {
      firstName: 'A',
      lastName: 'B', 
      fullName2: 'A-B'
    },

    // 计算属性配置: 值为对象
    computed: {
      fullName1 () { // 属性的get()
        console.log('fullName1()', this)
        return this.firstName + '-' + this.lastName
      },
		//计算属性中,可以用对象的方式设置get() set()方法 固定写法
      fullName3: {
        // 当获取当前属性值时自动调用, 将返回值(根据相关的其它属性数据)作为属性值
        get () {
          console.log('fullName3 get()')
          return this.firstName + '-' + this.lastName
        },
        // 当属性值发生了改变时自动调用, 监视当前属性值变化, 同步更新相关的其它属性值
        set (value) {// fullName3的最新value值(由用户输入)  A-B23
          console.log('fullName3 set()', value)
          // 更新firstName和lastName
          const names = value.split('-')
          this.firstName = names[0]
          this.lastName = names[1]
        }
      }
    },

    watch: {
      // 配置监视firstName
      firstName: function (value) { // 相当于属性的set
        console.log('watch firstName', value)
        // 更新fullName2
        this.fullName2 = value + '-' + this.lastName
      }
    }
  })

  // 监视lastName
  vm.$watch('lastName', function (value) {
    console.log('$watch lastName', value)
    // 更新fullName2
    this.fullName2 = this.firstName + '-' + value
  })

script>

深度监视并存储到localStorage中

watch:{
	todos: { // 监视todos这个vue的data数组对象
		deep: true, // 表示深度监视
		handler: function(value) { // 这个value就是每一次todos改变后的值
		//将todos最新的值,保存到localStorage中,localStorage中是通过key-value的形式保存的,最好把它转换成json格式存储
		window.localStorage.setItem('todos_key', JSON.stringify(value))
		}
	}
}
//从data中取数据的时候的写法
data () {
	return {
		//从localStorage读取todos,如果localStorage中没有,json.parse就会转换null,所以判断localStorage取出的数据为空时需要让json转换'[]'数组字符串为空数组
		todos: JSON.parse(window.localStorage.getItem('todos_key') || '[]')
	}
}

强制绑定 class 和style

<head>
  <meta charset="UTF-8">
  <title>04_class与style绑定title>
  <style>
    .classA {
      color: red;
    }
    .classB {
      background: blue;
    }
    .classC {
      font-size: 20px;
    }
  style>
head>
<body>



<div id="demo">
  <h2>1. class绑定: :class='xxx'h2>
  <p :class="myClass">xxx是字符串p>
  <p :class="{classA: hasClassA, classB: hasClassB}">xxx是对象p>
  <p :class="['classA', 'classB']">xxx是数组p>

  <h2>2. style绑定h2>
  <p :style="{color:activeColor, fontSize}">:style="{ color: activeColor, fontSize: fontSize + 'px' }"p>

  <button @click="update">更新button>

div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      myClass: 'classA',
      hasClassA: true,
      hasClassB: false,
      activeColor: 'red',
      fontSize: '20px'
    },

    methods: {
      update () {
        this.myClass = 'classB'
        this.hasClassA = !this.hasClassA
        this.hasClassB = !this.hasClassB
        this.activeColor = 'yellow'
        this.fontSize = '30px'
      }
    }
  })
script>
body>

条件指令



<div id="demo">
  <p v-if="ok">表白成功p>
  <p v-else>表白失败p>

  <hr>
  <p v-show="ok">求婚成功p>
  <p v-show="!ok">求婚失败p>

  <button @click="ok=!ok">切换button>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      ok: true,
    }
  })
script>

列表渲染



<div id="demo">
  <h2>测试: v-for 遍历数组h2>
  <ul>
    <li v-for="(p, index) in persons" :key="index">
      {{index}}--{{p.name}}--{{p.age}}
      --<button @click="deleteP(index)">删除button>
      --<button @click="updateP(index, {name:'Cat', age: 16})">更新button>
    li>
  ul>
  <button @click="addP({name: 'xfzhang', age: 18})">添加button>

  <h2>测试: v-for 遍历对象h2>

  <ul>
    <li v-for="(item, key) in persons[1]" :key="key">{{key}}={{item}}li>
  ul>

div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      persons: [
        {name: 'Tom', age:18},
        {name: 'Jack', age:17},
        {name: 'Bob', age:19},
        {name: 'Mary', age:16}
      ]
    },

    methods: {
      deleteP (index) {
      //splice是删除方法 第一个参数 删除对应索引位置的数据 第二个参数 删除几个元素
        this.persons.splice(index, 1) // 调用了不是原生数组的splice(), 而是一个变异(重写)方法
              // 1. 调用原生的数组的对应方法
              // 2. 更新界面
      },

      updateP (index, newP) {
        console.log('updateP', index, newP)
        // this.persons[index] = newP  // vue根本就不知道,并没有改变persons本身,在数组内部发生了变化,但并没有调用变异方法,vue不会更新界面
        this.persons.splice(index, 1, newP)
        // this.persons = [] //直接操作并改变数组本身,界面会发生变化,但是全部清空了
      },

      addP (newP) {
        this.persons.push(newP)
      }
    }
  })
script>

列表的搜索(过滤)和排序



<div id="demo">
  <input type="text" v-model="searchName">
  <ul>
    <li v-for="(p, index) in filterPersons" :key="index">
      {{index}}--{{p.name}}--{{p.age}}
    li>
  ul>
  <div>
    <button @click="setOrderType(2)">年龄升序button>
    <button @click="setOrderType(1)">年龄降序button>
    <button @click="setOrderType(0)">原本顺序button>
  div>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      searchName: '',
      orderType: 0, // 0代表不排序, 1代表降序, 2代表升序
      persons: [
        {name: 'Tom', age:18},
        {name: 'Jack', age:17},
        {name: 'Bob', age:19},
        {name: 'Mary', age:16}
      ]
    },

    computed: {
      filterPersons () {
//        debugger
        // 取出相关数据
        const {searchName, persons, orderType} = this
        let arr = [...persons]
        // 过滤数组
        if(searchName.trim()) {
          arr = persons.filter(p => p.name.indexOf(searchName)!==-1)
        }
        // 排序
        if(orderType) {
          arr.sort(function (p1, p2) {
            if(orderType===1) { // 降序
              return p2.age-p1.age
            } else { // 升序
              return p1.age-p2.age
            }

          })
        }
        return arr
      }
    },

    methods: {
      setOrderType (orderType) {
        this.orderType = orderType
      }
    }
  })
script>

事件处理



<div id="example">

  <h2>1. 绑定监听h2>
  <button @click="test1">test1button>
  <button @click="test2('abc')">test2button>
  <button @click="test3('abcd', $event)">test3button>

  <h2>2. 事件修饰符h2>
  <a href="http://www.baidu.com" @click.prevent="test4">百度一下a>
  <div style="width: 200px;height: 200px;background: red" @click="test5">
    <div style="width: 100px;height: 100px;background: blue" @click.stop="test6">div>
  div>

  <h2>3. 按键修饰符h2>
  <input type="text" @keyup.13="test7">
  <input type="text" @keyup.enter="test7">

div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#example',
    data: {

    },
    methods: {
      test1(event) {
        alert(event.target.innerHTML)
      },
      test2 (msg) {
        alert(msg)
      },
      test3 (msg, event) {
        alert(msg+'---'+event.target.textContent)
      },

      test4 () {
        alert('点击了链接')
      },

      test5 () {
        alert('out')
      },
      test6 () {
        alert('inner')
      },

      test7 (event) {
        console.log(event.keyCode)
        alert(event.target.value)
      }
    }
  })
script>

表单输入绑定


<div id="demo">
  <form action="/xxx" @submit.prevent="handleSubmit">
    <span>用户名: span>
    <input type="text" v-model="username"><br>

    <span>密码: span>
    <input type="password" v-model="pwd"><br>

    <span>性别: span>
    <input type="radio" id="female" value="" v-model="sex">
    <label for="female">label>
    <input type="radio" id="male" value="" v-model="sex">
    <label for="male">label><br>

    <span>爱好: span>
    <input type="checkbox" id="basket" value="basket" v-model="likes">
    <label for="basket">篮球label>
    <input type="checkbox" id="foot" value="foot" v-model="likes">
    <label for="foot">足球label>
    <input type="checkbox" id="pingpang" value="pingpang" v-model="likes">
    <label for="pingpang">乒乓label><br>

    <span>城市: span>
    <select v-model="cityId">
      <option value="">未选择option>
      <option :value="city.id" v-for="(city, index) in allCitys" :key="city.id">{{city.name}}option>
    select><br>
    <span>介绍: span>
    <textarea rows="10" v-model="info">textarea><br><br>

    <input type="submit" value="注册">
  form>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      username: '',
      pwd: '',
      sex: '男',
      likes: ['foot'],
      allCitys: [{id: 1, name: 'BJ'}, {id: 2, name: 'SS'}, {id: 3, name: 'SZ'}],
      cityId: '2',
      info: ''
    },
    methods: {
      handleSubmit () {
        console.log(this.username, this.pwd, this.sex, this.likes, this.cityId, this.info)
        alert('提交注册的ajax请求')
      }
    }
  })
script>

Vue生命周期



<div id="test">
  <button @click="destroyVue">destory vuebutton>
  <p v-if="isShow">尚硅谷IT教育p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#test',
    data: {
      isShow: true
    },

    mounted () { //初始化显示之后 立即调用(1次) 注意这里面最好都使用=>函数,这样在里面使用this会使用vue的对象
      // 执行异步任务设置1000ms定时
      this.intervalId = setInterval(() => {
        console.log('-----')
        this.isShow = !this.isShow
      }, 1000)
    },

    beforeDestroy() {//死亡之前调用(1次)
    
    //光销毁vue对象并不能停止定时器,必须在销毁之前手动停止计时器
      console.log('beforeDestroy()')
      // 执行收尾的工作
      clearInterval(this.intervalId)
    },

    methods: {
      destroyVue () {
        this.$destroy()
      }
    }
  })


script>

过渡与动画

渐进式展示隐藏效果

<style>
    /*指定过渡样式*/
    .xxx-enter-active, .xxx-leave-active {
      transition: opacity 1s 
    }
    /*指定隐藏时的样式*/
    .xxx-enter, .xxx-leave-to { 
      opacity: 0;
    }


    .move-enter-active {
      transition: all 1s
    }

    .move-leave-active {
      transition: all 3s
    }

    .move-enter, .move-leave-to {
      opacity: 0;
      transform: translateX(20px)
    }
  style>
head>
<body>




<div id="demo">
  <button @click="show = !show">Togglebutton>
  <transition name="xxx">
    <p v-show="show">hellop>
  transition>
div>

<hr>
<div id="demo2">
  <button @click="show = !show">Toggle2button>
  <transition name="move">
    <p v-show="show">hellop>
  transition>
div>


<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      show: true
    }
  })

  new Vue({
    el: '#demo2',
    data: {
      show: true
    }
  })

script>
body>

放大缩小效果

  <style>
    .bounce-enter-active {
      animation: bounce-in .5s;
    }
    .bounce-leave-active {
      animation: bounce-in .5s reverse;
    }
    @keyframes bounce-in {
      0% {
        transform: scale(0);
      }
      50% {
        transform: scale(1.5);
      }
      100% {
        transform: scale(1);
      }
    }
  style>
head>
<body>

<div id="example-2">
  <button @click="show = !show">Toggle showbutton>
  <br>
  <transition name="bounce">
    <p v-if="show" style="display: inline-block">Loremp>
  transition>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script>
  new Vue({
    el: '#example-2',
    data: {
      show: true
    }
  })
script>
body>

过滤器



<div id="test">
  <h2>显示格式化的日期时间h2>
  <p>{{time}}p>
  <p>最完整的: {{time | dateString}}p>
  <p>年月日: {{time | dateString('YYYY-MM-DD')}}p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript" src="https://cdn.bootcss.com/moment.js/2.22.1/moment.js">script>
<script>
  // 定义过滤器  							//形参默认值,没传就是它,传了就是传参的值
  Vue.filter('dateString', function (value, format='YYYY-MM-DD HH:mm:ss') {
	//js的moment库,可以使用日期格式化方法
    return moment(value).format(format);
  })


  new Vue({
    el: '#test',
    data: {
      time: new Date()
    },
    mounted () {
      setInterval(() => {
        this.time = new Date()
      }, 1000)
    }
  })
script>

指令

<style>
    [v-cloak] { display: none }
style>

<div id="example">
  <p v-cloak>{{content}}p>
  <p v-text="content">p>   
  <p v-html="content">p>  
  <p ref="msg">abcdp>
  <button @click="hint">提示button>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  new Vue({
    el: '#example',
    data: {
      content: '百度一下'
    },
    methods: {
      hint () {
        alert(this.$refs.msg.innerHTML)
      }
    }
  })
script>

自定义指令




<div id="test">
  <p v-upper-text="msg">p>
  <p v-lower-text="msg">p>
div>

<div id="test2">
  <p v-upper-text="msg">p>
  <p v-lower-text="msg">p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript">
  // 注册一个全局指令
  // el: 指令所在的标签对象
  // binding: 包含指令相关数据的容器对象
  Vue.directive('upper-text', function (el, binding) {
    console.log(el, binding)
    el.textContent = binding.value.toUpperCase()
  })
  new Vue({
    el: '#test',
    data: {
      msg: "I Like You"
    },
    // 注册局部指令
    directives: {
      'lower-text'(el, binding) {
        console.log(el, binding)
        el.textContent = binding.value.toLowerCase()
      }
    }

  })

  new Vue({
    el: '#test2',
    data: {
      msg: "I Like You Too"
    }
  })
script>

插件

自定义插件

创建文件 vue-plugin.js

(function (window) {
  //向外暴露的插件对象
  const MyPlugin = {}
  //插件对象必须有一个install()
  MyPlugin.install = function (Vue, options) {
    // 1. 添加全局方法或属性
    Vue.myGlobalMethod = function () {
      //在这里写一些逻辑
      console.log('Vue函数对象的myGlobalMethod()')
    }

    // 2. 添加全局资源
    Vue.directive('my-directive',function (el, binding) {
      el.textContent = 'my-directive----'+binding.value
    })

    // 4. 添加实例方法
    Vue.prototype.$myMethod = function () {
      console.log('vm $myMethod()')
    }
  }
  window.MyPlugin = MyPlugin
})(window)

在其他位置使用插件


<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>17_插件title>
head>
<body>

<div id="test">
  <p v-my-directive="msg">p>
div>

<script type="text/javascript" src="../js/vue.js">script>
<script type="text/javascript" src="vue-myPlugin.js">script>
<script type="text/javascript">
  // 声明使用插件(安装插件: 调用插件的install())
  Vue.use(MyPlugin) // 内部会调用插件对象的install()

  const vm = new Vue({
    el: '#test',
    data: {
      msg: 'HaHa'
    }
  })
  Vue.myGlobalMethod()
  vm.$myMethod()

  new Object()
script>
body>
html>

你可能感兴趣的:(前端,vue)