【7】【vue】【vue3】【组件】【语法】【路由】【项目结构】

1、项目结构:

asserts用来存放静态资源的(一些图片,公共的css文件等)

components用来存放vue的组件(vue是组件开发)

 

App.vue是主入口组件 (根组件,所有组件都是从这里开始,从这里显示的)

 

main.js是主入口文件,(所有程序入口)

 

template可以理解是写html的

script可以理解为是写业务逻辑的

 

2、模板语法

目的:为了让标签里显示的数据从静态变为动态

语法:双花括号{ {}}

步骤:

(1)写一个data函数(用来返回数据)


<script>
export default {
  name: 'HelloWorld',
  data(){
    return {
      message:"测试"
    }
  }
}
</script>

(2)用花括号引入数据

<template>
  <div class="hello">

    <h3>学习vue模板语法</h3>
    <p>{
   
   {message}}</p>

  </div>
</template>

结果

目的:为了识别标签里的链接

语法:在标签括号里加v-html 

其实就是超链接的做法 以下对比普通的和v-html属性的标签

<template>
  <div class="hello">

    <p>{
   
   {message}}</p>
    <div>{
   
   {rawHtml}}</div>
    <div v-html="rawHtml"></div>


  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data(){
    return {
      message:"测试",
      rawHtml:"<a href='http://www.itbaizhan.com'>百战</a>"
    }
  }
}

结果

目的:让标签里的属性也动态化

语法:在标签括号里加v-bind

 <div v-bind:id="dynamicId"></div>
    //v-bind:可以简写为一个冒号“:”
 <div :id="dynamicId"></div> 
export default {
  name: 'HelloWorld',
  data(){
    return {
      dynamicId:10001
    }
  }
}

Vue.js也支持JavaScript表达式支持

结果

 注意只支持表达式,不支持语句和流程空值(如赋值语句和if语句都不会生效)

3、条件渲染

目的:用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true值的时候被渲染。

 语法:v-if=""

比如用来标记某个物品是否为新增的状态或者控制父级容器的显示和隐藏

export default {
  name: 'HelloWorld',
  data(){
    return {

      message:"测试",
      rawHtml:"<a href='http://www.itbaizhan.com'>百战</a>",
      dynamicId:10001,
      num:10,
      flag:true
    }
  }
}

结果:

 目的:与v-if组合成一个逻辑的要么这样要么那样

语法:v-else

 只能控制一个的显示的

v-show 

v-if与v-show的区别(前者是删除,后者是隐藏)

4、列表渲染

目的:把一个数组映射为一组元素

语法:v-for="item in items" (items指的是定义的数组名称,item为数组的每一个元素)

步骤:

 (1)创建一个数组(数组用方括号创建)

 newsList:[
          {
            id:1001,
            title:"今日新闻1"
          },
          {
            id:1002,
            title:"今日新闻2"
          },
          {
            id:1003,
            title:"今日新闻3"
          }
        ]

 (2)以ul加li标签的形式显示在页面上

报错:

 解决:在后面加 :key=“item.id”

(106条消息) Elements in iteration expect to have ‘v-bind:key‘ directives.‘_DaftJayee的博客-CSDN博客_v-bind:key' directives

<template>
  <div class="hello">
    <ul>
      <li v-for="item in newsList" :key="item.id">
        {
   
   { item.title }}
      </li>
    </ul>
  </div>
</template>

结果 

 改成item.title

 上面bug的原因

说人话:Vue渲染机制是就地渲染每次只渲染新变化的部分,所以要有一个唯一的key供Vue识别排列所有的现有元素 

也可以以数组下标作为key,但是不推荐

5、事件处理

目的:监听DOM事件,并在触发事件时执行一些javascript

语法:v-on click="methodName"或者把v-on缩写成@

步骤:

(1)测试一个最简单的事件

<template>
  <div class="hello">
    <button v-on:click="counter +=1">点击:{
   
   {counter}}</button>
    //或者直接把v-on写成@
    <button @:click="counter +=1">点击:{
   
   {counter}}</button>
  </div>
</template>

<script>
  export default {
    name: 'HelloWorld',
    data(){
      return {
        // flag:true,
        counter:1
      }
    }
  }
</script>

结果:

每次点击都会counter都会+1 

(2)测试事件处理方法

引入methods方法模块

<el-button @:click="clickHandle">按钮3</el-button>
<script>
  export default {
    name: 'HelloWorld',
    data(){
      return {
        counter:1
      }
    },
    methods:{
      clickHandle(){
        console.log("哈哈哈")
      }
    }
  }
</script>

结果:

 更改标签中的文本

 methods:{
      clickHandle(){
        //在事件中,读取data中的属性,是需要通过this,属性
        this.message="消息被撤回了"
      }

结果:

----------->

引入event关键字

methods:{
      clickHandle(event){
        //在事件中,读取data中的属性,是需要通过this,属性
        this.message="消息被撤回了"
        //event是原生的DOM event
        console.log(event);
        //把按钮内的文字改一下
        event.target.innerHTML="点击之后"
      }
    }

传递参数:

<button @click="say('你好')"></button>
    methods:{
   
      say(data){
        console.log(data)
      }
    }

结果:

点击标签事件:

 <ul>
      <li @:click="clickItemHandle(item)" v-for="(item,index) in names" :key="index">
        {
   
   {item}}
      </li>
    </ul>
   methods:{
 
      clickItemHandle(item){
        console.log((item))
      }
    }

结果: 

 6、表单输入绑定

目的:用v-model指令在表单<input><textarea><select>元素上创建双向数据绑定(既可以获取,又可以设置)。它会根据控件类型自动选取正确的方法来更新元素,负责监听用户的输入事件来更新数据,在某种极端场景下进行一些特殊处理。

语法:v-model=" " placeholder=" "()

步骤:

<template>
  <div class="hello">
   <input type="text" v-model="username">
    <p>{
   
   {username}}</p>
    <el-button @:click="clickUser">获取用户名</el-button>
  </div>
</template>
<script>
  export default {
    name: 'HelloWorld',
    data(){
      return {
       username:""
      }
    },
    methods:{
     
      clickUser(){
        console.log(this.username)
      }
    }
  }
</script>

结果:

实现边输入表单边实时获取

修饰符:

语法:在v-model后面添加

1、.lazy

目的:把输入实时获取,改成有change事件(回车,失去焦点)后才获取

2、.trim

目的:自动过滤用户输入的首尾空白字符,可以给v-model添加trim修饰符

v-modelv-blind:model的区别:

1、v-model:
v-model 是 v-model:value 的缩写,通常用于表单上的双向数据绑定(表单接受值 value,故v-model默认收集的就是 value ,所以缩写直接省略 value),可以实现子组件到父组件的双向数据动态绑定。数据不仅能从data流向页面,还可以从页面流向data。

2、:model:
:model 是 v-bind:model 的缩写,可以实现将父组件的值传递给子组件,但是子组件不能传给父组件,无法双向绑定。

3、v-bind:
v-bind:value 可以简写为 :value ,数据只能从data流向页面。

7、组件基础

 其中:template标签部分必须存在

步骤:

(1)创建组件

(2)加载组件

 

 第三部的标签也可以用-隔开单词书写,结果相同

结果:

 小知识:

style标签里面添加scoped关键字,会让这个style里面对各种标签等的样式只在本组件内生效,否则会全局生效

 每个组件都可以引用其它组件,形成一个组件库,组件之间又独立运行,使得容错性提高

8、Props组件交互

目的:父组件传子组件数据,赋予组件存在的意义

语法:Props能决定组件与组件之间的一些数据的传递

步骤:

(1)在父组件App.vue设置data并在里面编写传的数据内容

export default {
  name: 'App',
  components: {
    MyComponent
    // HelloWorld
  },
  data(){
    return{
      title:"我是一个标题"
    }
  }

}

(2)在子组件MyComponent.vue建立props,并在内部定义被传输的数据

<template>
  <p>{
   
   {title}}</p>
</template>

export default {
  name: "MyComponent",
  props:{
    title:{
      type:String,
      default:"" //防止没有传输,给予默认值
    }
  }
}

(3)在父组件标签里动态传输数据 ,传数据的个数无限制

结果: 

注意当要传输的数据为数组或者对象的时候,需要用函数的形式传

Mycomponent.vue

<template>
  <ul>
    <li v-for="(item,index) in names" :key="index">{
   
   {item}}</li>
  </ul>
</template>

<script>
export default {
  name: "MyComponent",
  props:{
    names:{
      type:Array,
      //数组和对象必须使用函数进行返回
      default: function (){
        return []
      }
    }
  }
}
</script>

App.vue

export default {
  name: 'App',
  components: {
    MyComponent
    // HelloWorld
  },
  data(){
    return{
      names:["星期1","星期2","星期3"]
    }
  }

}

结果:

9、自定义事件组件交互

自定义事件可以在组件中反向传递数据,prop可以将数据从父组件传子组件,那么反向如何操作呢(从子组件传给父组件),就可以利用自定义事件实现$emit   (比prop操作麻烦但是常用)

目的:反向传输数据(从子组件传给父组件)

语法://参数1:字符串:理论上是随便的,但是需要有意义
           //参数2:传递的数据
         this.$emit("onEvent",this.message)

步骤:

(1)编写子组件Mycomponent里面要发送的数据内容、按钮点击发送的方法

<template>
  <h3>自定义事件传递数据</h3>
  <el-button @:click="sendMessage">发送给App组件数据</el-button>
</template>

<script>
export default {
  name: "MyComponent",
  data(){
    return{
      message:"我是Mycomponent数据"
    }
  },
  methods:{
    sendMessage(){
      //参数1:字符串:理论上是随便的,但是需要有意义
      //参数2:传递的数据
      this.$emit("onEvent",this.message)
    }

  }

(2)在父组件App.vue编写标签Mycomponent,将之前在Mycomponent.vue里编写$emit括号里的字符串与在App.vue内编写的获取数据的方法用等号连接

 <my-component @onEvent="getMessage"/>
export default {
  name: 'App',
  components: {
    MyComponent
    // HelloWorld
  },
  data(){
    return{
    }
  },
  methods:{
    getMessage(data){
      console.log(data);
    }
  }

}
</script>

结果:

在自己定义的getMessage方法里可以随意的对数据进行操作,如把它赋值给当前组件的标签

<p>{
   
   {message}}</p>
  data(){
    return{
      message:""
    }
  },
  methods:{
    getMessage(data){
      this.message=data;
    }
  }

 结果:

10、兄弟之间组件传值

prop可以将数据从父组件传递道子组件,子组件给父组件传递数据,需要借助自定义事件$.emit(),而兄弟组件之间传递数据的方式则需要借助EventBus

目的:平行组件之间的传输数据(兄弟组件进行数据传递)

语法://参数1:字符串:理论上是随便的,但是需要有意义
           //参数2:传递的数据
         this.$emit("onEvent",this.message)

步骤:

其它平行组件传值的思路

     由子传给父,又同步传给兄弟

11、组件声明周期

每个组件在被创建时都要经过一系列的初始化过程--例如,需要设置数据监听,编译模板,将实例挂载到DOM并在数据变化时更新DOM等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己代码的机会

生命周期函数不需要我们进行调用,它虽然被称作函数,但为自动化调用。

我们可以把生命周期函数分为以下四类:

 我们编写这八个方法,实行程序可以看到他们的加载顺序

<script>
export default {
  name: "MyComponent",
  data(){
    return {
      message:""
    }
  },
  beforeCreate() {
    console.log("beforeCreate:组件创建之前")
  },
  created(){
    console.log("created:组件创建完成")
  },
  beforeMount() {
    console.log("beforeMount:组件渲染之前")
  },
  mounted() {
    console.log("mounted:组件渲染之后")
  },
  beforeUpdate() {
    console.log("beforeUnmount:组件更新之前")
  },
  updated() {
    console.log("updated:组件更新之后")
  },
  beforeUnmount(){
    console.log("beforeUnmount:组件卸载之前")
  },
  unmounted() {
    console.log("unmounted:组件卸载之后")
  }
}
</script>

 绑定一个按钮事件:

点击按钮,会运行两个函数:

所以不同的生命周期函数会在不同的节点做不同的工。

 比方说mounted函数一般会将网络请求放在这个函数,当页面组件加载渲染完成后,发送网络请求请求数据,然后渲染数据

 再如beforeUnmounted会在组件卸载之前先把无效占用的程序关闭清理

12、Vue引入第三方

目的:引入不属于Vue的但是常用的第三方制作的插件

最常见的就是轮播图swiper Swiper Vue.js Components (swiperjs.com)

步骤:

(1)安装

 npm i swiper

(2)引入swiper和适配器的css

// import Swiper core and required modules
  import { Navigation, Pagination, Scrollbar, A11y } from 'swiper';

  // Import Swiper Vue.js components
  import { Swiper, SwiperSlide } from 'swiper/vue';

  // Import Swiper styles
  import 'swiper/css';
  import 'swiper/css/navigation';
  import 'swiper/css/pagination';
  import 'swiper/css/scrollbar';

 (3)在swiper标签中编写适配器信息并编写swiper-slide(这里选用Vue自带图标为轮播图片)

<swiper
        :modules="modules"
        :slides-per-view="1"
        :space-between="50"
        navigation
        :pagination="{ clickable: true }"
        :scrollbar="{ draggable: true }"
        @swiper="onSwiper"
        @slideChange="onSlideChange"
    >
      <swiper-slide>
        <img src="../assets/logo.png" alt="">
      </swiper-slide>
      <swiper-slide>
        <img src="../assets/logo.png" alt="">
      </swiper-slide>
      <swiper-slide>
        <img src="../assets/logo.png" alt="">
      </swiper-slide>

    </swiper>

(4)编写export defalut,引入组件components,编写setup()

setup() {
    const onSwiper = (swiper) => {
      console.log(swiper);
    };
    const onSlideChange = () => {
      console.log('slide change');
    };
    return {
      onSwiper,
      onSlideChange,
      modules: [Navigation, Pagination, Scrollbar, A11y],
    };
  }

 效果:

Vue引入路由配置

目的:通过vue-router路由管理页面之间的关系(可以让单页面应用变得轻而易举)

语法:

步骤:

(1)安装路由 npm install --save vue-router

(2)配置独立的路由文件(其实可以设置自动创建,这里手动创建一遍)

创建router文件夹,创建index.js(编写路由配置的文件)

创建view文件夹:创建两个界面HomeView、AboutView

对index.js进行编写:先引入两个页面

import HomeView from "@/views/HomeView";
import AboutView from "@/views/AboutView";

编写页面的信息数组routes (component是小写,这里被坑了)

//配置信息中需要页面的相关配置

const routes = [
    {
        //访问路径设置
        path:"/",
        component:HomeView
    },
    {
        path:"/about",
        component: AboutView
    }
]

将数组填入创建的路由router中

const router = createRouter({
    history:createWebHashHistory(),
    routes
})

导出路由

export default router;

对App.vue进行编写

在template里添加路由的显示入口

<!--  //路由的显示入口-->
  <router-view></router-view>

添加页面点击的链接 (to里面是之前在routes数组里设置的页面配置路径)

  <router-link to="/">首页</router-link>
  <a> | </a>
   <router-link to="/about">关于</router-link>

对main.js进行编写(将路由导入主程序入口并使用)

添加以下两句

import router from "@/router";


app.use(router)

结果:(点击即可跳转页面)

特殊说明:推荐使用createWebHashHistory

Vue插槽函数

目的:可以让某一列table-column的值自定义插入你想要的内容(值、组件、图片等) 

语法:<template>slot-scope="scope"</template>

步骤:

  <el-table-column  label="">
        <template>slot-scope="scope"</template>
         //插入想要插入的内容


  </el-table-column>

小知识

1、el-table 设置自增序号列

(1)根据页码数和页码大小生成自增序号

HTML代码:

<el-table-column type="index" :index="getIndex" label="序号" width="120"></el-table-column>

JS代码:

getIndex(index) {
  return (this.currentPage - 1) * this.pageSize + index + 1;
},

(2)直接生成自增序号(数据量少只有一页)

HTML代码:与上面一样

JS代码:

getIndex(index) {
  return index + 1;
},

效果:

猜你喜欢

转载自blog.csdn.net/qq_53478650/article/details/128832264
今日推荐