0
点赞
收藏
分享

微信扫一扫

关于Vue的简单学习

杨小羊_ba17 2022-02-17 阅读 76
vue.js

目录

第一个Vue程序

v-if、v-else-is、v-else

v-for

v-on

使用Axios实现异步通信

第一个Axios应用程序

v-bind

v-model

组件

计算属性

插槽与自定义事件

插槽

自定义事件

Vue-cli

Webpack

vue-router

整合ElementUI

登录案例

添加表单验证

嵌套路由

参数传递

路径匹配方式

props传参

组件重定向

去除路径中的 #

处理404

路由钩子函数和异步请求

vuex

vuex操作对象

vuex模块化

第一个Vue程序

Vue官网

先要引入 vue.js,在官网复制 CDN ,或者下载 js 文件都行

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			{{message}}
		</div>
		<script>
		var app = new Vue({
			// element 缩写,挂载元素
			el: "#app",
			data: {
				message: "Hello Vue!" 
			}
		})
		</script>
	</body>
</html>

v-if、v-else-is、v-else

具体作用和其他语言一样

		<div id="app">
			<h1 v-if="flag === 'awe'">Vue is awesome</h1>
			<h1 v-else-if="flag === 'no'">No no 👻</h1>
			<h1 v-else>Yes yes 🤡</h1>
		</div>
		<script>
		var app = new Vue({
			
			el: "#app",
			data: {
				// flag: "awe",
				// flag: "no",
				flag: "yes"
			}
		})
		</script>

 

v-for

我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名

这里的 items 相当于 Java 中的数组,而 item 就相当于从数组中遍历出的对象,要使用其中的属性直接 对象.属性 即可

		<ul id="app">
			<li v-for="item in items">
				{{item.message}}
			</li>
		</ul>
		<script>
		var app = new Vue({
			
			el: "#app",
			data: {
				items: [
					{message: '小红'},
					{message: '小明'},
					{message: '小李'}
					]
			}
		})
		</script>

 

v-on

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

		<!-- 点击按钮,弹出弹窗,显示 message 中的内容 -->
		<div id="app">
			<button v-on:click="func">按钮</button>
		</div>
		<script>
		var app = new Vue({
			
			el: "#app",
			data:{
				message: "Hello Vue"
			},
			methods:{
				func:function(){
					alert(this.message)
				}
			}
		})
		</script>

使用Axios实现异步通信

第一个Axios应用程序

现在前端伪造一段 json 数据

{
	"name": "百度",
	"url": "http://www.baidu.com",
	"page": 66,
	"isNonProfit": true,
	"address": {
		"street": "海定区",
		"city": "北京",
		"country": "中国"
	},
	"links": [
		{
			"name": "Google",
			"url": "http://www.geogle.com"
		},
		{
			"name": "Sougou",
			"url": "http://www.sougou.com"
		}
	]
	
}

使用 axios 来获取

		<div id="app">
			<div>
				名称:{{info.name}}<br>
				链接:{{info.url}}
			</div>
			<ul>
				<li v-for="link in info.links">
					<p>名称:{{link.name}}</p>
					<p>链接:{{link.url}}</p>
				</li>
			</ul>
		</div>
		<script>
		var app = new Vue({
			el: "#app",
			data(){
				return{
					info: {
						name: '',
						url: '',
						links: []
					}
				}
			},
			mounted() {
				axios.get('data.json').then(respose => this.info = respose.data)
			}
			
		})
		</script>

v-bind

我们可以在标签的任意属性前面加上 v-bind,这样我们就可以将值赋给标签的属性了

例如:让上面百度的链接可以点击

 

 

v-model

使用 v-model 来实现数据的双向绑定。注意:v-model 会忽略所有表单元素的 valuecheckedselected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。

实现和表单的数据同步显示

		<div id="app">
			<input type="text" v-model="message"/>
			<p>Message is: {{message}}</p>
		</div>
		<script>
		var app = new Vue({
			el: "#app",
			data:{
				message: ""
			}
		})
		</script>

其他的 多行文本单选按钮复选框选择框 的使用查看官网即可

组件

使用 Vue.component 定义一个组件,并将 data 中的值赋给组件,具体值是如何传递的如箭头所示

计算属性

计算属性是用来声明式的描述一个值依赖了其他的值,当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新DOM。简单来说,它是一个能够将计算结果缓存起来的属性(把行为转化为了静态属性)。

使用 computed 来声明一个计算属性,注意 methods 中的方法名和 computed 中的属性名不能相同

		<div id="app">
			<p>当前时间:{{getCurrentTime()}}</p>
			<p>当前时间属性:{{getCurrentTime1}}</p>
		</div>
		<script>
		var app = new Vue({
			el: "#app",
			methods:{
				getCurrentTime:function(){
					return Date.now();
				}
			},
			computed:{
				getCurrentTime1:function(){
					return Date.now();
				}
			}
		})
		</script>

 

计算属性和方法的区别

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。

插槽与自定义事件

插槽

使用 <slot> 标签来将组件进行动态拔插,下面我们将标题组件和内容组件通过插槽的方式进行插入

		<div id="app">
			<todo>
				<todo-title slot="todo-title" v-bind:title="title"></todo-title>
				<todo-items slot="todo-items" v-for="item in items" v-bind:item="item">
					
				</todo-items>
			</todo>
		</div>
		<script>
		// 定义代办事项组件
		Vue.component("todo", {
			template:"<div><slot name='todo-title'></slot><ul><slot name='todo-items'></slot></ul></div>"
		});
		// 标题组件
		Vue.component("todo-title", {
			props:['title'],
			template:"<div>{{title}}</div>"
		});
		// 内容组件
		Vue.component("todo-items", {
			props:['item'],
			template:"<li>{{item}}</li>"
		})
		var app = new Vue({
			el: "#app",
			data:{
				title: "标题",
				items: ["吃饭", "睡觉", "看电视"]
			}
		})
		</script>

 

自定义事件

根据上面案例,我们想实现在列表的每一个元素后面添加删除按钮,实现删除

 

我们的子组件是没办法直接调用外面的方法,因此,我们只能在子组件内定义方法,然后将该方法与外面的方法进行绑定,这里我们就要使用 this.$emit

Vue-cli

Vue-cli: 官方提供的一个脚手架(预先定义好目录结构和基础代码,与 java 中的 maven 类似),用于快速生成一个 vue 的项目模板

具体安装过程根据网上教程安装即可

Webpack

简介:是一个现代化的 JavaScript 应用程序静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将这些模块打包成一个或多个 bundle

安装:

npm install webpack webpack-cli -g

简单使用

编写下面两个 js 文件

hello.js

exports.sayHi = function(){
	document.write("<div>Hello Vue3456789!</div>")
}

main.js

var hello = require("./hello");
hello.sayHi();

webpack 配置文件,必须命名为 webpack.config.js,这里只是简单使用

module.exports = {
	entry: "./modules/main.js",
	output: {
		filename: "./js/bundle.js"
	},
	watch: true //检测代码的变化,也可以在打包时使用 webpack --watch 打包开启
}

在控制台中进入项目目录,使用 webpack 指令进行打包,就会出现下面文件

在 html 文件中引入

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script src="dist/js/bundle.js"></script>
	</body>
</html>

 

vue-router

简介:Vue Router 是 Vue.js 官方的路由管理器,它和 Vue.js 的核心深度集成,让构建单页应用变得易如反掌,包含的功能有:

  • 嵌套路由映射

  • 动态路由选择

  • 模块化、基于组件的路由配置

  • 路由参数、查询、通配符

  • 展示由 Vue.js 的过渡系统提供的过渡效果

  • 细致的导航控制

  • 自动激活 CSS 类的链接

  • HTML5 history 模式或 hash 模式

  • 可定制的滚动行为

  • URL 的正确编码

简而言之,就是可以实现页面跳转的功能

安装:在想要安装的项目目录下输入下面指令

npm install vue-router --save-dev

如果报下面的错

就使用这个命令

npm install vue-router --save-dev --legacy-peer-deps

简单实现

先编写一个组件

<template>
  <div>我是HelloWorld</div>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

配置路由

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '../components/HelloWorld.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/hello',
      name: 'HelloWorld',
      component: HelloWorld
    }
  ]
})

main.js 中添加 router

路径跳转时,使用组件

 

整合ElementUI

安装依赖

router:

npm install vue-router --save-dev --legacy-peer-deps

elementui:

npm i element-ui -S

sass-loader 和 node-sass

npm install sass-loader@7.3.1 sass@1.26.5  --save-dev

//最后安装sass@1.26.5
npm install sass@1.26.5  --save-dev

安装所有依赖

npm install

简单使用

引入 element

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

显示使用

Vue.use(ElementUI);

在 new Vue 中添加

render: h => h(App)

再在 element 官网 组件 | Element 选择自己需要的组件,CTRL+C/V,修改即可

登录案例

编写登陆页面组件 Login.vue

<template>
  <div>
    <el-form ref="form" :model="form" class="login-box">
      <h3 class="login-title">欢迎登录</h3>
      <el-form-item label="账号">
        <el-input type="text" v-model="form.name" placeholder="请输入用户名"></el-input>
      </el-form-item>
      <el-form-item label="密码">
        <el-input type="password" v-model="form.password" placeholder="请输入密码"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">登录</el-button>
        <el-button>取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
  export default {
    name: 'Login',
      data() {
        return {
          form: {
            name: '',
            password: ''
          }
        }
      },
      methods: {
        onSubmit() {
          this.$router.push("/main");
        }
      }
    }
</script>
<style lang="scss" scoped>
  .login-box{
    width: 350px;
    margin: 150px auto;
    border: 1px solid #DCDFE6;
    padding: 20px;
    border-radius: 5px;
    box-shadow: 0 0 30px #DCDFE6;
  }
  .login-title{
    text-align: center;
  }
</style>

主页面组件

<template>
  <div>登陆成功</div>
</template>

<script>
  export default {
    name: 'Main'
  }
</script>

<style>
</style>

配置路由

import Vue from 'vue'
import Router from 'vue-router'
import Login from '../views/Login.vue'
import Main from '../views/Main.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/login',
      name: 'Login',
      component: Login
    },
    {
      path: '/main',
      name: 'Main',
      component: Main
    }
  ]
})

main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI)

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  render: h => h(App),
  router,
  components: { App },
  template: '<App/>'
})

App.vue

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

<script>
export default {
  name: 'App'
}
</script>

<style>
</style>

添加表单验证

需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名,校验规则:async-validator

设置验证规则

设置点击登录时检测,这里只是检测是否为空,并未进行匹配

      methods: {
        onSubmit(formName) {
                this.$refs[formName].validate((valid) => {
                  if (valid) {
                    this.$router.push("/main");
                  } else {
                    this.$message({
              			message: '请输入用户名或密码',
              			type: 'warning'
           			 });
                    return false;
                  }
                });
              }
      }

 

嵌套路由

 

我们现在有上面一个页面,要实现顶部和导航不变,点击导航相应按钮时,只有中间内容部分发生变化。这里就要使用嵌套路由

首先编写会员等级和会员列表的组件

MemberLevel.vue

<template>
  <div>
    会员等级
  </div>
</template>

<script>
  export default {
    name: 'MemberLevel'
  }
</script>

<style>
</style>

 MemberList.vue

<template>
  <div>
    会员列表
  </div>
</template>

<script>
  export default {
    name: 'MemberList'
  }
</script>

<style>
</style>

配置组件路由,因为这里是要获取到上面组件后,放在 Main.vue 中,因此使用嵌套路由 children,格式如下

参数传递

路径匹配方式

方式一:

修改路由配置:在路径中使用形式为 :id 的占位符,然后在请求路径后加上相应参数

 

 

获取参数:使用 {{$route.params.id}} 形式获取

<template>
  <div>
    会员等级 ID={{$route.params.id}}
  </div>
</template>

 

方式二:

修改请求路径的形式:

 

props传参

在配置路由时开启 props

	{
        path: '/member/level/:id',
        name: 'MemberLevel',
        component: MemberLevel,
        props: true
      }

在对应组件内用 props 接收

其他和路径匹配一样

组件重定向

使用不同的路径访问同一个组件,路由中配置即可

 

去除路径中的 #

 

在 index.js 中加上 mode:'history'

 

处理404

使用通配符 *,来处理 404

{
      path: '*',
      name: 'NotFound',
      component: NotFound
    }

路由钩子函数和异步请求

路由钩子函数

beforeRouteEnter:在进入路由前执行

beforeRouteLeave:在离开路由前执行

在项目目录下安装 axios

npm install axios -s

在 main.js 中导入 axios

import axios from 'axios'

Vue.prototype.axios = axios

示例

<template>
  <div>
    会员等级 ID={{id}}
  </div>
</template>

<script>
  export default {
    name: 'MemberLevel',
    props:['id'],
    beforeRouteEnter(to, from, next)  {
      console.log("进入会员等级页面");
      next(vm => {
        vm.getData();
      });
    },
    beforeRouteLeave(to, from, next)  {
      console.log("离开会员等级页面");
      next();
    },
    methods:{
      getData: function(){
        this.axios({
          method: 'get',
          url: 'http://localhost:8080/data.json'
        }).then(function(repos){
          console.log(repos);
        }).catch(function(error){
          console.log(error);
        });
      }
    }
  }
</script>

<style>
</style>

这里由于将数据存在了 tomcat 中,会出现跨域问题,在后端再解决

vuex

Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式,它采用集中式存储管理应用程序的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。cookie 和 session ???

安装

在项目根目录下安装

npm install vuex --save

报错就用这个

npm install vuex --save --legacy-peer-deps

在 main.js 中引入和使用

import Vuex from 'vuex'

Vue.use(Vuex)

//每次路由跳转之前执行
router.beforeEach((to, from, next) => {
  let isLogin = sessionStorage.getItem("isLogin");
  if (to.path == '/logout') {
    //清空
    sessionStorage.clear();
    //跳转到登录页面
    next({
      path: '/login'
    });
  } else if (to.path == '/login') {
    //判断是否为空,不为空跳转到首页
    if (isLogin != null) {
      next({
        path: '/main/:name'
      })
    }
  }
  next();
})

vuex操作对象

import Vue from 'vue'
import Vuex from 'Vuex'

Vue.use(Vuex)

//全局state对象,用于保存所有组件的公共数据
const state=sessionStorage.getItem('state') ? JSON.stringify(sessionStorage.getItem('state')):{
  user:{
    name: ''
  }
};
//监听state对象值的最新状态(计算属性)
const getters={
  getUser(state){
    return state.user;
  }
}
//唯一一个可以修改 state 值的方法(同步执行)
const mutations={
  updateUser(state,user){
    state.user = user;
  }
}
//异步执行 mutations 中的方法
const actions={
  asyncUpdateUser(context,user){
    context.commit("updateUser",user);
  }
}

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

vuex模块化

就是将每个对象提出来

const user = {
  //全局state对象,用于保存所有组件的公共数据
  state: {
    user: {
      name: ''
    }
  },
  //监听state对象值的最新状态(计算属性)
  getters: {
    getUser(state) {
      return state.user;
    }
  },
  //唯一一个可以修改 state 值的方法(同步执行)
  mutations: {
    updateUser(state, user) {
      state.user = user;
    }
  },
  //异步执行 mutations 中的方法
  actions: {
    asyncUpdateUser(context, user) {
      context.commit("updateUser", user);
    }
  }
}
export default user;
举报

相关推荐

0 条评论