vue(2019/7/15)

vue實現(xiàn)照片選擇或者拍照功能

照片格式校驗,

圖片質(zhì)量壓縮牍汹,

圖片尺寸壓縮铐维,

圖片離線保存柬泽,

圖片base64編碼互轉(zhuǎn)

<template>
<div class="photo-list">
<hips-view
ref="photoList"
header-fixed
sub-header-fixed
header-height="48"
:sub-header-height="subHeaderHeight"
footer-height="48"

<div
slot="header"
style="width:100%"

<hips-nav-bar
:title="headerTitle"

<div slot="left">
<hips-button
style="margin-left:10px"
@click="goBack"

返回
</hips-button>
</div>
<div slot="right">
<hips-button
v-if="orderStatus===1"
style="margin-right:10px"
@click="uploadImg"

上傳
</hips-button>
<hips-button
v-if="orderStatus===0"
style="margin-right:10px"
@click="saveImg"

保存
</hips-button>
</div>
</hips-nav-bar>
</div>
<div
slot="sub-header"
class="sub-header"

<div class="content-item">
<div
v-if="orderStatus===0"
class="content-item-checked"

<hips-checkbox
v-model="checked"
:border="false"
class="content-item-components"

已確認(rèn)錄入完整信息
</hips-checkbox>
</div>
<div class="content-title">
<span v-if="orderStatus===1|orderStatus===0">
數(shù)量({{ photoDataList.length }}/30)
</span>
<span v-if="orderStatus===2">
數(shù)量({{ photoDataList.length }})
</span>
</div>
<hips-button
v-if="deleteFileSelected.length < 1&&orderStatus!==2"
class="read-only-delete"
size="small"
@click="deleteNull"

刪除
</hips-button>
<hips-button
v-if="deleteFileSelected.length>0&&orderStatus!==2"
size="small"
type="warning"
@click="deleteFile"

刪除
</hips-button>
<hips-button
v-if="orderStatus===2"
class="back-to-top"
size="small"
@click="backToTop"

回到頂部
</hips-button>
</div>
</div>
<div
class="content"
:class="[orderStatus!==0?'content-12':'content-0']"

<hips-scroll
ref="scroll"

<div
v-if="photoDataList.length"
class="list"

<ol class="list-ol">
<li
v-for="(item, index) in photoDataList"
:key="index"
class="list-li"

<label
v-if="item.status.canSelect"
class="checkbox-label"

<span class="checkbox-lists">
<input
v-model="item.status.selectValue"
class="checkbox-list-input"
type="checkbox"
@change="checkChange"
@click="select(item)"

<span class="checkbox-list-span" />
</span>
</label>
<img
v-if="item.status.read"
ref="showImg"
:src="changeUrl(item.file)"
class="show-img"
@click="showPreviewer(index)"

<img
v-if="item.status.unUpload"
:src="upload"
alt="圖片未上傳"
class="upload"

</li>
</ol>
</div>

<img
:src="yasuohou"
alt=""

</hips-scroll>
</div>
<div
slot="footer"
class="footer"

<div class="left">
<label
v-if="photoDataList.length < 30"
for="picture"
class="button"

  • 相冊照片
    </label>
    <label
    v-else
    class="only-read-button"
  • 相冊照片
    </label>
    <input
    id="picture"
    type="file"
    @change="change"

</div>
<div class="right">
<label
v-if="photoDataList.length < 30"
id="camera"
class="button"

  • 新拍照片
    </label>
    <label
    v-else
    class="only-read-button"
  • 新拍照片
    </label>
    <input
    id="camera"
    type="file"
    accept="image/*"
    capture="camera"

</div>
</div>
</hips-view>
</div>
</template></pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n8" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><script>
import { NavBar, Button, Tabs, Tab, View, Scroll, Input, Group, Cell, Checkbox , CheckboxGroup, Previewer } from "@hips/vue-ui";
import edit from "../../../assets/editor.png"
import add from "../../../assets/add-fill.png"
import upload from "../../../assets/upload.png"
import DB from "@/indexDB"
// import { uuid } from "@/utils"
?
import Vue from "vue"
Vue.use(Previewer);
export default {
name: "PhotoList",
components: {
[View.name]: View,
[Tabs.name]: Tabs,
[Tab.name]: Tab,
[NavBar.name]: NavBar,
[Button.name]: Button,
[Scroll.name]: Scroll,
[Input.name]: Input,
[Group.name]: Group,
[Cell.name]: Cell,
[Checkbox.name]: Checkbox,
[CheckboxGroup.name]: CheckboxGroup,
[Previewer.name]: Previewer,
},
data(){
return{
subHeaderHeight: 100,
headerTitle: "照片一覽",
checked: false,
edit: edit,
add: add,
upload: upload,
mimeTypes: [ 'image/png', 'image/jpeg' ], // 圖片類型
selectValue: false,
photoDataList: [], // 數(shù)據(jù)列表數(shù)組
imgUrl: "",
canSelect: false,
unUpload: false,
orderStatus: 0, // 0 工單還未提交, 1 工單已經(jīng)提交嫁蛇,但還未點擊完成派工時 2 完成派工后
imageSet: [], // 展示的照片源
deleteFileSelected: [], // 已經(jīng)勾選刪除的照片數(shù)組
yasuohou: "",
files: [],
}
},
beforeRouteEnter(to,from,next){
next((vm) => {
if(vm.orderStatus !== 0) {
vm.subHeaderHeight = 38
vm.resizePage();
}
vm.photoDataList = [];
let PhotoAlbum = {
name: "album",
store: "photo1",
id: "timeStamp",
db: null,
}
DB.openDB(PhotoAlbum, PhotoAlbum.name, 1, PhotoAlbum.store, PhotoAlbum.id).then((DBres) => { // 將當(dāng)前角色的menu存在indexedDB中
DB.readAll(DBres.db, PhotoAlbum.store).then((res)=> {
for(let i = 0; i < res.length; i ++){
let status = {};
if(vm.orderStatus === 0) {
status = {
canSelect: true,
unUpload: true,
selectValue: false,
read: true, // 是否是從本地文件夾讀取的圖片
}
}
if(vm.orderStatus === 1) {
status = {
canSelect: false,
unUpload: true,
selectValue: false,
read: true, // 是否是從本地文件夾讀取的圖片
}
}
if(vm.orderStatus === 2) {
status = {
canSelect: false,
unUpload: false,
selectValue: false,
read: true, // 是否是從本地文件夾讀取的圖片
}
}
res[i].status = status;
}
vm.photoDataList = res;
})
})
})
},

watch: {
photoDataList() {
this.deleteFileSelected = this.photoDataList.filter((item) => {
return item.status.selectValue === true;
})
},
files() {
console.log("files", this.files)
},
},
methods: {
showPreviewer (index) { // 圖片預(yù)覽
this.imageSet = [];
for(let i = 0; i < this.photoDataList.length; i ++) {
this.imageSet.push({
msrc: "",
src: window.URL.createObjectURL(this.photoDataList[i].file),
desc: this.photoDataList[i].file.name,
})
}
this.hips.previewer.show({ imageSet: this.imageSet, options: { index: index, }, onClose: () => { console.log(`onClose`) }, onIndexChange: (index) => { console.log(`onIndexChange index ={index}) }, }) }, saveImg() { // 保存圖片 let PhotoAlbum = { name: "album", store: "photo1", id: "timeStamp", db: null, } DB.openDB(PhotoAlbum, PhotoAlbum.name, 1, PhotoAlbum.store, PhotoAlbum.id).then((DBres) => { // 將當(dāng)前角色的menu存在indexedDB中 DB.update(DBres.db, PhotoAlbum.store, this.photoDataList); }) }, uploadImg() { // 上傳圖片 ? }, typeCheck(file) { // 圖片類型校驗 let flag = false; let fileTypes = ".jpg"; let filePath = file.value; //當(dāng)括號里面的值為0锨并、空字符、false 睬棚、null 第煮、undefined的時候就相當(dāng)于false if(filePath){ let isNext = false; let fileEnd = filePath.substring(filePath.indexOf(".")); if (fileTypes === fileEnd) { isNext = true; flag= true; } if (!isNext){ alert('不接受此文件類型,請上傳jpg格式文件'); file.value = ""; flag = false; } } return flag; }, sizeCheck(file) { let filePath = file.value; let that = this; that.files = []; let fileTypes = ".jpg"; if(filePath) { let isNext = false; let fileEnd = filePath.substring(filePath.indexOf(".")); if (fileTypes === fileEnd) { isNext = true; } if (!isNext){ // 類型檢測 that.$hips.dialog({ title: "提示", content: "不接受此文件類型抑党,請上傳jpg格式文", okText: '確定', cancelText: '取消', closable: false, }) file.value = ""; return; } let filePic = file.files[0]; //讀取圖片數(shù)據(jù) let reader = new FileReader(); reader.onload = function (e) { let data = e.target.result; let image = new Image(); //加載圖片獲取圖片真實寬度和高度 image.src = data; setTimeout(() => { if(image.width < 640 | image.height < 480) { // 分辨率不可小于640*480 // alert("照片添加失敗包警,分辨率不可小于640*480"); let back = () => { that.files = []; file.value = ""; return; } that.$hips.dialog.confirm({ title: "提示", content: "照片添加失敗,分辨率不可小于640*480", okText: '確定', cancelText: '取消', closable: false, onOk: back, }); } if(image.width >= 640 && image.height >= 480&& image.width <= 1920 && image.height <= 1080) { // 分辨率不可大于1920*1080 if(file.files[0].size/1024 > 150) { // 壓縮大小 let canvasWidth = image.width; let canvasHeight = image.height; let canvas = document.createElement('canvas');//生成canvas let ctx = canvas.getContext('2d'); canvas.width = canvasWidth; // 創(chuàng)建節(jié)點屬性 canvas.height = canvasHeight; let anw = document.createAttribute('width'); anw.nodeValue = canvasWidth; let anh = document.createAttribute('height'); anh.nodeValue = canvasHeight; canvas.setAttributeNode(anw); canvas.setAttributeNode(anh); ctx.fillRect(0, 0, canvasWidth, canvasHeight); ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight); //圖像質(zhì)量,值越小底靠,所繪制出的圖像越模糊 let quality = 0.05; let size = 0; let lastObj; while(size < 150) { if(obj) { lastObj = obj; } let base64String = canvas.toDataURL('image/jpeg', quality); let obj = that.base64ToImg(base64String, file.files[0].name); size = Number((obj.size / 1024).toFixed(2)); quality = Number((quality + 0.05).toFixed(2)); } that.files.push(lastObj); file.value = ""; } else { that.files.push(file.files[0]); file.value = ""; } } if(image.width > 1920 | image.height > 1080) { // 壓縮分辨率 let scale = Number((image.width / image.height).toFixed(2)); let standard = Number((1920 / 1080).toFixed(2)); let canvasWidth, canvasHeight; if( scale > standard ) { canvasWidth = image.width; canvasHeight = Number((image.width / scale).toFixed(2)); } else { canvasHeight = image.height; canvasWidth = Number((image.height * scale).toFixed(2)); } let canvas = document.createElement('canvas');//生成canvas let ctx = canvas.getContext('2d'); canvas.width = canvasWidth; // 創(chuàng)建節(jié)點屬性 canvas.height = canvasHeight; let anw = document.createAttribute('width'); anw.nodeValue = canvasWidth; let anh = document.createAttribute('height'); anh.nodeValue = canvasHeight; canvas.setAttributeNode(anw); canvas.setAttributeNode(anh); ctx.fillRect(0, 0, canvasWidth, canvasHeight); ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight); //圖像質(zhì)量,值越小害晦,所繪制出的圖像越模糊 let quality = 0.95; let base64String = canvas.toDataURL('image/jpeg', quality); let obj = that.base64ToImg(base64String, file.files[0].name); if((obj.size / 1024) < 150) { that.files.push(obj); file.value = ""; } else { // 壓縮大小 let quality = 0.05; let size = 0; let lastObj; while(size < 150) { if(obj) { lastObj = obj; } let base64String = canvas.toDataURL('image/jpeg', quality); let obj = that.base64ToImg(base64String, file.files[0].name); size = Number((obj.size / 1024).toFixed(2)); quality = Number((quality + 0.05).toFixed(2)); } that.files.push(lastObj); file.value = ""; return; } } let arr = []; for(let i = 0; i < that.files.length; i ++) { let pictureObj = {}; let status = { canSelect: true, unUpload: true, selectValue: false, read: true, // 是否是從本地文件夾讀取的圖片 } pictureObj.status = status; pictureObj.file = that.files[i]; pictureObj.timeStamp = (new Date()).valueOf(); arr.push(pictureObj); } that.photoDataList = [ ...that.photoDataList, ...arr ] ; }, 1) }; reader.readAsDataURL(filePic); } else { this.$hips.dialog } }, change(e) { this.sizeCheck(e.target); // this.imgToBase64(this.photoDataList); // indexedDB不能直接存儲base64 }, imgToBase64(imgList) { // 圖片base64編碼 for(let i = 0; i < imgList.length; i ++) { let reader = new FileReader(); reader.readAsDataURL(imgList[i].file); reader.onload = (e) => { imgList[i].status.base64 = e.target.result; } } }, base64ToImg(base64, filename) { // 圖片base64轉(zhuǎn)碼 let dataURLtoFile = (dataurl, filename = 'file') => { if(!dataurl) return; let arr = dataurl.split(',') let mime = arr[0].match(/:(.*?);/)[1] let suffix = mime.split('/')[1] let bstr = atob(arr[1]) let n = bstr.length let u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new File([ u8arr ],{filename}.{suffix}, { type: mime, }) } let imgFile = dataURLtoFile(base64, filename); if(!imgFile) return; // return window.URL.createObjectURL(imgFile); return imgFile; }, changeUrl(item) { // 獲取圖片地址 let a = window.URL.createObjectURL(item); return a; }, deleteFile() { // 刪除圖片 let back = ()=> { console.log("要刪除的圖片", this.photoDataList); let PhotoAlbum = { name: "album", store: "photo1", id: "name", db: null, } for(let i = 0; i < this.photoDataList.length; i ++) { if(this.photoDataList[i].status.selectValue) { let mainKey = this.photoDataList[i].timeStamp; DB.openDB(PhotoAlbum, PhotoAlbum.name, 1, PhotoAlbum.store, PhotoAlbum.id).then((DBres) => { // 將當(dāng)前角色的menu存在indexedDB中 DB.remove(DBres.db, PhotoAlbum.store, mainKey); }) } } let arr = []; for(let i = 0; i < this.photoDataList.length; i ++) { if(!this.photoDataList[i].status.selectValue) { arr.push(this.photoDataList[i]); } } this.photoDataList = []; for(let i = 0; i < arr.length; i ++) { this.$set(this.photoDataList, i, arr[i]); } } this.$hips.dialog.confirm({ title: '提示', content:請確認(rèn)是否刪除這{this.deleteFileSelected.length}張照片`, okText: '確定', cancelText: '取消', closable: false, onOk: back, }); // this.forceUpdate();
// this.resizePage();
},
deleteNull() { // 未勾選刪除
this.hips.dialog.confirm({ title: '提示', content: '請先勾選需刪除的照片', okText: '確定', cancelText: '取消', closable: false, }); }, backToTop() { // 回到頂部 this.refs.scroll.scrollTo(0, 0, 700, "easing");
},
goBack() { // 返回上頁面
if(this.orderStatus === 1) {
let back = ()=> {
this.router.push({ name:"Order", params: { checked: this.checked, }, }) } this.hips.dialog.confirm({
title: '提示',
content: '數(shù)據(jù)未被保存,是否繼續(xù)返回暑中?',
okText: '確定',
cancelText: '取消',
closable: false,
onOk: back,
onCancel() {},
});
}
if(this.orderStatus === 0 | this.orderStatus === 2) {
this.router.push({ name:"Order", params: { checked: this.checked, }, }) } }, select(item) { // 選擇要刪除圖片 item.status.selectValue = !item.status.selectValue; this.deleteFileSelected = this.photoDataList.filter((item) => { return item.status.selectValue === true; }) console.log("select", this.deleteFileSelected); }, checkChange() { // 更新checkbox視圖 this.forceUpdate(); // 數(shù)據(jù)改變更新視圖
},
resizePage () { // 刷新頁面(未使用)
this.refs.photoList.emit('hips-view:resize');
},
},
}
</script></pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="css" cid="n9" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><style lang="stylus" scoped>
// 選擇框樣式 start
.checkbox-list-input {
display: none;
}
.checkbox-list-input:checked + .checkbox-list-span {
background-color: #c30;
border-color: #c30;
}
.checkbox-list-input:checked + .checkbox-list-span::after {
border-color: #fff;
transform: rotate(45deg) scale(1);
}
.checkbox-list-input[disabled] + .checkbox-list-span {
background-color: #d9d9d9;
border-color: #ccc;
}
.checkbox-list-span {
display: inline-block;
background-color: #fff;
border-radius: 100%;
border: 1px solid #ccc;
position: relative;
width: 26px;
height: 26px;
vertical-align: middle;
}
.checkbox-list-span::after {
border: 2px solid transparent;
border-left: 0;
border-top: 0;
content: "";
top: 4px;
left: 9px;
position: absolute;
width: 6px;
height: 16px;
transform: rotate(45deg) scale(0);
transition: transform .2s;
}
// 選擇框樣式 end
.photo-list {

.hips-view__sub-header {
border-bottom none
}
.sub-header {
.content-item {
margin 10px
.content-item-checked {
margin-top 10px
margin-bottom 10px
text-align center
background #fff
/deep/.hips-checkbox {
color #009999
}
/deep/.hips-checkbox__checked--active {
background #c30
}
.content-item-components {
display inline-block
}
}
.content-title {
display inline-block
height 30px
width 100%
line-height 30px
text-align center
margin-right -70px
}
.delete, .back-to-top {
background #ff6600
color #ffffff
}
.read-only-delete {
background #e4e4e4
color #000
}
}
}

.content-0 {
height: calc( 100vh - 218px);
}
.content-12 {
height: calc( 100vh - 166px);
}
.content {
margin: 10px;
border: 1px solid #ccc;
border-radius: 10px;
background: #fff;

.hips-row:after {
display: none;
}
.list {
.list-ol {
display flex
flex-flow row wrap
// justify-content space-around
align-items flex-start
}
.list-li {
position relative
margin-top 10px
margin-left 8px
.checkbox-lists {
position absolute
right -4px
top -6px
}
.show-img {
width 100px
height 100px
padding 2px
border 2px dashed #cccccc
}
.upload {
position absolute
width 30px
height 30px
bottom -2px
right -4px
background #fff
border-radius 50% 50%
}
}
}
}
.footer {
display flex
flex 1
height 100%
.hips-view__sub-header {
border-bottom none
}
.sub-header {
.content-item {
margin 10px
.content-item-checked {
margin-top 10px
margin-bottom 10px
text-align center
background #fff
/deep/.hips-checkbox {
color #009999
}
/deep/.hips-checkbox__checked--active {
background #c30
}
.content-item-components {
display inline-block
}
}
.content-title {
display inline-block
height 30px
width 100%
line-height 30px
text-align center
margin-right -70px
}
.delete, .back-to-top {
background #ff6600
color #ffffff
}
.read-only-delete {
background #e4e4e4
color #000
}
}
}
.content-0 {
height: calc( 100vh - 218px);
}
.content-12 {
height: calc( 100vh - 166px);
}
.content {
margin: 10px;
border: 1px solid #ccc;
border-radius: 10px;
background: #fff;
>>>.hips-row:after {
display: none;
}
.list {
.list-ol {
display flex
flex-flow row wrap
// justify-content space-around
align-items flex-start
}
.list-li {
position relative
margin-top 10px
margin-left 8px
.checkbox-lists {
position absolute
right -4px
top -6px
}
.show-img {
width 100px
height 100px
padding 2px
border 2px dashed #cccccc
}
.upload {
position absolute
width 30px
height 30px
bottom -2px
right -4px
background #fff
border-radius 50% 50%
}
}
}
}
.footer {
display flex
flex 1
height 100%
line-height 48px
input {
display inline-block
width 0
height 0
}
.left {
width 50%
text-align center
.button {
display inline-block
height 40px
width: 90%
line-height 40px
background #ff6600
color #ffffff
}
.only-read-button {
background #e4e4e4
color #000
height 40px
width: 90%
line-height 40px
display inline-block
}
}
.right {
width 50%
text-align center
.button {
display inline-block
height 40px
line-height 40px
width: 90%
background #cc3300
color #ffffff
}
.only-read-button {
background #e4e4e4
color #000
height 40px
width: 90%
line-height 40px
display inline-block
}
}
}
}
</style></pre>

效果展示

image.png

vue父子組件傳參

// dom部分

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n14" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><div id="app">
<my-header :l="list"></my-header>
</div></pre>

// vue父子組件如何傳參

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n16" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">var oApp = new Vue({
el: "#app",
data: {
list: ["第1項", "第2項", "第3項"]
},
components: {
'my-header': {
template: <div> <h2 ref>{{nowMessage}}</h2> <ul> <li v-for="item in l">{{item}}</li> <my-nav @changEvent="getChildContent"></my-nav> </ul> </div>,
data: function() {
return {
message: "hello world!!!",
nowMessage: this.message //單向數(shù)據(jù)流壹瘟,數(shù)據(jù)操做帮哈,refDOM操作 浙于,.native
}
},
methods: {
getChildContent: function(arg) {
console.log(arg);
this.nowMessage = arg;
}
},
props: ['l'], //父組件向子組件進行通信操作
components: {
'my-nav': { //子組件向父組件傳值
template: <ul> <li @click="getContent">"yes, I'm fine"</li> </ul>,
methods: {
getContent: function(ev) {
this.$emit("changEvent", ev.target.innerText);
}
}
}
}
}
}
})</pre>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者蜈敢。
  • 序言:七十年代末雕凹,一起剝皮案震驚了整個濱河市殴俱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌请琳,老刑警劉巖粱挡,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異俄精,居然都是意外死亡询筏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門竖慧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嫌套,“玉大人,你說我怎么就攤上這事圾旨□馓郑” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵砍的,是天一觀的道長痹筛。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么帚稠? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任谣旁,我火速辦了婚禮,結(jié)果婚禮上滋早,老公的妹妹穿的比我還像新娘榄审。我一直安慰自己,他們只是感情好杆麸,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布搁进。 她就那樣靜靜地躺著,像睡著了一般昔头。 火紅的嫁衣襯著肌膚如雪饼问。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天减细,我揣著相機與錄音匆瓜,去河邊找鬼。 笑死未蝌,一個胖子當(dāng)著我的面吹牛驮吱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播萧吠,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼左冬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了纸型?” 一聲冷哼從身側(cè)響起拇砰,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎狰腌,沒想到半個月后除破,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡琼腔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年瑰枫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丹莲。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡光坝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出甥材,到底是詐尸還是另有隱情盯另,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布洲赵,位于F島的核電站鸳惯,受9級特大地震影響商蕴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜悲敷,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一究恤、第九天 我趴在偏房一處隱蔽的房頂上張望俭令。 院中可真熱鬧后德,春花似錦、人聲如沸抄腔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赫蛇。三九已至绵患,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悟耘,已是汗流浹背落蝙。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留暂幼,地道東北人筏勒。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像旺嬉,于是被迫代替她去往敵國和親管行。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容