VUE基础学习

一、文件目录结构

  • .vscode ----- vscode工具配置文件
  • node_modules ----- vue的依赖文件夹
  • public ----- 资源文件夹(浏览器图标)
  • src ----- 源码文件夹(assets:公共资源图片css或字体等)
  • package.json ----- 信息描述文件
  • vite.config.js ----- vue配置文件

二、VUE的模版语法

1、文本插值 {{变量}} :

  1. 其中也支持一些单一表达式(ps:有返回值)。 例如:
<template>
  <p>{{name + 1 > 10 ? "你好!":"你不好"}}</p>
</template>
<script>
  export default {
    data(){
      return{
        name: 123
      }
    }
  }
</script>
  1. 对于插入值的内容也会被转为纯文本对HTML显示(加入需要v-html=‘变量’),例如:
<template>
  <p v-html="rahtml"></p>
</template>
<script>
  export default {
    data(){
      return{
        rahtml: "<a href='https://www.baidu.com'>百度</a>"
      }
    }
  }
</script>

2、属性绑定 v-bind/:

  1. 不能使用{{变量}}直接加入属性位置获取,需要使用v-bind,(ps:如果变量属性值为null或者undefined,那么该属性会从元素上移出),同时也支持绑定多个属性,例如:
<template>
  <div v-bind:id="dname">完整格式</div>
  <div :id="dname">简写</div>
  <button :disabled="isDiabled">按钮</button>
  <div v-bind="objectAttributes">多属性</div>
</template>
<script>
export default {
  data() {
    return {
      dname: "dname",
      isDiabled: false,
      objectAttributes:{
        id: "id",
        class: "class"
      }
    }
  }
}
</script>

3、条件渲染 v-if/v-show

  1. v-if,指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被染
  2. v-else
  3. v-else-if
  4. v-show
  • ps: v-if和v-show的区别:
    (1) v-if是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
    (2) v-if也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。
    相比之下,
    (3) v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display属性会被切换.

  • 总的来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要频繁切换,则使用v-show较好;如果在运行时绑定条件很少改变,则v-if会更合适
    例如:

<template>
  <div v-if="flag">条件测试</div>
  <div v-else-if="!flag">条件2</div>
  <div v-else>条件3</div>
  <div v-show="flag">条件5 </div>
</template>
<script>
export default {
  data() {
    return {
      flag: true
    }
  }
}
</script>

4、列表渲染 v-for

使用v-for指令基于一个数组来渲染一个列表语法:item in items,其中也可以使用of命令代替in
例如:

<template>
  <div v-for="item in arrays">{{ item }}</div>
  <hr>
  <div>
    <div v-for="item in arraysObject">我叫{{ item.name }},今年{{ item.age }}岁,性别是{{ item.sex }}
      <img :src="item.sex">
    </div>
  </div>
  <hr>
  <div>
    <div v-for="(item,index) of arraysObject">
      我叫{{ item.name }},今年{{ item.age }}岁,性别是{{ item.sex }},下标是{{ index }}
    </div>
  </div>
  <hr>
  <div>
    <div v-for="(value,key,index) of objects">
    {{ value }}-{{ key }}-{{ index }}
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      arrays: ["name1", "name2", "name3"],
      arraysObject: [{name: "name1", age: 123, sex: "man"}, {name: "name2", age: 10, sex: "man"}, {
        name: "name3",
        age: 12,
        sex: "woman"
      }],
      objects: {name: "name1", age: 123, sex: "man"}
    }
  }
}
</script>

ps:在渲染列表数据时,存在顺序修改,而为了不让vue每次都渲染所有数据,只对修改的数据重新渲染,使用key属性(在真实的场景下一般不会使用index数组索引作为key,而是使用数据的返回的唯一id作为数据key)
例如:

<template>
  <div v-for="(item,index) in arrays" :key="index" >{{item}}</div>
</template>
<script>
export default {
  data() {
    return {
      arrays: ["name1", "name2", "name3"]
    }
  }
}
</script>

5、事件处理 v-on/@

使用v-on(简写@)来监听DOM事件,格式:v-on:click="值"或者@click=“值”
ps:值可以是:内联事件处理器(js代码)或者 方法事件处理器(js方法)
例如:

<template>
  <button @click="count++">按钮(内联)</button>
  <hr>
  <button @click="addCount">按钮(方法)</button>
  <div>{{count}}</div>
</template>
<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  //所有的方法函数都放入methods中
  methods:{
    addCount(){
      console.log("点击!")
      //读取data数据使用this.属性
      this.count++
    }
  }
}
</script>
事件参数

作用:

  1. 在事件方法中有一个默认的方法参数event(就是原生js的event对象)
  2. 传递数据(再想添加event在第二个参数位置使用$event)
    例如:
<template>
  <p  @click="myclick(item,$event)" v-for="(item,index) in arrays" :key="index">{{item}}</p>
</template>
<script>
  export default {
    data() {
      return {
        arrays: ["name1", "name2", "name3"]
      }
    },
    methods:{
      myclick(value,event){
        console.log("点击数据value:",value)
        console.log(event)
      }
    }
  }
</script>

6、事件修饰符(为v-on提供)

  • .stop 阻止事件冒泡
  • .prevent 阻止默认事件
  • .once 事件只会被触发一次
  • .enter 回车按键触发
    例如:
 <template>
  <a href="https://www.baidu.com" @click.prevent="myclick">百度</a>
</template>
<script>
  export default {
    methods:{
      myclick(event){
        console.log(event)
      }
    }
  }
</script>

7、数组变化侦测

  1. 变更方法:push(),pop(),shift(),unshift(),splice(),sort(),reverse()使用方法vue会自动重新渲染更改数据数据(会自动更新)
  2. 替换数组方法:filter(),concat(),slice()这些不会更改原数组
  • ps:两个区别就是变更会直接修改原数组数据,而替换数组不会修改原数组方法

8、计算属性 computed

为了不让模版承载太多逻辑
例如:

<template>
  <div>{{age}}</div>
  <div>{{jisuanage}}</div>
</template>
<script>
export default {
  data(){
    return{
      age: 12
    }
  },
  //计算属性放入的方法
  computed:{
      jisuanage(){
        return this.age > 18 ? "成年!" : "未成年!"
      }
  }
}
</script>

ps :

  • 计算属性(computed):计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算(多次调用只会计算一次)
  • 方法(methods):方法调用总是会在重渲染发生时再次执行函数(每次调用每次计算)

9、CLASS绑定 :class

vue对class的v-bind用法提供了特殊的功能增强,表达式也可以是对象和数组
(在数组和对象嵌套使用,只能是数组嵌套对象不能相反)

10、STYLE绑定 :style

跟CLASS绑定一样,vue对其做了一些增强

11、侦听器 watch

对data中数据在页面中使用{{}}展示的数据添加侦听器,侦听变量数据发生变化,从而进一步运行其不同的逻辑操作

<template>
  <div>侦听器</div>
  <p>{{ massage }}</p>
  <button @click="update">点击修改</button>
</template>
<script>
export default {
  data() {
    return {
      massage: "消息!"
    }
  },
  //侦听器
  watch: {
    //侦听器方法名必须与侦听数据变量名一样
    massage(newValue, oldValue) {
      //数据发生变化执行
      console.log("新值:" + newValue + "旧值:" + oldValue)
    }
  },
  methods: {
    update() {
      this.massage = "点击修改!"
    }
  }
}
</script>

12、表单输入绑定 v-model

处理表单中输入框输入数据绑定到对应的变量中(在表单中所有数据都可以绑定)
例如:

<template>
  <form>
    <input type="text" v-model="massage">
  </form>
  <div>
    {{massage}}
  </div>
</template>
<script>
export default {
  data() {
    return {
      massage: ""
    }
  }
}
</script>
v-model的修饰符
  1. .lazy 修改每次change事件后跟新数据
  2. .number 只接受输入的数字
  3. .trim 获取时去掉前后空格

13、模版引用

在使用的时候需要特殊的ref属性获取dom属性,在vue渲染的时候会被挂载到[this.$refs.属性名]之上,例如:

<template>
  <input ref="input" type="text">
  <button @click="getDom">getDom</button>
</template>
<script>
export default {
  methods: {
    getDom() {
      console.log(this.$refs.input.value)
    }
  }
}
</script>

14、组件组成

组件最大优点 可复用(一般定义在单独的.vue文件中)

<!-- 承载标签(必须要的) -->
<template></template>
<script>
//业务逻辑
export default {}
</script>
<!--所有样式  scoped让当前样式只在当前组件生效 -->
<style scoped></style>
引入组件步骤
  1. 引入组件
  2. 注入组件
  3. 显示组件
    例如:
<template>
  <!--  第三部显示组件  -->
  <MyAssembly></MyAssembly>
</template>
<script>
  //第一步 引入vue组件
  import MyAssembly from '地址'
  export default {
    //第二步注入组件
    components:{
      MyAssembly
    }
  }
</script>

15、组件嵌套关系

16、组件的注入方式(两种 全局和局部)

正常注册的import都是局部注册组件,全局注册需要再main.js中注册组件就是全局
例如:

//这是main.js引入MyAssembly组件
import { createApp } from 'vue'
//引入
import MyAssembly from './components/MyAssembly.vue'
import App from './App.vue'

var app = createApp(App)
app.component('MyAssembly',MyAssembly) //注入组件
app.mount('#app')

全局注册的问题:

  • 全局注册,但并没有被使用的组件无法在生产打包时被自动移除(也叫tree-shaking),也会在js文件中
  • 全局注册在大型项目中使用的依赖关系变得不那么明确,影响引用长期的可维护性

17、组件传递数据 props

业务逻辑中使用props以数组的形式加入数据(也可以动态传递,类型也可以是数组对象)属性(ps:父组件传递数据到子组件,不能反着来)

<!--使用MyAssembly组件-->
<template>
  <MyAssembly title="你猜我"></MyAssembly>
</template>
<script>
import MyAssembly from './components/MyAssembly.vue'
export default {
  components:{
    MyAssembly
  }
}
</script>
<!--组件的值接收后处理-->
<template>
  <div>{{title}}</div>
</template>
<script>
 export default {
   props:["title"],
 }
</script>

18、Props数据校验

ps: props是只读的

<script>
 export default {
   props:{
     //type类型校验,default默认值,request是否必选
     title:{type:[String,Number],default:"name",request:true},
     //返回对象的数组和对象 需要使用工厂方式的返回
     title2:{
         type: Object,
         default(){
           return {
               name: "name",   
               age:12
           }
       }
       
     }
  }
 }
</script>

19、组件事件

在组件的模版表达式中,可以直接使用$emit方法触发自定义事件,目的是组件之间数据传递。在父级使用@触发添加自定义事件,通过子级触发父级自定义事件(也可以在第二个参数传入参数,达到从子级传输数据到父级)

<!--父vue-->
<template>
  <MyAssembly @chuandi="chuandi2"></MyAssembly>
  <div>{{message}}</div>
</template>
<script>
  import MyAssembly from './components/MyAssembly.vue'
  export default {
    data(){
      return{
        message:""
      }
    },
    components:{
      MyAssembly
    },
    methods:{
      chuandi2(data){
        console.log("父级"+data)
        this.message = data
      }
    }
  }
</script>
<!--子vue-->
<template>
  <input  type="text" v-model="inputh">
  <button @click="chuandi">传递数据</button>
</template>
<script>
 export default {
   data(){
     inputh:""
   },
    methods:{
      chuandi(){
        //触发父级的事件,第二个参数传递参数
        this.$emit("chuandi",this.inputh)
      }
    }
 }
</script>
  • 组件事件和v-model配合使用(利用侦听器实现子传值到父)
<!--子-->
<template>
  搜索:<input type="text" v-model="search">
</template>
<script>
  export default {
    data() {
      return {
        search: ''
      }
    },
    watch:{
      search(newVal, oldVal){
        this.$emit('search', newVal)
      }
    },
  }
</script>
<!--父-->
<template>
  <h3>Main</h3>
  <div> 显示内容:{{search}}</div>
  <searchComponent @search="search2"/>
</template>
<script>
import searchComponent from './searchComponent.vue'
export default {
  data() {
    return{
      search: ''
    }
  },
  components: {
    searchComponent
  },
  methods:{
    search2(value){
      this.search = value
    }
  }
}
</script>

20、利用函数实现props子传父

使用props的传递函数来(间接)实现,例如:

<!--父-->
<template>
  <searchComponent  :onEvent="datafn"/>
  <div> 显示内容:{{datafn2}}</div>
</template>
<script>
import searchComponent from './searchComponent.vue'
export default {
  data() {
    return{
      datafn2:''
    }
  },
  components: {
    searchComponent
  },
  methods:{
    datafn(data){
      console.log("数据: "+data)
      this.datafn2=data
    }
  }
}
</script>
<!--子-->
<template>
  <div>{{onEvent('传递数据')}}</div>
</template>
<script>
export default {
  props:{
    onEvent:Function
  }
}
</script>

21、透传属性 attribute

当一个组件以单个元素作为渲染,透传的attribute会自动添加到根元素上,常见的class、id、style,禁止可以使用inheritAttrs:false

22、插槽Slots

父组件向子组件传递一些模版片段,让子其在子组件中渲染这些片段,使用标签显示使用,是一个插槽出口,标示了父元素提供的插槽内容将在哪里被渲染

1、渲染作用域

插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模版中定义的,例如:
例如:

<!--父-->
<template>
  <searchComponent>
    <!--    添加具名方便指定渲染位置-->
    <template v-slot:zi>
      <div>子组件</div>
    </template>
    <!--    #简写v-slot-->
    <template #message>
      <div>{{ message }}</div>
    </template>
  </searchComponent>
</template>
<script>
  import searchComponent from './searchComponent.vue'
  export default {
    data() {
      return {
        message: "作用域"
      }
    },
    components: {
      searchComponent
    }
  }
</script>
<!--子-->
<template>
  <!-- name指定模块渲染位置 -->
  <slot name="zi">插槽默认值</slot>
  <hr/>
  <slot name="message">插槽默认值</slot>
</template>
2、插槽中同时使用父组件数据和子组件内数据
<!--父-->
<template>
  <!--  使用v-slot起一个变量接收子组件传递的值-->
  <searchComponent v-slot="stoltprops">
    <!--    <template #message="stoltprops">-->
    <div>{{ message }} - 子数据 - {{ stoltprops.datah }}</div>
    <!--    </template>-->
  </searchComponent>
</template>
<script>
  import searchComponent from './searchComponent.vue'

  export default {
    data() {
      return {
        message: "作用域"
      }
    },
    components: {
      searchComponent
    }
  }
</script>

<!--子-->
<template>
  <!--  上传数据到父组件再使用显示-->
  <slot :datah="message">插槽默认值</slot>
</template>
<script>
export default {
  data() {
    return {
      message: "hello"
    }
  }
}
</script>

23、组件的生命周期(八个函数方法)

  • 创建期:beforeCreate,created
  • 挂载期:beforeMount(render),mounted
  • 更新期:beforeMount(render),mounted
  • 销毁期:beforeDestroy,destroyed
    在这里插入图片描述

24、动态组件

动态更换组件使用 标签实现
例如:

<template>
  <component :is="component"/>
  <button @click="clickh">切换组件</button>
</template>
<script>
import searchComponent from './searchComponent.vue'
import MyAssembly from './MyAssembly.vue'
export default {
  data() {
    return {
      component: "MyAssembly"
    }
  },
  components: {
    searchComponent,
    MyAssembly
  },
  methods:{
    clickh(){
      this.component==="MyAssembly"? this.component = "searchComponent": this.component = "MyAssembly"
    }
  }
}
</script>

25、组件保持存活keep-alive

将component加入 标签中,就是放组件被切换组件不会被卸载了(其中修改的数据就会被修改,而不会重新加载组件显示旧数据)

26、异步组件

//在script中异步加入组件方式
import {defineAsyncComponent} from "vue";
//异步加载组件
const searchComponent = defineAsyncComponent(() => import('./searchComponent.vue'))

27、依赖注入

  • 多层级的组件嵌套数据传输,需要一层一层向下传。
  • 使用provide和inject解决问题
    例如:
<!--父-->
<script>
  export default {
    provide:{
      MyAssembly: "MyAssembly"
    }
  }
</script>

<!--子-->
<script>
  export default {
    inject:["MyAssembly"]
  }
</script>

ps: provide和inject只能由上往下传递数据,不能反着传递

  • 还可以使用全局注入解决
elementApp.provide("MyAssembly2","MyAssembly")
//使用也要在inject引入

28、vue应用

从main.js中创建实例对象createApp(),再通过mount挂载数据到index.html中的div中,可以自定义组件挂载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何心而为殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值