vue父子组件传值,option 和onclick,select,@image()@change,商品管理【诗书画唱】
'@image()',在mockjs中是用来生成随机图片的。
目录:
例子1:熟练完成单页面VUE演示程序代码。(代码等部分见例子7)
当绑定一个属性的时候用v-bind,比如绑定url属性的时候用v-bind:url,但是v-bind:url等等是可以简写成:url的(v-bind:可以简写成:)。
同时,Vscode中,<myTag/>等驼峰命名法的组件或属性等等和my-tag之类的组件或属性等等是等价的。
例子2:创建一个下拉框,父组件是<select>,子组件<option>,在这两个组件之间传值,select传值到option,option中传值到select(本题意义不大,所以不必深究)
Vscode中:
Select1.vue
/**在IE里, select的option是不支持onclick事件的, 而在FF 和 OPERA 里, option 是支持onclick事件的 */
index.js
HBuilder中:
在这两个组件之间传值,select传值到option,option中传值到select.html
select为子组件,option为父组件,进行父子组件的互相传值.html
例子3:创建一个表单,父组件是<form>,子组件是输入文本框,将输入文本框中的值传递给<form>
创建一个表单,父组件是form,子组件是输入文本框,将输入文本框中的值传递给form.html
方法1
方法2:用 v-model="childValue"或 v-model:value="childValue"
例子4:静态绑定(个人理解为:子组件中的属性值=值之类的,值写成固定值了,于是称之为静态绑定。动态绑定就是子组件中的属性值=变量名之类的,该变量名的变量的值可变,在别处可以设置变量名=某个自定义的值,于是称之为动态绑定),使用props让父组件调用时,相当于调用了很多被父组件传值,赋值的子组件,其中发生了父组件传值给子组件的过程(在父组件的template中,调用了子组件,并且声明了子组件的某个属性的值。template关于模板字符串中的子组件HTML代码等等的调用,其实就是父组件被调用时会返回,会显示的内容)
本例子调用父组件的结果就是调用被父组件声明值(即传值)的4个子组件。myTag,my-tag(驼峰命名法),dataMsg和data-msg(我称之为:以短杠为分割符的命名法)在本例中作为子组件名和子组件的属性值,是可以互换,等价的。
例子5:在例子4的基础上,实现父组件传值给子组件,动态绑定(用v-bind:XXX或:XXX。v-bind:XXX可以略写掉v-bind,简写成:XXX,效果相同,都有绑定的效果)
vue中引用数据中的图片路径示例.html
例子7:HBuilder实现基础简单的增删查功能的vue商品管理程序(单页面)
例子8:Vscode中用axios,mockjs等等实现基础简单的增删查功能的vue商品管理程序(单页面)
'@image()',在mockjs中是用来生成随机图片的。
npm install --save axios mockjs
Products.vue
index.js
mock.js
学习截图
--save-dev何-save的区别
给option中加点击事件的方法.html

例子1:熟练完成单页面VUE演示程序代码。(代码等部分见例子7)


父子组件的传参方式:父传子通过props属性来传递参数,子传父通过emit来传递参数

当绑定一个属性的时候用v-bind,比如绑定url属性的时候用v-bind:url,但是v-bind:url等等是可以简写成:url的(v-bind:可以简写成:)。
同时,Vscode中,<myTag/>等驼峰命名法的组件或属性等等和my-tag之类的组件或属性等等是等价的。
例子2:创建一个下拉框,父组件是<select>,子组件<option>,在这两个组件之间传值,select传值到option,option中传值到select
Vscode中:
Select1.vue

<template>
<div id="app">
<parent />
</div>
</template>
<script>
/**在IE里, select的option是不支持onclick事件的, 而在FF 和 OPERA 里, option 是支持onclick事件的 */
var childNode = {
template: `<option @click="f" :value=dataMsg>{{dataMsg}}</option>`,
data() {
return {
childValue:
"诗书画唱提醒你!我是子组件的数据(childValue),\n" +
"我通过$emit传到父组件来了,被用在console.log(childValue)中!",
};
},
props: ["dataMsg"],
methods: {
f() {
alert(666);
this.$emit('cd', this.childValue);
},
},
};
var parentNode = {
template: `<select @change= "cdChange" ><child v-on:cd="childByValue" v-bind:data-msg = "sshc" ></child>
<child v-on:cd="childByValue" v-bind:data-msg = "sl" ></child></select>`,
components: {
child: childNode,
},
data: function () {
return {
sshc: "诗书画唱,",
sl: "值得三连!",
};
},
methods: {
childByValue: function (childValue) {
// childValue就是子组件传过来的值:
console.log(childValue);
},
cdChange() {
alert("触发了select中的onchange事件");
// console.log(childNode)
// childNode.methods.cdChange()
},
},
};
export default {
components: {
parent: parentNode,
},
};
</script>

index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
//自己加入的必须加载和要使用组件的代码 START
import Select1 from '@/components/Select1'
//自己加入的必须加载和要使用组件的代码 END
Vue.use(Router)
export default new Router({
routes: [
{//http://localhost:8080/#/Select1
path: '/Select1',
name: 'Select1',//路由跳转时使用
component: Select1
}
//自己加的代码 END
]
})
//解决重复点击路由,界面跳转等时报错的代码 START
const originalPush = Router.prototype.push
Router.prototype.push = function push (location) {
return originalPush.call(this, location).catch(err => err)
}
//解决重复点击路由,界面跳转等时报错的代码 END


HBuilder中:
在这两个组件之间传值,select传值到option,option中传值到select.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" srcc="js/vue.js"></script>
</head>
<body>
<div id="app">
<parent/>
</div>
<script>
var childNode = {
template: `<option :value=dataMsg>{{dataMsg}}</option>`,
data() {
return {
childValue: '诗书画唱提醒你!我是子组件的数据(childValue),\n' +
'我通过$emit传到父组件来了,被用在console.log(childValue)中!'
}
},
props: ['dataMsg'],
methods: {
}
};
var parentNode = {
template: `<select @change= "cdChange"><child v-on:cd="childByValue" v-bind:data-msg = "sshc" ></child>
<child v-on:cd="childByValue" v-bind:data-msg = "sl" ></child></select>`,
components: {
child: childNode
},
data: function() {
return {
sshc: "诗书画唱,",
sl:"值得三连!"
}},
methods: {
childByValue: function(childValue) {
// childValue就是子组件传过来的值:
console.log(childValue);
},
cdChange() {
alert('触发了select中的onchange事件')
// this.$emit('cd', this.childValue);
}
}
};
new Vue({
el: '#app',
components: {
parent: parentNode
}
});
</script>
</body>
</html>


select为子组件,option为父组件,进行父子组件的互相传值.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" srcc="js/vue.js"></script>
</head>
<body>
<div id="app">
<show/>
</div>
<script>
let child={
template:`<select @change="chg">
<option >{{mydata}}</option>
<option >{{mydata}}</option>
<option >{{mydata}}</option>
</select>`,
props:['mydata'],
data:function(){
return{
msg:'我改变了'
}
},
methods:{
chg:function(){
this.$emit('myEve',this.msg);//把this.msg传到myEve这个方法中
}
}
};
let parent={
template:`
<op mydata='诗书画唱' @myEve="valFromChild" />
<!--声明myEve方法就是为valFromChild(val)方法,其中val=this.msg
@myEve和v-on:myEve是等价的
-->
`,
components:{
op:child
},
methods:{
valFromChild(val){
console.log('来自子组件的数据:'+val)
}
,
data: function() {
return {
sshc: "诗书画唱",
sl: "三连"
}
}
}
};
new Vue({
el:'#app',
components:{//注册需要使用的组件
show:parent
}
})
</script>
</body>
</html>


例子3:创建一个表单,父组件是<form>,子组件是输入文本框,将输入文本框中的值传递给<form>
创建一个表单,父组件是form,子组件是输入文本框,将输入文本框中的值传递给form.html

方法1
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" srcc="js/vue.js"></script>
</head>
<body>
<div id="app">
<parent/>
</div>
<script>
var childNode = {
template: `<input type = "text" @input = "cdClick" >`,
data() {
return {
childValue: '诗书画唱提醒你!我是子组件的数据(childValue),\n' +
'我通过$emit传到父组件来了,被用在console.log(childValue)中!'
}
},
methods: {
cdClick() {
//第一个参数自定义事件名
//第二个参数this. childValue是需要传的值
this.$emit('cd', this.childValue);
}
}
};
var parentNode = {
template: `<form><child v-on:cd="childByValue"></child></form>`,
components: {
child: childNode
},
methods: {
childByValue: function(childValue) {
// childValue就是子组件传过来的值:
console.log(childValue);
}
}
};
new Vue({
el: '#app',
components: {
parent: parentNode
}
});
</script>
</body>
</html>


方法2:用 v-model="childValue"或 v-model:value="childValue"
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" srcc="js/vue.js"></script>
</head>
<body>
<div id="app">
<parent/>
</div>
<script>
var childNode = {
template: `<input type = "text" @input = "cdClick" v-model="childValue">`,
data() {
return {
childValue: '给诗书画唱三连'
}
},
methods: {
cdClick() {
//第一个参数自定义事件名
//第二个参数this. childValue是需要传的值
this.$emit('cd', this.childValue);
}
}
};
var parentNode = {
template: `<form><child v-on:cd="childByValue"></child></form>`,
components: {
child: childNode
},
methods: {
childByValue: function(childValue) {
// childValue就是子组件传过来的值:
console.log(childValue);
}
}
};
new Vue({
el: '#app',
components: {
parent: parentNode
}
});
</script>
</body>
</html>


例子4:静态绑定(个人理解为:子组件中的属性值=值之类的,值写成固定值了,于是称之为静态绑定。动态绑定就是子组件中的属性值=变量名之类的,该变量名的变量的值可变,在别处可以设置变量名=某个自定义的值,于是称之为动态绑定),使用props让父组件调用时,相当于调用了很多被父组件传值,赋值的子组件,其中发生了父组件传值给子组件的过程(在父组件的template中,调用了子组件,并且声明了子组件的某个属性的值。template关于模板字符串中的子组件HTML代码等等的调用,其实就是父组件被调用时会返回,会显示的内容)



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" srcc="js/vue.js"></script>
</head>
<body>
<div id="app">
<!--在id为app的div中调用自定义名字的父组件(在这里调用这个父组件,
相当于调用获取自定义个数的被父组件赋值了的子组件的效果):-->
<show/>
</div>
<script>
/*定义一个子组件(标签),名为child,
当前定义的这个child标签(即为child子组件)
中有一个dataMsg(data-msg)属性:*/
let child = {
template: `<h1>{{dataMsg}}</h1>`,
props: ['dataMsg']
};
let parent = {
template: `<div >
<myTag data-msg = "三连" />
<myTag data-msg = "关注" />
<my-tag data-msg = "三连" />
<my-tag data-msg = "关注" />
</div>`,
/*在parent组件中会注册需要使用的其他组件child,并且给组件取名为myTag,
即给child这个子租价起别名 为myTag后,调用myTag。
(parent组件中的template中会调用myTag,相当于
调用child组件,而child组件中,因为props: ['dataMsg']这段代码,
所以可以通过<myTag data-msg = "三连" /> 的方式设置
template: `<h1>{{dataMsg}}</h1>`中的值:*/
components: {
myTag: child
}
};
new Vue({
el: '#app',
components: {
show: parent
}
});
</script>
</body>
</html>

本例子调用父组件的结果就是调用被父组件声明值(即传值)的4个子组件。myTag,my-tag(驼峰命名法),dataMsg和data-msg(我称之为:以短杠为分割符的命名法)在本例中作为子组件名和子组件的属性值,是可以互换,等价的。




例子5:在例子4的基础上,实现父组件传值给子组件,动态绑定(用v-bind:XXX或:XXX。v-bind:XXX可以略写掉v-bind,简写成:XXX,效果相同,都有绑定的效果)



<my-tag v-bind:data-msg = "sshc" />
<my-tag :data-msg = "sshc" />
data: function() {
return {
sshc: "诗书画唱"
}
}

例子6:通过$emit实现子组件传值给父组件




<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" srcc="js/vue.js"></script>
</head>
<body>
<div id="app">
<parent/>
</div>
<script>
var childNode = {
template: `<input type = "button" value = "点击触发" @click = "cdClick" >`,
data() {
return {
childValue:
'诗书画唱提醒你!我是子组件的数据(childValue),\n'
+'我通过$emit传到父组件来了,被用在console.log(childValue)中!'
}
},
methods: {
cdClick() {
//第一个参数自定义事件名
//第二个参数this. childValue是需要传的值
this.$emit('cd', this.childValue);
}
}
};
var parentNode = {
template: `<child v-on:cd="childByValue"></child>`,
components: {
child: childNode
},
methods: {
childByValue: function(childValue) {
// childValue就是子组件传过来的值:
console.log(childValue);
}
}
};
new Vue({
el: '#app',
components: {
parent: parentNode
}
});
</script>
</body>
</html>


例子7:HBuilder实现基础简单的增删查功能的vue商品管理程序(单页面)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script srcc="js/vue.min.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="pid" />
<input type="text" v-model="pname" />
<input type="button" value="新增" @click="add" />
<input type="text" placeholder="请输入查询内容" v-model="searchQuery" />
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>入库日期</th>
<th>操作</th>
</tr>
<!--<tr v-for="item in list" :key="item.id">-->
<tr v-for="item in filteredPros" :key="item.id">
<td>{{item.id}}</td>
<td><img :src="item.img" />{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.sdate}}</td>
<td>
<a href="#" @click="del(item.id)">删除</a>
</td>
</tr>
</table>
</div>
<script>
new Vue({
el: '#app',
data: {
list: [{
"id": 1,
"name": "毛衣",
"price": 498.0,
"sdate": "2018-12-1",
img: "img/p(1).jpeg"
},
{
"id": 2,
"name": "LV",
"price": 200000.0,
"sdate": "2019-3-15",
img: "img/p(2).jpeg"
}
],
pid: '',
pname: '',
searchQuery: ''
},
methods: {
add: function() {
var pro = {
"id": this.pid,
"name": this.pname,
"img": "img/p(2).jpeg"
};
this.list.push(pro);
this.pid = 0;
this.pname = '';
},
del: function(pid) {
if(!confirm('确认删除吗?')) {
return;
}
var index = this.list.findIndex(function(product) {
return product.pid === pid;
});
//从下标处开始删除1个元素
this.list.splice(index, 1);
}
},
computed: {
filteredPros: function() {
var self = this;
return self.list.filter(function(pro) {
console.log(pro);
return pro.name.indexOf(self.searchQuery) !== -1;
})
}
}
})
</script>
</body>
</html>


vue中引用数据中的图片路径示例.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>引用数据中的图片路径示例</title>
<script srcc="js/vue.min.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in list" :key="item.img">
<img :src="item.img"/>
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
list:[
{img:"img/p(1).jpeg"},
{img:"img/p(1).jpeg"}
]
}
})
</script>
</body>
</html>




例子8:Vscode中用axios,mockjs等等实现基础简单的增删查功能的vue商品管理程序(单页面)
'@image()',在mockjs中是用来生成随机图片的。
npm install --save axios mockjs

Products.vue

<template>
<div>
<input type="text" placeholder="请输入商品名称" v-model="pname" />
<input type="text" placeholder="请输入商品价格" v-model="price" />
<input type="button" value="新增" @click="add" />
<br>
<input type="text" placeholder="请输入查询内容"
v-model="skey" />
<table class="tb">
<thead>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>入库日期</th>
<th>图片</th>
<th>操作</th>
</thead>
<tbody>
<tr v-for="pro in flist" :key="pro.id">
<td>{{pro.id}}</td>
<td>{{pro.name}}牌商品</td>
<td>{{pro.price}}</td>
<td>{{pro.sdate}}</td>
<td><img :src="pro.img"/></td>
<td><a href="#" @click="deletePro(pro.id);">删除</a></td>
</tr>
</tbody>
</table>
</div>
</template>
<style scoped>
img{
width:50px ;
height: 50px;
}
</style>
<script>
import axios from 'axios';
//导入mock数据模块
import '../mock';
export default {
created(){//组件创建成功以后获取Mock中的数据
axios.get('/demo')
.then(res => {
this.list = res.data.pros;
});
},
data(){
return {
list: [],//存放商品信息的数组
pid: 11,//用来存放商品的id
pname: '',//用来存放商品名称
price: '',//用来存放商品的价格
skey: ''//搜索的关键字
};
},
methods: {
add(){
let p = {
id: this.pid + 1,
name: this.pname,
price: this.price
};
this.list.push(p);
//清空输入框中的内容
this.pname = '';
this.price = '';
},
deletePro(id){
if(!confirm('确认删除吗?')){
return;
}
//找到跟选择的商品id相同的商品的下标
let index = this.list.findIndex(function(pro){
return pro.id === id;
});
//从下标处开始删除1个元素
this.list.splice(index,1);
}
},
computed: {
flist: function(){
// var self = this;
// return self.list.filter(function(pro){
// return pro.name.indexOf(self.skey) !== -1;
// });
return this.list.filter(pro =>
pro.name.indexOf(this.skey) !== -1);
}
}
}
</script>
<style scoped>
.tb {
border: 3px solid blue;
padding: 0;
margin: 0 auto;
}
</style>

index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
//自己加入的必须加载和要使用组件的代码 START
import Products from '@/components/Products'
//自己加入的必须加载和要使用组件的代码 END
Vue.use(Router)
export default new Router({
routes: [
{//http://localhost:8080/#/Products
path: '/Products',
name: 'Products',//路由跳转时使用
component: Products
}
//自己加的代码 END
]
})
//解决重复点击路由,界面跳转等时报错的代码 START
const originalPush = Router.prototype.push
Router.prototype.push = function push (location) {
return originalPush.call(this, location).catch(err => err)
}
//解决重复点击路由,界面跳转等时报错的代码 END

mock.js

//src/mock.js
import Mock from 'mockjs';
//使用mockjs模拟数据
Mock.mock('/demo', {
"pros|2-3": [{ // 随机生成5到10个数组元素
'id|+1': 5, // 属性值自动加 1,初始值为1
'name': '@cname', // 中文名称
'price': '@integer(100,99999)',//随机生成一个100到99999之间的价格
'sdate': '@datetime()',//随机时间
'img': '@image()',//随机图片
}]
});

npm run dev后:

http://localhost:8080/#/Products


学习截图



--save-dev何-save的区别
1.安装使用--save-dev简写为-D 的插件是被写入到 devDependencies 对象里面。
2.使用--save简写为-S 的插件是则被写入到 dependencies 对象里面
3.devDependencies 里面的插件只用于开发环境,不用于生产环境。
4.dependencies 则是需要发布到生产环境的。
简单的说-D用于开发环境,-S用于生产环境
是你开发时候依赖的东西, 是你发布之后还依赖的东西。
比如,你写 ES6 代码,如果你想编译成 发布那么 就是。
如果你用了 jQuery,由于发布之后还是依赖,所以是。
但是在 npm 里面除了二进制的依赖,似乎也不用区分是不是。
因为使用就是自己编译的意思,而不使用直接拿编译后的版本的,这些依赖项也看不到。
给option中加点击事件的方法.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta charset="UTF-8">
<title>select-option onclick </title>
<script type="text/javascript" >
function simOptionClick4IE(){
var evt=window.event ;
var selectObj=evt?evt.srcElement:null;
// IE Only
if (evt && selectObj && evt.offsetY && evt.button!=2
&& (evt.offsetY > selectObj.offsetHeight || evt.offsetY<0 ) ) {
// 记录原先的选中项
var oldIdx = selectObj.selectedIndex;
setTimeout(function(){
var option=selectObj.options[selectObj.selectedIndex];
// 此时可以通过判断 oldIdx 是否等于 selectObj.selectedIndex
// 来判断用户是不是点击了同一个选项,进而做不同的处理.
showOptionValue(option)
}, 60);
}
}
function showOptionValue(opt,msg){
var now=new Date();
var dt= (1900+now.getYear())+'-'+(now.getMonth()+1)+'-'+now.getDate()+
' '+now.getHours()+':'+now.getHours()+':'+now.getSeconds()+'.'+now.getMilliseconds();
var resultZone=document.getElementById('reslut');
resultZone.style.margin="10px";
resultZone.innerHTML=dt +" 时,点击了: " + (opt.text + ' = '+opt.value);
}
</script>
</head>
<body>
<select onclick="simOptionClick4IE()" >
<!-- 下面的 onclick="showOptionValue( this )" 是为 ff 和 opera而准备 -->
<option value="1" onclick="showOptionValue( this )" >aaaaa</option>
<option value="2" onclick="showOptionValue( this )" >bbbbb</option>
<option value="3" onclick="showOptionValue( this )" >ccccc</option>
</select>
<div id="reslut" ></div>
</body>
</html>



