这里有篇讲Vue的博客,挺不错的,参考:
https://blog.csdn.net/qq_44317018/article/details/104146747
首先使用vscode快捷键打开当前文件夹下的命令行
Ctrl + `
运行
npm init -y
生成package.json文件
在项目中需要用到webpack进行打包,下面安装webpack
执行
npm install webpack webpack-cli -D
其中-D是 --save-dev的简写,表示开发环境依赖
首先对项目进行基本配置
创建index.html、main.js等
npm install vue
配置完成后在node_modules文件夹下回多出一个vue文件夹,并且在package.json中会多出vue依赖
//导入path模块
const path=require('path')
module.exports={
//打包入口
entry:'./src/main.js',
//打包出口
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'dist')
}
}
在package.json中添加脚本指令
现在打包执行下面的指令即可
npm run build
vue-loader官方文档:https://vue-loader.vuejs.org/
loader的官方文档:https://www.webpackjs.com/loaders/
执行:
npm install -D vue-loader vue-template-compiler
执行:
npm install -D css-loader
npm install style-loader --save-dev
配置webpack配置文件:
//导入path模块
const path=require('path')
const {
Plugin } = require('webpack')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports={
//打包入口
entry:'./src/main.js',
//打包出口
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'dist')
},
//打包规则
module:{
rules:[
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
//插件配置
plugins:[
new VueLoaderPlugin()
]
}
报错:
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.
默认导出:vue.common.js
在webpack中添加 别名的配置:
resolve:{
alias:{
'vue':'vue/dist/vue.js'
}
}
Test.vue:
<template>
<div>
<button id="btn_add" @click="add_num()">+button>
<h2 id="num">{
{num}}h2>
<button id="btn_del" @click="del_num()">-button>
div>
template>
<script>
export default {
name:"test",
data:function () {
return{
num:0
}
},
methods:{
add_num:function () {
console.log(123);
this.num++;
},
del_num:function () {
this.num--;
}
}
}
script>
main.js:
import Vue from 'vue'
import test from './Test.vue'
const app=new Vue({
el: '#app',
components:{
test
},
template:` `
})
代码如下:
Test2.vue:
<template>
<div>
<h1>用户名:{
{name}}h1>
<h2>性别:{
{sex==1?"男" :"女"}}h2>
<h3>下单时间:{
{new Date().toLocaleDateString()}}h3>
<h3>小计:¥{
{(price*count).toFixed(2)}}h3>
<input v-model="name" type="text">
<input type="radio" id="male" value="1" v-model="sex" name="sex">男
<input type="radio" id="male" value="0" v-model="sex" name="sex">女
div>
template>
<script>
export default {
name:"test2",
data:function() {
return{
name:"张三",
sex:"1",
orderTime:"1579507293225",
price:12.5,
count:5
}
}
}
script>
这里讲过复选框等基础控件的v-modal的用法:
https://blog.csdn.net/lzl980111/article/details/104740163
<template>
<div>
<h2 v-if="isLogin">已登录h2>
<a @click="login()">登录a>
<a @click="exit()">注销a>
div>
template>
<script>
export default {
name:"test3",
data:function(){
return{
isLogin:false
}
},
methods:{
login:function () {
this.isLogin=true
},
exit:function () {
this.isLogin=false
}
}
}
script>
这里使用v-show也是可以实现的,v-show是加入了display:none这个css样式,而v-if是直接删除dom,相比的话v-if效率会低一些
<template>
<div>
<h1>Message:{
{message_now}}h1>
<input v-model="message_now" v-focus>
<br>
<button @click="addObv()">添加观察者button>
<br>
<button @click="publish_message()">发布button>
<ul>
<li v-for="(item,index) in observers" :key='index'>
<h2>观察者姓名:{
{item.name}}h2>
<h3>观察者信息:{
{item.message}}h3>
li>
ul>
div>
template>
<script>
export default {
name:"test4",
data:function(){
return {
message_now:"123",
observers:[
{
name:"obv1",
message:"321",
getNewMessage:function(){
this.message=message_now
}
}
],
}
},
methods:{
//定义addObv方法用来添加观察者
addObv:function(){
console.log("测试添加观察者");
const obverser={
name:"obv",
message:this.message
};
this.observers.push(obverser);
console.log("观察者添加完成");
},
//定义publish_message方法用来发布信息
publish_message:function(){
this.observers.forEach(observer=>{
observer.item="obv",
observer.message=this.message_now
})
},
}
}
script>
main.js:
import Vue from 'vue'
import test4 from './Test4.vue'
/**
* 此处应用自定义指令,在相应的控件上添加对应指令即可应用
* 例:v-focus
*/
Vue.directive("focus",{
inserted(domElem){
//让当前元素自动获得焦点
domElem.focus();
}
})
const app=new Vue({
el: '#app',
components:{
test4
},
template:` `
})
上面还用到了自定义指令,自动聚焦到文本框
购物车
<template>
<div>
<div v-if="books.length">
<table>
<thead>
<tr>
<th>th>
<th>书籍名称th>
<th>出版日期th>
<th>价格th>
<th>数量th>
<th>操作th>
tr>
thead>
<tr v-for="(item,index) in books" :key="index">
<td>{
{item.id}}td>
<td>{
{item.bookname}}td>
<td>{
{item.pubdate}}td>
<td>{
{item.price | showPrice}}td>
<td>
<button @click="decrement(index)" v-bind:disabled="item.count<=1">-button>
{
{item.count}}
<button @click="increment(index)" >+button>
td>
<td><button @click="del(index)">移除button>td>
tr>
<tbody>tbody>
table>
<h2>总价格:{
{sum}}h2>
div>
<h2 v-else>购物车为空h2>
div>
template>
<script>
export default {
name:"test5",
data:function(){
return{
books:[
{
id:1,bookname:'计算机网络',pubdate:'2006-9',price:15.00,count:1},
{
id:2,bookname:'操作系统',pubdate:'2016-9',price:20.00,count:1},
{
id:3,bookname:'JavaSE程序设计',pubdate:'2012-9',price:35.00,count:1},
{
id:4,bookname:'PHP程序设计',pubdate:'2010-9',price:42.00,count:1},
]
}
},
methods:{
increment:function(index){
console.log('---------increment'+index)
this.books[index].count++;
},
decrement:function(index){
//if (this.books[index].count==0) return;
console.log('---------decrement'+index)
this.books[index].count--;
},
del:function(index){
this.books.splice(index,1);
}
},
filters:{
/**
* 过滤器语法格式:
* (1). 绑定语法中: {
{变量 | 过滤器1 |过滤器2 | … }}
(2). 强调:
a. 后一个过滤器2,进入的旧值,已经不是变量的原始值了,而是前一个过滤器加工后的中间值。
b. 只有最后一个过滤器的返回值,才会显示到页面上。如果希望前几个过滤器的返回值也能一起显示到页面上,只能在最后一个过滤器中将新值拼接到上一步过滤器传入的旧值上。
*/
showPrice(price){
return '¥'+price.toFixed(2)
}
},
computed:{
/**
* computed区别于methods
* computed(计算属性)
* (1). 只要计算属性所依赖的另一个属性值发生改变,同样会通知计算属性重新计算新的属性值。
(2). 计算属性计算出的结果,会被Vue缓存起来,反复使用,避免重复计算。即使反复使用多次,也只在首次计算一次。
-------区别--------
(1). 用法:
a. methods必须加()
b. computed 不用加()
(2). 反复使用:
a. methods中的方法,每调用一次,就会重新执行一次,执行结果,不会被vue缓存起来。
b. computed中的计算属性,只在第一次使用时计算一次,然后,结算结果,就会被Vue缓存起来,即使在别的地方反复使用这个计算属性,也不会重复计算,而是直接从缓存中获取值。但是,当所依赖的其他属性值发生变化时,计算才被迫重新计算一次。
如何选择methods和computed:
(1). 如果这次使用时,更关心函数的执行结果数据时,首选计算属性
(2). 如果这次使用时,更关心函数执行操作的过程,结果数据无所谓,甚至函数没有返回值,则首选methods中的方法。
*
*/
sum:{
get(){
let sum=0;
for (let book of this.books){
sum+=book.count*book.price;
}
return sum+'¥';
}
}
}
}
script>
<style scoped>
table{
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th, td{
padding: 8px 16px;
border:1px solid #e9e9e9;
text-align: left;
}
th{
background-color: #f7f7f7;
color: #5c6b77;
font-weight:600;
}
style>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<meta name="format-detection" content="telephone=no">
<meta charset="UTF-8">
<meta name="description" content="Violate Responsive Admin Template">
<meta name="keywords" content="Super Admin, Admin, Template, Bootstrap">
<style>
hr{
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top-color: currentcolor;
border-top-style: none;
border-top-width: 0px;
border-top: 1px solid #eee;
}
style>
head>
<body id="skin-blur-violate">
<title>Vue练习title>
<div id="app">
<p>{
{name}}p>
<p>计算属性:{
{sum}};计算属性是基于它们的响应式依赖进行缓存的,若num1或num2没有发生改变,再次获取sum是直接获取到而不需要执行其中的方法,区别于methodsp>
<p>{
{fullName}}p>
<hr>
<p>请输入问题:p>
<input v-model="question">
<p>{
{answer}}p>
<div v-bind:class="{active:isActive}">div>
<h1 v-if="isActive">Vue is awesome!h1>
<h1 v-else>Oh no h1>
<button @click="changeActive()">改变isActivebutton>
<ul>
<li v-for="(item,index) in books">
{
{item}}
li>
ul>
<input v-on:keyup.13="enterdown" placeholder="回车监听" v-model="book">
<hr>
<h2>model与各个控件之间的使用h2>
<p>{
{textmessage}}p>
<input type="text" v-model="textmessage">
<hr>
<p style="white-space: pre-line;">{
{textareamessage}}p>
<textarea name="" id="" cols="30" rows="10" v-model="textareamessage">textarea>
<hr>
<p>{
{checkboxmessage}}p>
<input type="checkbox" v-model="checkboxmessage">
<hr>
<p>{
{checkedmessage}}p>
<input type="checkbox" value="西游记" v-model="checkedmessage"><label>西游记label>
<input type="checkbox" value="三国演义" v-model="checkedmessage"><label>三国演义label>
<input type="checkbox" value="水浒传" v-model="checkedmessage"><label>水浒传label>
<input type="checkbox" value="红楼梦" v-model="checkedmessage"><label>红楼梦label>
<hr>
<p>{
{sex==1 ? '男' : '女'}}p>
<input type="radio" v-model="sex" value="1"><label>男label>
<input type="radio" v-model="sex" value="0" checked><label>女label>
<hr>
<p>{
{selected|selected}}p>
<select v-model="selected">
<option value="1">西游记option>
<option value="2">三国option>
<option value="3">鲁滨逊option>
select>
<hr>
div>
body>
<script src="./vue.js">script>
<script>
const app=new Vue({
el:"#app",
data:{
name:"张三",
num1:1,
num2:2,
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar',
question:'',
answer:'I cannot give you an answer until you ask a question!',
isActive:false,
books:["海贼王","JAVA","三国"],
book:'',
textmessage:'textmessage',
textareamessage:'textareamessage',
checkboxmessage:true,
checkedmessage:[],
sex:'性别',
selected:''
},
computed:{
sum:function(){
return this.num1+this.num2
},
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
},
},
methods:{
changeActive:function(){
if(this.isActive){
this.isActive=false;
}else{
this.isActive=true;
}
},
enterdown:function(){
this.books.push(this.book);
}
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
},
question:function(newque,oldque){
console.log("测试quest");
this.answer='Waiting for you to stop typing...';
},
books:function(){
console.log("测试数组");
}
},
filters:{
selected:function(value){
switch(value){
case '1':
return '西游记';
break;
case '2':
return '三国'
break;
case '3':
return '鲁滨逊'
break;
}
}
}
})
script>
html>