Vue 笔记

本文深入探讨Vue.js的高级特性,包括动态绑定、条件渲染、列表循环、事件处理、表单绑定、组件通信、路由配置、状态管理及分页实现等,旨在帮助开发者掌握Vue.js的精髓。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

v-bind:class

 <h1 :class="{listStyle: true}">h1</h1>
 // class的样式应用四种
    1.数组用法
        显示用标识符v-bind
        :class="['red','thin']"

    2.三元表达式
        :class="[ture?'样式':'样式']"

    3.数组中嵌套对象
        :class="[{'样式':ture}]"

    4.直接使用对象
        :class="{red:ture}"
	// 例:  <td :class="{red: items.age > 20}">{{items.age}}</td>

v-if v-else-if v-else

// v-if 和 v-show 的区别 v-if根据判断条件决定是否渲染 v-show 无论如何都会进行模块的渲染(display:none)

	<template v-if="type === 'A'">
      <h1>typeA</h1>
      <span>spana</span>
    </template>

    <template v-else-if="type === 'B'">
      <h1>typeB</h1>
      <span>spanb</span>
    </template>

    <template v-else>
      <h1>typeC</h1>
      <span>spac</span>
    </template>

v-for

 <div v-for="(v, k) in data" :key="k">{{v.text}}</div>
 <div v-for="v in data" :key="v.id">{{v.text}}</div>

传参数 event?

     <div v-for="v in data" :key="v.id">
      <span @click="headdleClick(v.id, $event)">{{v.text}}</span>
      <span @click="e => headdleClick(v.id, e) ">{{v.text}}</span>
    </div>
  methods: {
    headdleClick(id, e) {
      console.log(id, e);
    },
  }

事件 冒泡、捕获

.stop // 阻止单击事件继续传播
.prevent // 阻止默认事件
.capture // 添加事件监听器时使用事件捕获模式
.self // 只当在 event.target 是当前元素自身时触发处理函数
.once // 支触发一次
.passive // 会立即触发 (能够提升移动端的性能。)
详情链接…

 <div v-for="v in data" :key="v.id" @click="divClick">
      <a href="http://baidu.com" @click.prevent.stop>百度</a>
 </div>
 methods: {
    divClick() {
      console.log("DIV");
    },
  }

表单

// 自带双向绑定 和 React 不一样

	// 多选框...
	// 点击label 时 也可以选中多选框  checkedNames = []
	<input type="checkbox" id="jack" value="排球" v-model="checkedNames" />
    <label for="jack">排球</label>

    <input type="checkbox" id="john" value="足球" v-model="checkedNames" />
    <label for="john">足球</label>

    <input type="checkbox" id="mike" value="篮球" v-model="checkedNames" />
    <label for="mike">篮球</label>

    <h2>选中: {{checkedNames.join('、')}}</h2>
// 单选框、下拉框
	<label for="nan"></label>:
    <input type="radio" v-model="radios" value="男" id="nan" />
    <label for="mv"></label>:
    <input type="radio" v-model="radios" value="女" id="mv" />
    {{`Radio: ${radios}`}}

    <select v-model="selsectx">
      <option v-for="items in data" :key="items.id">{{items.text}}</option>
    </select>
    {{selsectx}}

父子组件传参

1. 父传子
// 绑定动态 
 <Button :data="data" />
// 绑定静态  
 <Button data="哈哈哈" />
// 子组件中: 
 props: ["data"],
// 传入对象?使用变量的方式
2. 子传父 。通过事件的方式传
// import Button from "@@/Button"; 引入
//  components: { Button },  // 注册
<!-- 子组件 -->
 <button @click="setAge">点击</button>
 methods: {
    setAge() {
	// 定义事件    参数
      this.$emit("getAge", "我是子组件传给父组件的文字...");
    }
  }
<!-- 父组件 -->
<Button @getAge="getAgeInfo"/>  // 子组件定义的事件, 父组件中自定义的事件
 methods: {
    getAgeInfo(items) {
      console.log(items);
    }
 }

全局路由守卫

router.beforeEach((to, from, next) => {
    // 如果没有 token 值 , 并且 浏览器的地址不是login 才会跳转到login 否则 next()...
    if (!localStorage.getItem('token') && to.path !== '/login') {
        next('/login')
    } else {
        next()
    }
})

路由传参

1. this.$route.params
{
    path: '/from/:id',
    component: From,
},
<router-link to="B">点击跳转到B页面</router-link>
<router-link :to="{name:'B',params:{id:item.id}}">点击跳转到B页面</router-link>

 2. props: ["id"], 
{
    path: '/from/:id',
    component: From,
    props: true,
},
// 第一次进来触发
  mounted() {
  },
  // props 改变的时候
  updated() {
  },
   watch: {
    '$route' (to, from) {
  	// 对路由变化做出响应...
  	}	
  }
3.
 <router-link to="/from?id=1&name=嘤嘤嘤">表单</router-link> 
  {
     path: '/from',
      component: From,
      props: route => ({ query: route.query }),
  },
 props: ["query"],

路由懒加载

// 安装: cnpm i --save-dev @babel/plugin-syntax-dynamic-import -S
const Home = () => import(/* webpackChunkName: "Home" */ './pages/home')
// babel.config.js
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
  ],
  "plugins": [
    [
      "component", {
        "libraryName": "mint-ui",
        "style": true
      },
      "@babel/plugin-syntax-dynamic-import"
    ],
  ]
}

重定向

在router文件中index.js里面的routes中加入默认路径
 
{ 
    path:"/",
    redirect:"index"
}

Vuex

在这里插入图片描述
在这里插入图片描述

vuex store/ index.js
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './constants'

const store = new Vuex.Store({
  state: { 
  	data: [],
  },
  // 同步
  mutations: {
    // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
    [SOME_MUTATION] (state, payload) {
      // mutate state
       state.data = payload
    }
  },
  // 异步
   actions: {
   // getData 也可以使用常量 [GET_DATA]
    getData({ commit }, payload) {
     return new Promise((resolve, reject) => {
      // 调用 services/login 里的 loginData 方法 传入参数
	  // export const loginData = options => requestPost(api.login, options)
      loginData(payload)
        .then(res => {
          commit('SOME_MUTATION', res.data)
          resolve(res)
        })
    })
      
    },
   
  },
  
})
// store.dispatch('loginData', '参数')
// store.commit('SOME_MUTATION', '参数')
export default store
数据持久化

数据持久化__相关链接

 // store中 数据持久化
 1. 安装 npm install vuex-persistedstate --save
 2. import createPersistedState from "vuex-persistedstate"
	const store = new Vuex.Store({
	 // ...
		plugins: [createPersistedState({
		    key: 'rootPersisted',
		    // storage: window.sessionStorage,  //不写,默认是localstorage
		    reducer (options) {
		      return {
		       // 要持久化的数据
		      }
		    }
	  	})]
	})

Module
const moduleA = {
  namespaced: true,
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  namespaced: true,
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
store.dispatch('a/state')
this.$store.dispatch('someOtherAction', null, { root: true })  // 可以获取全部state
input输入 存入 vuex 中 可以任何页面使用
 <input :value="message" @input="updateMessage">
 computed: {
  ...mapState({
    message: state => state.obj.message
  })
},
methods: {
  updateMessage (e) {
    this.$store.commit('updateMessage', e.target.value)
  }
}
分页实现
<template>
  <div class="List">
    <el-table :data="List" style="width: 100%">
      <el-table-column prop="countyName" label="姓名" width="180"></el-table-column>
      <el-table-column prop="createTime" label="日期" width="180"></el-table-column>
      <el-table-column prop="id" label="号码" width="180"></el-table-column>
    </el-table>
    <el-pagination
      background
      @current-change="currentChange"
      layout="prev, pager, next"
      :page-size="page.pageSize"
      :current-page="page.currentPage"
      :total="page.total"
    ></el-pagination>
  </div>
</template>
 <script>
//假分页
import monitoringAPI from "@/api/index.js";
monitoringAPI;
export default {
  name: "List",
  data() {
    return {
      List: [],
      page: {
        total: 1,
        pageSize: 5,
        currentPage: 1
      }
    };
  },
  methods: {
    async initFn(pageNo) {
      let res = await monitoringAPI.selfcheckresult();
      this.List = res.data.data.slice(
        (pageNo - 1) * this.page.pageSize,
        pageNo * this.page.pageSize
      );
      this.page.total = res.data.data.length || 1;
    },

    // 页数改变
    currentChange(pageNo) {
      this.initFn(pageNo);
    }
  },
  created() {
    this.initFn(1);
  }
};
</script>


 <style >
</style>
 <template>
  <div>
    <el-button @click="updata">点击改变数据</el-button>
    <el-table
      :data="tableData.slice((currentPage-1)*pagesize,currentPage*pagesize)"
      style="width: 100%"
    >
      <!-- 要使当页显示分页后的对应数据,其下标应为(当前页-1)*每页数据数 到 当前页*每页数据数。使用slice方法进行取用  -->
      <el-table-column prop="id" label="ID" width="180"></el-table-column>
      <el-table-column prop="title" label="标题"></el-table-column>
      <el-table-column prop="peo" label="姓名" width="180"></el-table-column>
      <el-table-column prop="tel" label="手机"></el-table-column>
      <el-table-column prop="dataTimes" label="时间"></el-table-column>
      <el-table-column label="头像">
        <!-- <template scope="scope">
          <p class="pic">
            <img :src="scope.row.pho" :alt="scope.row.peo" />
          </p>
        </template>-->
      </el-table-column>
    </el-table>
    <div class="yema">
      <el-pagination
        background
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[5,10,15]"
        :page-size="pagesize"
        layout="total,jumper,prev, pager, next,sizes"
        :total="tableData.length"
      ></el-pagination>
    </div>

    <!-- handleSizeChange为pagesize发生改变时的相应函数	-->
    <!-- handleSizeChange为pagesize发生改变时的相应函数	-->
    <!-- -->
    <!-- page-sizes为所有可选择的page-size。可以自己更改其中的数字 设置多少条一页 -->
    <!-- layout为附带的功能,一般不用动它 -->
    <!--total为总数据数 -->
  </div>
</template>

  <script>
export default {
  data() {
    return {
      currentPage: 1,
      pagesize: 5,
      tableData: [
        {
          id: "1",
          title: "标题",
          content: "内容 ",
          city: "城市",
          adrs: "地址描述",
          room: "文字描述",
          imgUrl: "图片地址 ",
          dataTimes: "日期",
          peo: "姓名",
          tel: "手机号",
          pho: "img的src地址"
        },
        {
          id: "2",
          title: "标题",
          content: "内容",
          city: "城市",
          adrs: "地址描述",
          room: "文字描述",
          imgUrl: "图片地址 ",
          dataTimes: "日期",
          peo: "姓名",
          tel: "手机号",
          pho: "img的src地址"
        },
        {
          id: "3",
          title: "标题",
          content: "内容",
          city: "城市",
          adrs: "地址描述",
          room: "文字描述",
          imgUrl: "图片地址 ",
          dataTimes: "日期",
          peo: "姓名",
          tel: "手机号",
          pho: "img的src地址"
        },
        {
          id: "4",
          title: "标题",
          content: "内容",
          city: "城市",
          adrs: "地址描述",
          room: "文字描述",
          imgUrl: "图片地址 ",
          dataTimes: "日期",
          peo: "姓名",
          tel: "手机号",
          pho: "img的src地址"
        },
        {
          id: "5",
          title: "标题",
          content: "内容",
          city: "城市",
          adrs: "地址描述",
          room: "文字描述",
          imgUrl: "图片地址 ",
          dataTimes: "日期",
          peo: "姓名",
          tel: "手机号",
          pho: "img的src地址"
        },
        {
          id: "6",
          title: "标题",
          content: "内容",
          city: "城市",
          adrs: "地址描述",
          room: "文字描述",
          imgUrl: "图片地址 ",
          dataTimes: "日期",
          peo: "姓名",
          tel: "手机号",
          pho: "img的src地址"
        }
      ]
    };
  },
  methods: {
    ///分页    初始页currentPage、初始每页数据数pagesize和数据testpage
    handleSizeChange(size) {
      this.pagesize = size;
    },
    handleCurrentChange(currentPage) {
      this.currentPage = currentPage;
    },
    updata() {
      console.log(this.tableData);
    }
  },
  created() {}
};
</script>
watch
handler方法和immediate属性
这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 firstName 改变时才执行监听计算。那我们想要一开始就让他最初绑定的时候就执行改怎么办呢?我们需要修改一下我们的 watch 写法,修改过后的 watch 代码如下:
watch: {
  firstName: {
    handler(newName, oldName) {
      this.fullName = newName + ' ' + this.lastName;
    },
    // 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
    immediate: true
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值