vue学习笔记

注释

对着文档和视频整理的笔记,都是完整示例。复制即可实现功能,配图或控制台/页面数据。
组件区有gitee 的一个项目源码 可以看着学习

vue.config.js配置

热更新 和 runtimeCompiler

module.exports = {
    runtimeCompiler: true,
    devServer: {
        hot: true,
        open: true,
        port: 8080,
        host: "127.0.0.1"
    }
}

vscode中 npm-v 报错

npm : 无法加载文件 D:\Program Files\nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:
/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
输入
get-ExecutionPolicy
输出:
Restricted
受限制的,表示状态是禁止的,那就给个权限:
Set-ExecutionPolicy -Scope CurrentUser
输入:
RemoteSigned
验证一下:
get-ExecutionPolicy
原文链接:https://blog.csdn.net/weixin_43336281/article/details/107064733

对一些使用的简单记录

v-mdoel 双向绑定

在这里插入图片描述

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

指令:强制数据绑定 v-bind:src = :src 绑定事件监听 v-on:click = @click


<body>
    <div id="app">
        <p>{{username}}</p>
        <!-- textContent -->
        <p v-text="username">{{username}}</p>
        <!-- textContent -->
        <p v-html="username">{{username}}</p>
        <!-- innerhtml -->
        <h2>指令一:强制数据绑定</h2>
        <img src="imgUrl">
        <img v-bind:src="imgUrl">
        <img :src="imgUrl">
        <h2>绑定事件监听</h2>
        <button v-on:click="test">test</button>
        <button @click="test2(username)">test</button>
    </div>
</body>
<script src="vue.js"></script>
<script src="vue-myPlugin.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            username: '<a>www.baidu.com</a>',
            imgUrl: "https://cn.vuejs.org/images/logo.png"
        },
        methods: {
            test() {
                alert("test")
            },
            test2(content) {
                alert(content)
            }
        }
    })
</script>

计算属性computed之基本使用

1.计算属性
在computed属性对象中定义计算属性的方法
在页面中使用{{方法名}}来显示计算的结果
2.监视属性:
通过vm对象的$watch()或watch配置来监视指定的属性
当属性变化时,回调函数自动调用,在函数内部进行计算
3.计算属性高级
通过getter / setter 实现对属性数据的显示和监视
计算属性存在缓存,多次读取只执行一次getter计算
在这里插入图片描述

<body>
    <div id="app">
        姓<input type="text" v-model="firstname"> 名
        <input type="text" v-model="lastname"> 姓名
        <input type="text" v-model="fullname">
    </div>
</body>
<script src="vue.js"></script>
<script src="vue-myPlugin.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            firstname: 'a',
            lastname: 'b',

        },
        computed: {
            //什么时候执行:初始化显示/相关的data属性数据发生改变
            //计算属性中的一个方法,方法返回值作为属性值
            fullname() {
                console.log('fullname()')
                return this.firstname + this.lastname
            }
        }
    })
</script>

用watch实现一下上面的案例

<body>
    <div id="app">
        姓<input type="text" v-model="firstname"> 名
        <input type="text" v-model="lastname"> 姓名
        <input type="text" v-model="fullname">
        <input type="text" v-model="fullname2">
    </div>
</body>
<script src="vue.js"></script>
<script src="vue-myPlugin.js"></script>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstname: 'a',
            lastname: 'b',

        },
        computed: {
            //什么时候执行:初始化显示/相关的data属性数据发生改变
            //计算属性中的一个方法,方法返回值作为属性值
            fullname() {
                console.log('fullname()')
                return this.firstname + this.lastname
            }
        },
        watch: { //配置监视
            firstname: function(value) {
                //firstname发生变化 修改
                console.log(this) //就是vm对象
                this.fullname2 = value + this.lastname
            }
        }
    })
    vm.$watch('lastname', function(value) {
        this.fullname2 = this.first + value

    })

1.计算属性
在computed属性对象中定义计算属性的方法
在页面中使用{{方法名}}来显示计算的结果
2.监视属性:
通过vm对象的$watch()或watch配置来监视指定的属性
当属性变化时,回调函数自动调用,在函数内部进行计算
3.计算属性高级
通过getter / setter 实现对属性数据的显示和监视
计算属性存在缓存,多次读取只执行一次getter计算
getter get() setter set()
用一个双向的 改变全名 姓和名都改变

<body>
    <div id="app">
        姓<input type="text" v-model="firstname"> 名
        <input type="text" v-model="lastname"> 姓名
        <input type="text" v-model="fullname">
        <input type="text" v-model="fullname2">
    </div>
</body>
<script src="vue.js"></script>
<script src="vue-myPlugin.js"></script>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            firstname: 'a',
            lastname: 'b',

        },
        computed: {
            //什么时候执行:初始化显示/相关的data属性数据发生改变
            //计算属性中的一个方法,方法返回值作为属性值
            fullname() {
                console.log('fullname()')
                return this.firstname + this.lastname
            },
            fullname2: {
                /*  1.你定义的 2.你没有调用3.但最终它执行了
                    2.什么时候调用 2.用来做什么
                    回调函数 当需要读取当前属性值时回调,根据相关数据
                    计算并返回当前属性的值*/
                get() {
                    return this.firstname + this.lastname
                },
                set(value) {
                    const names = value.split('')
                    this.firstname = names[0]
                    this.lastname = names[1]
                }
            }
        }
    })
</script>

强制绑定class和style

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .aClass {
            color: red;
        }
        
        .cClass {
            font-size: 10px;
        }
        
        .bClass {
            color: blue;
        }
    </style>
</head>

<body>
    <div id="demo">
        <p :class="a">绑定字符串aClass</p>
        <p :class="{aClass:isA,bClass:isB}">绑定对象一开始aClass updata变成bclass </p>
        <p :class="['aClass','cClass']">aClass cClass 数组</p>
        <p :style="{color: activeColor,fontSize:fontsize+'px'}"> this is object</p>
        <button @click="update">update</button>


    </div>
    <script src="vue.js">
    </script>
    <script>
        new Vue({
            el: '#demo',
            data: {
                a: 'aClass',
                activeColor: 'green',
                fontsize: 50,
                isA: true,
                isB: false
            },
            methods: {
                update() {
                    this.a = 'bClass ',
                        this.isA = false,
                        this.isB = true,
                        this.activeColor = 'yellow'
                    this.fontsize = 100
                }
            }
        })
    </script>
</body>

</html>

条件渲染 v-if v-else v-else-if

页面显示
Vue is awesome!
A

<template>
 <div id="example-1">
  <h1 v-if="awesome">Vue is awesome!</h1>
  <h1 v-else>Oh no 😢</h1>
    <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>
</template>

<script>
export default {
data () {
      return { 
     awesome:true,
     type:'A'
      }
    }
}
</script>

<style>
</style>

列表渲染

Foo
Bar
Parent - 0 - Foo
Parent - 1 - Bar

<template>
 <div>
   <ul id="example-1">
  <li v-for="item in items" :key="item.message">
    {{ item.message }}
  </li>
  </ul>
  <ul id="example-2">
    <li v-for="(item,index) in items" :key="item.message">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>

</ul>
 </div>
</template>

<script>
export default {

data () {
  
      return { 
       parentMessage: 'Parent',
       items: [
          { message: 'Foo' },
          { message: 'Bar' }
        ]
      }
    }
}
</script>

<style>
</style>

  1. title : How to do lists in Vue
  2. author : Jane Doe
  3. publishedAt : 2016-04-10
<template>
 <div>
  <ul id="v-for-object" class="demo">
  <li v-for="(value, key, index) in object" :key="index">
     {{ index }}. {{ key }} : {{ value }}
    </li>
</ul>
 </div>
</template>

<script>
export default {

data () {
  
      return { 
       object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
      }
    }
}
</script>

<style>
</style>

2
4

<template>
 <div>
  <li v-for="n in evenNumbers">{{ n }}</li>
 </div>
</template>

<script>
export default {  

       data () { 
              return { 
                numbers: [ 1, 2, 3, 4, 5 ]
              }
          },
      computed: {
            evenNumbers: function () {
            return this.numbers.filter(function (number) {
            return number % 2 === 0
          })
        }  
      }
}
</script>

<style>
</style>

事件处理

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

<template>
 <div id="example-1">
  <button @click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>
</template>

<script>
export default {  

       data () { 
              return { 
                counter: 0
              }
          }
}
</script>

<style>
</style>


v-on 还可以接收一个需要调用的方法名称

<template>
 <div id="example-2">
  <!-- `greet` 是在下面定义的方法名 -->
  <button v-on:click="greet">Greet</button>
</div>
</template>

<script>
export default {  

       data () { 
              return { 
                name: 'Vue.js'
              }
          },
          methods: {
    greet: function (event) {
      // `this` 在方法里指向当前 Vue 实例
      console.log(this)
      console.log(this.name)
      console.log('Hello ' + this.name + '!')
      // `event` 是原生 DOM 事件
      if (event) {
        console.log(event)
        console.log(event.target.tagName)
      }
    }
  }
}
</script>

<style>
</style>

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 e v e n t 把 它 传 入 方 法 : 不 用 event 把它传入方法: 不用 eventevent 的事件

methods: {
    say: function (message) {
      alert(message)
    }

event.preventDefault()方法

阻止元素发生默认的行为。调用此方法链接(a标签)不会被打开,但是会冒泡到父元素上。

例如:

(1). 当点击提交按钮时阻止对表单的提交

(2). 阻止 URL 的链接(意思是如果点击一个a标签,浏览器不会跳到新的 URL 里面去)
  
用event 返回原始DOM事件

<template>
 <div id="example-2">
<a href="https://www.baidu.com">
 <button v-on:click="warn('warn', $event)">
  Submit
</button></a>
</div>
</template>

<script>
export default {  

       data () { 
              return { 
           
              }
          },
       methods: {
          warn: function (message, event) {
            // 现在我们可以访问原生事件对象
            if (event) {
              console.log(event)
              event.preventDefault()
            }
            console.log(message)
          }
       }
}
</script>

<style>
</style>


生命周期

在这里插入图片描述

<template>
  <div id="app">
   <button @click="destoryVM()">destroy vm</button>
   <p v-show="isShow">vm</p>
  </div>
</template>

<script>

export default {
  data(){
    return{
      isShow:true
    }
  },
  //初始化
  beforeCreate(){
    console.log('beforeCreate')
  },
  created(){
    console.log('created')
  },
  beforeMount(){
    console.log('beforeMount')
  },
  mounted(){ //初始化显示之后立即调用
    this.intervalId = setInterval(()=>{
       console.log('-----mounted')
       this.isShow = !this.isShow
     },1000)
  },
  beforeUpdate(){
    console.log('beforeUpdata')
  },
  //更新阶段
  updated(){
    console.log('updated')
  },
  beforeDestroy(){
    console.log('beforeDestroy')
    //死亡之前调用一次
    clearInterval(this.intervalId)
  },
  destory(){
    console.log('destory')
  },
  methods:{
    destoryVM(){
      this.$destroy()
    }
  }
}
</script>

<style>

</style>

slot

引用了一个github上的demo 当时为了偷懒 demo1、2、3 合在一起了 所以有点乱 可以去看原作者的分开的 但是混合之后问题不大 理解的更加明白了
https://github.com/cunzaizhuyi/vue-slot-demo/tree/master/src/components
在这里插入图片描述
App.vue

<template>
  <div class="father">
    <h3>这里是父组件</h3>
    <!--demo1第一次使用-->
    <child>
            <div class="tmpl">
              <span>菜单1</span>
              <span>菜单2</span>
              <span>菜单3</span>
              <span>菜单4</span>
              <span>菜单5</span>
              <span>菜单6</span>
            </div>
    </child>
     <h3>这里是父组件demo2</h3>
      <!--demo2第一次使用-->
    <child>
      <div class="tmpl" slot="up">
        <span>菜单1</span>
        <span>菜单2</span>
        <span>菜单3</span>
        <span>菜单4</span>
        <span>菜单5</span>
        <span>菜单6</span>
      </div>
      <div class="tmpl" slot="down">
        <span>菜单-1</span>
        <span>菜单-2</span>
        <span>菜单-3</span>
        <span>菜单-4</span>
        <span>菜单-5</span>
        <span>菜单-6</span>
      </div>
      <div class="tmpl">
        <span>菜单->1</span>
        <span>菜单->2</span>
        <span>菜单->3</span>
        <span>菜单->4</span>
        <span>菜单->5</span>
        <span>菜单->6</span>
      </div>
      
    </child>
    <!--demo3第一次使用:用flex展示数据-->
    <child>
      <template slot-scope="user">
        <div class="tmpl">
          <span v-for="item in user.data">{{item}}</span>
        </div>
      </template>

    </child>

    <!--第二次使用:用列表展示数据-->
    <child>
      <template slot-scope="user">
        <ul>
          <li v-for="item in user.data">{{item}}</li>
        </ul>
      </template>

    </child>

    <!--第三次使用:直接显示数据-->
    <child>
      <template slot-scope="user">
       {{user.data}}
      </template>

    </child>

    <!--第四次使用:不使用其提供的数据-->
    <child>
      我就是模板
    </child>
  </div>
</template>

<script>
  import Child from './components/Child'
  export default {
    data: function () {
      return {
        msg: ''
      }
    },
    methods: {
      clickHandler(data){
          console.log(data);
      }
    },
    components:{
      'child': Child
    }
  }
</script>

<style scoped>
  .father{
    width:100%;
    background-color: #ccc;
    height: 650px;
  }
  .tmpl{
    display: flex;
    justify-content: space-around;
    flex-direction: row;
    width: 30%;
    margin: 0 auto;
  }
  .tmpl span{
    border:1px solid red;
    height:50px;
    line-height: 50px;
    padding: 10px;
  }
</style>

Child.vue

<template>
  <div class="child">
    
    <h3>这里是子组件</h3>
    <!-- demo1 -->
    <slot></slot>
    <!-- demo2 -->
    <slot name="up"></slot>
    <h3>这里是子组件</h3>
    <slot name="down"></slot>
    <slot></slot>
    <!-- demo3 -->
    <slot  :data="data"></slot>
  </div>
</template>

<script>
  export default {
      data: function(){
        return {
          data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
        }
      },
    computed: {
    },
    methods:{
    },
    components: {
    }
  }
</script>

<style scoped>
  .child{
    background-color: #00bbff;
    width: 100%;
    padding: 10px;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
  }
</style>

自定义指令 组件 props父子传参

单项的数据处理 没有很复杂 不需要用到自定义组件 用 自定义指令
App.vue

<template>
  <div>
    我是父组件
    <hello-world :age="ages" @patch="msg"> 
    </hello-world>
   
  </div>  
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import './components/n'
export default {
  name:'app',
  components: {
    HelloWorld
  },
  data(){
    return{
      ages:18
    }
  },
  methods:{
    msg:function(){
      window.console.log('msg')
      this.ages++
    }
  }
}
</script>

<style>

</style>

HelloWorld.vue

<template>
  <div >
  <div v-n="3"></div>
  <div v-n="4"></div>
  {{age}}
  <button type="button" name="button" @click="$emit('patch')">send</button>
    <slot></slot>
  </div>
</template>

<script>
export default {
  props: ['age'],
  data(){
    return{
      name:'helloworld'
    }
  }

}
</script>

<style scoped>
</style>

n.js

import Vue from 'vue'
Vue.directive('n', {
    bind: function(el, binding) {
        el.textContent = Math.pow(binding.value, 2)
    },
    update: function(el, binding) {
        el.textContent = Math.pow(binding.value, 2)
    }

})

组件

有一个完成度还不错的网易云仿写项目可以参考,有时间就会不断的补上笔记或者是完善项目
https://gitee.com/thinkerwing/test

路由

router.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import pageA from './pages/a.vue'
import pageB from './pages/b.vue'
Vue.use(VueRouter)
    /*如果在一个模块化工程中使用它,必须要通过
     Vue.use() 明确地安装路由功能:

配置路由的路径 path  配置了关联 并 没有生效*/
const routes = [{
        path: '/pagea',
        component: pageA
    }, {

        path: '/pageb',
        component: pageB
    }]
    // 实例化
const router = new VueRouter({
    routes
})
    //导出
export default router

cli脚手架搭建的main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: function (h) { return h(App) },
}).$mount('#app')

import Vue from 'vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
    router
}).$mount('#app')

vue.runtime.esm.js?2b0e:619 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

(found in )
解决方法:
创建vue.config.js

module.export = {
    runtimeCompiler: true
}

重启cli 重新编译
挂载index.html

 <div id="app">
        <router-view></router-view>
    </div>

路由跳转

 <router-link to="/pagea">pagea</router-link>
 <router-link to="/pageb">pageb</router-link>

vuex

父子之间的通信 想共享到子组件 ? props
子组件的数据想回传到父组件? 可以用事件
有几个不相关的想共享数据呢? 用vuex
在这里插入图片描述
state 所有公用的部分 想要共享的那个数据 不是全局的变量 用mutations 直接操作state数据
actions 触发什么时候去改变 commit 提交commit
数据在state 如何改变呢 在mutaitons 什么时候去改变在actions
state是数据虽然没有在data里面 vue模板是可以render这个数据的
完整的数据流:dispatch 通过用户的交互触发actions action做提交找到对应交互的mutations 最终让state数据改变 然后vue components更新

代码实现

vuex.js

<template>
  <div>
   vuex{{$store.state.count }}
   <button @click="increment">增加</button>
   <button @click="decrement">删减</button>
  </div>  
</template>

<script>
import {mapActions} from 'vuex'
export default {
    //让事件的方法跟定义的关联
    methods:mapActions([
        'increment',
        'decrement'
    ])
}
</script>

<style>

</style>

store.js

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const state = {
    count: 1
}
const mutations = {
    increment(state) {
        state.count++
    },
    decrement(state) {
        state.count--
    }
}
const actions = {
    increment: ({ commit }) => {
        commit('increment')
    },
    decrement: ({ commit }) => {
        commit('decrement')
    }
}

export default new Vuex.Store({ state, mutations, actions })

防止太多混乱,用index.js当入口文件

在这里插入图片描述
index.js

import Vue from 'vue';
import Vuex from 'vuex';
import money from './modules/a.js'
import count from './modules/b.js'
Vue.use(Vuex);
export default new Vuex.Store({
    modules: {
        money,
        count
    }
})

a.js

const state = {
    money: 10
}
const mutations = {
    add(state) {
        state.money++
    },
    reduce(state) {
        state.money--
    }
}
const actions = {
    add: ({ commit }) => {
        commit('add')
    },
    reduce: ({ commit }) => {
        commit('reduce')
    }
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}

a.vue

<template>
  <div>
  a {{$store.state.money.money}}
  <button @click="add">add</button>
  <button  @click="reduce">reduce</button>
  </div>  
</template>

<script>
import {mapActions}from 'vuex'
export default {
 methods:mapActions('money',['add','reduce'])
}
</script>

<style>

</style>

传参

const mutations = {
    add(state, param) {
        window.console.log(param)
        state.money += param
    },
    reduce(state) {
        state.money--
    }
}
const actions = {
    add: ({ commit }, param) => {
        commit('add', param)
    },
    reduce: ({ commit }) => {
        commit('reduce')
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值